Am trying to add assembly instructions for timing in pisa architecture using simplescalar simulator. For my instructions i should access clock cycles and store it in the register. This changes has to be made in the machine.def file where all other assembly instructions like add, mul etc are defined.
Am not getting how to access clock cycles in simplescalar simulator? Kindly help
Thank u
I do not know if I got it right, but I think you need to keep the PC value. If this is what you want to do, you can see the used definitions in the beginning of the machine.def file. NPC for next PC, CPC for current PC and SET_NPC/SET_CPC accordingly. So if you want the PC value, you can have it using CPC. Also these definitions are all set in the simulators' files, for example in sim-outorder.c.
Related
The strange issue happens on the ARM32 platform. I need to run a time-series database to store and process my sensor data on an edge device. I don't have many options as some popular databases can't run on a device with very small storage capabilities. After few cycles of evaluation, I found an open-sourced time-series database TDengie seems perfectly matched my requirements since it's powerful and small enough. But when I compile and run it on my ARM32 board, it hangs the whole system. I have tried it on my X86 Linux machine and even Raspberry Pi 4 and it doesn't have such an issue. I doubt it's a special bug that exists on ARM32 only. I spent some time debugging. and I found it hands on a piece of code in the src\query\src\qExecutor.c.
*(double *)pCtx->pOutput = *(double *)pCtx->pOutput + pInput->dsum;
It works great on the X86 and Raspberry Pi but always failed on ARM32. I don't have sufficient knowledge about ARM platform-specific instruction C program generated.
Appreciated if someone can help out on this?
I guess it must be a memory align issue. You can check if the memory address of pCtx->pOutput. If it is not a 4-byte value, it would lead a bus error as the ARM assembly instruction vstr requires.
A quick solution could be using a temporary variable to make the value to be stored the assign the temporary variable's value to the target address.
You may want to try TickTock (https://github.com/ytyou/ticktock), a lightweight TSDB. We have tested it in RPi zero wireless (32bit).
Disclaimer: I am co-author of TickTock. It is still being stress-test and not in production yet.
I'm trying to learn and master embedded C, so I was just gonna test a code that I found on Github, which is built for STM32F4 discovery board. The board that I'm actually working on is STM32L152. when I tried to build/run the code (obviously it won't work) the errors I'm getting are mostly related to functions not being defined or "identifier 'function_name' is undefined", note that the code file includes a library (lib).
take a look at the code file:
https://github.com/TDAbboud/STM32F4_Examples/tree/master/04_PWM_Servo
Generally speaking, What modifications should be done to successfully run the code on STM32L1?
Thanks
These are two different chips. Just because they are from ST just because they are ARM based, they are not the same chip. for starters the stm32f4 is a cortex-m4 the stm32l might not be, 99.9% of your code wont care, just some assembly might. if the stm32l is a cortex-m0 then you have far fewer instructions so the assembly will matter if it is a cortex-m3 then it wont.
The real isssue is peripherals not that this is two st chips not that this is two arm chips, the peripherals can/will vary. ST has a number of chips that use the same uart or same gpio or other, but they have more than one uart they use for STM32 chips, and more than one GPIO. And they mix and match as they make new chips, so if you want to port from one to the other you need to go peripheral by peripheral reading the new and old docs to see what if anything changed.
Sounds like you are using a library so the tool may know from the chip you have chosen what peripherals you have and which library you need, so it might not be finding them because for that chip that peripheral and thus that function and those defines do not apply. Take it one perpheral at a time and port between chips.
stm32 (L) serise incloud EEPROM which are important when they go to sleep mode and want to recover variables after wakup . so make sure application is running in sleep modes need to save data somewhere. so if you use STM (F) series care needs to attache a external EEPROM
For the life of me I can't make a timer for PIC18 or precisely PIC18f87j11. All I want to do is to have a counter that increments every 1 second. I just want to monitor how long PIC18 been running in terms of seconds.
Most of the tutorials out there are for PIC16 and are in assembly. I am trying to do this using C programming. For someone who is beginner I understand better if I see examples, so without examples I can't progress.
please someone show me an example, thank you!
To begin understanding timers you will need to have a look at their documentation. I suggest searching the manufacturers website. There are 5 timer available. If you use Timer0 which is either a 8 bit or 16bit timer. You will need to set the correct configuration for T0CON. Also you will need to have correct interrupt settings (INTCONbits), so a an event can be generated by interrupt service routine once timer expired.
You will most likely need to calculate the prescale value you require for correct timing, in your case 1 second. It does depend on FOsc: Here is a tutorial
Here an example of C code using MPLab and another one based on MPLab and hi-tech compiler. It is not for same chip, however it is based on PIC18F family.
It's been a awhile since I have visited PIC18F, so if any correction required, please do so.
If you use HIGH-TECH compiler, you can simply use its special function for close, open, read and write timers modules in below directory:
...\HI-TECH Software\PICC-18\9.80\sources\plib\Timers
According to your microcontroller name, you can figure out which version of these function is written for your microcontroller. So for first step, open pconfig.h file and search your microcontroller name to see for every module which version is fit to your microcontroller registers.
Good Luck
I using inline assembly to enable a bit in counter control register. I am looking out for the apt code in inline-assembly. I used the following code for an Infineon TriCore micro-controller.
__asm("ENABLE CCTRL.CE");
Please guide me in writing the correct code. In the above code, I will need to set 1 to the bit CE in Counter Control register (CCTRL). Please help.
A quick scan of the instruction set shows that the ENABLE command is used to enable interrupts. You probably want the ST.T instruction. There should be something in the SDK which maps the CCTRL register to a given memory address or variable name.
I have verilog based verification envirnoment for ARM based chip. I have to write new tests in
C++ to verifiy a peripheral. I have all ARM based GCC tools in place. I do not know how to make a
particular peripheral register visible in C++ based test. I want to write to this register, want to wait for the interrupt from the peripheral and then want to read back status of another peripheral register.
I would like to to know how can it be done? Which documentation from ARM should I refer to.
I tried and find all documentations are for system developers
I need the basic information.
Regards
Manish
You will eventually if not immediately want the ARM ARM (yes ARM twice, once for ARM the second one for Architectural Reference Manual, you can google it and find it for free as a download). Second you want the TRM, Technical Reference Manual for the specific core in your chip. ARM doesn't make chips they make processor cores that other people put in their chips so the company that has the chip may or may not have the TRM included in their documentation. If you have an arm core in verilog then I assume you purchased it and that means you have the specific TRM for the specific core that you purchased available, plus any add ons (like a cache for example).
You can take this with a grain of salt but I have done what you are doing for many years (testing in simulation and later on the real chip) now and my preference is to write my C code as if it were going to be running embedded on the arm. Well in this case perhaps you are running embedded on the arm.
Instead of something like this:
#define SOMEREG (*(volatile unsigned int *)0X12345678)
and then in your code
SOMEREG = 0xabc;
or
somevariable = SOMEREG;
somevariable |= 0x10;
SOMEREG = somevariable;
My C code uses external functions.
extern unsigned int GET32 ( unsigned int address );
extern void PUT32 ( unsigned int address, unsigned int data);
somevariable = GET32(0x12345678);
somevariable|=0x10;
PUT32(0x12345678,somevariable);
When running on the chip in or out of simulation:
.globl PUT32
PUT32:
str r1,[r0]
bx lr ;# or mov pc,lr depending on architecture
.globl PUT16
PUT16:
strh r1,[r0]
bx lr
.globl GET32
GET32:
ldr r0,[r0] ;# I know what the ARM ARM says, this works
bx lr
.globl GET16
GET16
ldrh r0,[r0]
bx lr
Say you name the file it putget.s
arm-something-as putget.s -o putget.o
then link putget.o in with your C/C++ objects.
I have had gcc and pretty much every other compiler fail to get the *volatile thing to work 100%, usually right after you release your code to the manufacturing folks to take your tests and run them on the product is when it fails and you have to stop production and re-write or re-tune a bunch of code to get the compiler not confused again. The external function approach has worked 100% on all compilers, the only drawback is the performance when running embedded, but the benefits of abstraction across all interfaces and operating systems pays you back for that.
I assume you are doing one of two things, either you are running code on the simulated arm trying to talk to something tied to the simulated arm. Eventually I assume the code will be doing that so you will have to get into tools and linker issues, which there are many examples out there, some of my own as well, just like building a gcc cross compiler, trivial once shown the first time. If this is a peripheral that will eventually be tied to an arm, but for now is outside the core but inside the design, meaning it hopefully is memory mapped and is tied to the arms memory interface (amba, axi, etc).
for the first case you have to overcome the embedded hurdle, you will need to build bootable code, probably rom/flash based (read only) as that is likely how the arm/chip will boot, dealing with the linker scripts to separate the rom/ram. Here is my advice on that eventually if not now the hardware engineers will want to simulate the rom timing, which is painfully slow in simulation. Compile your program to run completely from ram (other than the exception table which is a separate topic), compile to a binary format that you are willing to write an ad hoc utility for reading, elf is easy, so is ihex and srec, none as easy as a plain old binary .bin. What you ultimately want to do is write some assembler that boots up on the virtual prom/flash, enables the instruction cache (if they have that implemented and working in simulation, if not then wait on that step) uses the ldm amd stm instructions in a loop to copy as many words at a time as you can to ram, then branch to ram. I have a host based utility that takes the .bin file creates an assembler program that includes the assembler that copies the binary to ram and embed the binary itself as .words in the assembler, then assemble and link that program to a format the simulation can use. Do not let the hardware engineers convince you that you have to re-build the verilog every time, you can use a $readmemh() or some other such thing in verilog to read a file at runtime and not have to re-compile the verilog to change the arm binary. You will want to write an ad hoc host based utility to convert your .bin or .elf or whatever to a file that the verilog can read, readmemh is trivial... So I am getting off on a tangent, use the put/get to talk to registers, you have to use the TRM and the ARM ARM to place the interrupt handler code somewhere, you have to enable the interrupt, most likely in more than one place in the arm as well as in the peripheral. The beauty of simulating is that you can watch your code execute and you can see the interrupt leave the peripheral and debug your code based on what you see, with a real chip you dont know if your code is failing to create the interrupt or if your code is failing to enable the interrupt or if the interrupt is working but you made a mistake in the interrupt handler, with a verilog simulator you can see all of this and you should strive to learn to read the waveforms and not rely on the hardware engineers to do it for you. modelsim or cadence or whomever can save the waveforms in .vcd format and you can use a free tool named gtkwave to view the waveforms. Dont let them convince you that they dont have any more licences available for you to look at stuff.
All of that is secondary, if this is an off core but on chip peripheral then you probably want to test that logic without the arm core first. If you dont know verilog, its easy you should just look at the code and you can figure it out. Software engineers can pick it up in a few days or a week if already experienced in languages, particularly C. Either way, the hardware engineer likely has a test bench for the peripheral, you create or have them create a test bench with a register that is similar to what you will see once connected to the arm, either directly on the arm bus or on a test bench interface that simplifies the arm bus. then use vpi, which is ugly but works (google foreign language interface as well as vpi) to connect C code on the host machine running the simulation. Do most of your work in C and verilog minimizing the vpi nightmare. Because this is compiled and linked to the simulation in a sense you do not want to have to re-build the sim every time you want to change your test program. So use something like sockets or some other IPC interface so that you can separate from the vpi code. Then write some host code that implements put32 and get32 (put8, put16, whatever functions you want to implement). so now you take your test program that can run on the arm if compiled that way and instead compile it on the lost linking it to the put/get/whatever abstraction layer. Now you can write programs that for now run on the host but interact with the peripheral in simulation as if it were real hardware and as if your host programs were embedded programs in the arm. the interrupt is likely trivial in this environment as all you have to do is either look for it in the waveforms or have the vpi code print something on the console when the signal changes states or something like that.
Oh, the reason for copying from rom to ram then running from ram is that on average your sim times will be significantly shorter, fives and tens of minutes instead of hours. simulating the peripheral by itself without the arm using a foreign language interface to bridge to/from the host, cuts your sim time from fives of minutes to seconds depending on what you are doing. If you use some sort of abstraction like my put/get you can write your peripheral code one time in one file, linking it different ways that one file/program/function can be used with the perhipheral only in simulation for quickly developing your code, then run with the arm in place in simulation adding the complexity of the arm exceptions and arm interrupt system, and later on the real chip as you were running on the simulated chip. and then later that code can hopefully be used as is in a driver or application space using mmap, etc.