In the end, you donβt want ARM ARM (yes, ARM twice, once for ARM - the second for the Architecture Reference Guide, you can send it and download it for free as a download). Secondly, you want TRM, a technical reference guide for a specific core in your chip. ARM does not make chips, they make processor cores that other people put into their chips, so a company that has a chip may or may not have the TRM included in their documentation. If you have a hand core in verilog, then I assume that you bought it, and that means that you have a specific TRM for the specific core that you purchased, plus any additions (e.g. cache).
You can take this with salt, but I did what you have been doing for many years (testing in simulations, and then on a real chip), and my preference is to write my C code as if it were going to to be launched on the arm. Well, in this case, perhaps you are using the built-in hand.
Instead of 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 working on a chip in or out of a 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 named the itgetget.s file
arm-something-as putget.s -o putget.o
then bind putget.o to your C / C ++ objects.
I had gcc and almost every other compiler was unable to get the * volatile thing to work 100%, as a rule, right after you release your code for those involved in production to run your tests and run them on the product when it doesnβt work and you have to stop production, overwrite or reconfigure a bunch of code so as not to compromise the compiler again. The external function approach worked 100% on all compilers, the only drawback is the performance when starting the built-in ones, but the advantages of abstraction in all interfaces and operating systems return you for this.
I assume that you do one of two things: either you run the code on the simulated hand, trying to talk with something related to the simulated weapon. In the end, I assume that the code will do this, so you will have to deal with tools and problems with linkers, which are many examples, some of my own, as well as creating a gcc cross-compiler, is trivial as shown in the first times, If this is a peripheral device that will ultimately be attached to the hand, but is currently outside the core, but inside the design, that is, he hopes that the memory card is attached to the weapon's memory interface (amba, axi, etc. )
for the first case, you need to overcome the built-in obstacle, you will need to create boot code, possibly based on rom / flash (read-only), since this is most likely how the hand / chip will load, referring to the linker scripts split rom / ram. Here is my advice on this, in the end, if not now, hardware engineers will want to simulate the synchronization time, which very painfully slows down the simulation process. Compile your program for full launch from ram (except for the exception table, which is a separate topic), compile it into binary format, which you are ready to write a special utility for reading, el is easy, so it is ihex and srec, none is as simple as simple old binary bit. What you ultimately want to do is write some assembler that loads onto the virtual prom / flash, allows you to use the command cache (if they have it implemented and working in the simulation, if not, then wait at this point) uses the ldm instructions amd stm into a loop to copy as many words at a time as you can to smash and then go into ram. I have a host based utility that accepts a .bin file, creates an assembler program that includes an assembler that copies the binary for ram and embeds the binary itself as .words in assembler, and then compiles and links this program with the format which can use. Do not let hardware engineers convince you that you need to rebuild the verilog each time, you can use $ readmemh () or some other thing in verilog to read the file at runtime, and you should not recompile verilog to change the binary element of the hand. You will want to write a special host-based utility to convert your .bin or .elf or something else to a file that Verilog can read, readmemh is trivial ... So I'm going away tangentially, use put / get to talk to registers, you must use TRM and ARM ARM to place the interrupt handler code somewhere, you must enable the interrupt, most likely in several places both in the hand and in the periphery. The beauty of the simulation is that you can monitor the execution of the code, and you can see that the interrupt leaves the peripheral device and debugs your code based on what you see with a real chip that you don't know if your code is creating interrupt or if your code cannot turn on the interrupt or if the interrupt works, but you made a mistake in the interrupt handler, using the verilog simulator you can see all this and you should strive to learn how to read waveforms and not rely on hardware engineers to be it for you. modelsim or cadence or who can save waveforms in .vcd format and you can use a free tool called gtkwave to view waveforms. Do not let them convince you that they no longer have licenses available so you can look at things.
All this is secondary, if it is not a core, but a peripheral device on a chip, you probably want to check this logic first without a main core. If you don't know Verilog, you just need to take a look at the code, and you can figure it out. Software engineers can pick it up in a few days or a week, if they are already in languages, in particular C. In any case, the engineer-engineer probably has a test bench for peripherals, you create or create a test bench with a register that similar to what you will see, once connected to a hand, either directly on the lever bus or on the test bench interface, which simplifies the shoulder bus. then use vpi, which is ugly but works (google foreign language interface, as well as vpi) to connect the C code on the host machine that is running the simulation. Do most of your work in C and verilog, minimizing the vpi nightmare. Since this is compiled and related to the simulation, you do not want to re-mount the simulator every time you want to change your test program. So use something like sockets or another IPC interface so that you can separate from the vpi code. Then write some host code that implements put32 and get32 (put8, put16, any functions you want to implement). so now you take your test program, which can work on hand if it is compiled in this way, and instead compile it using the lost link to the put / get / whatever abstraction layer. Now you can write programs that are currently running on the host, but interact with peripherals in the simulation, as if it were real hardware, and as if your host programs were built-in programs in your hand. interruption is probably trivial in this environment since all you have to do is either look for it in waveforms or have a vpi code that prints something to the console when the signal changes state or something like that .
Oh, the reason for copying from rom to ram, and then from ram, is that on average your sim times will be much shorter, five and tens of minutes instead of hours. simulating peripherals on your own, without leverage, using a foreign language interface to go to / from the host, reduces the time of your simulator from five minutes to several seconds, depending on what you are doing. If you use some kind of abstraction, for example my put / get, you can write your peripheral code once in one file, linking it in different ways, so that one file / program / function can be used with perhipheral only in simulation to quickly develop your code , and then run it using the simulation in the simulation, adding the complexity of exceptions to the hand and the hand interrupt system, and then the real chip when you were working on the simulated chip. and then later this code can hopefully be used both in the driver or application area using mmap, etc.