OpenCores
no use no use 1/1 no use no use
regd Using or1ksim
by ag1986 on Dec 4, 2009
ag1986
Posts: 10
Joined: May 22, 2009
Last seen: Dec 18, 2009
Hi, I downloaded the gnu tool chain and finally i need to run some common algorithms like nelder mead or so for which i would have a C program.The information I would like to gather is how many cycles, cycle time so on and so forth it takes for the process to process it.
At the moment just to test it I wrote a simple C program which has nothing in it but just adds two numbers.
I used the command or32-elf-gcc test.c -o test.or32 to generate the binary file.
I then used or32-elf-sim -f sim.cfg --enable-profile test.or32

I get the following messages
Insn MMU 0KB: 1 ways, 64 sets, entry size 1 bytes
Data MMU 0KB: 1 ways, 64 sets, entry size 1 bytes
Or1ksim 0.3.0
Building automata... done, num uncovered: 0/213.
Parsing operands data... done.
WARNING: Unable to open RX file stream.
Resetting memory controller.
Resetting PIC.
loadcode: filename test.or32 startaddr=00000000 virtphy_transl=00000000
Not COFF file format
ELF type: 0x0002
ELF machine: 0x005c
ELF version: 0x00000001
ELF sec = 15
Section: .text, vaddr: 0x01000074, paddr: 0x1000074 offset: 0x00000074, size: 0x00007550
Section: .rodata, vaddr: 0x010075c4, paddr: 0x10075c4 offset: 0x000075c4, size: 0x000005d4
Section: .data, vaddr: 0x01009b98, paddr: 0x1009b98 offset: 0x00007b98, size: 0x0000008c


And it hangs here.
the code i used as of now is
#include stdio.h
int main()
{int a,b,c;
a=5;b=10;
c=a+b;
}

I would like to know what am i missing. I would also like to know if i want it to display the value of c how could i achieve that as i might want to check for accuracy of the processor too.

Apart from this i tried runing the demo file given with this but when i do it i end up getting messages such as
ERR:8-bit program load out of memory area: 0100xxx for all addresses.
How do i resolve this.

Thanks in advance for your help.

Regds

Aravindh
RE: regd Using or1ksim
by jeremybennett on Dec 4, 2009
jeremybennett
Posts: 815
Joined: May 29, 2008
Last seen: Jun 13, 2019

Hi Aravindh,

I think the problem is that you don't have a suitable bootloader for Or1ksim. I haven't looked at the default crt0 for OR1K GCC, but I am fairly certain it does not include an Or1ksim compatible bootloader.

It may be easiest to run your programs under some sort of operating system. FreeRTOS, eCOS and Linux/BusyBox are all ported to OpenRISC. These will provide you with all the infrastructure you need.

If you wish to run bare metal, you need code at the reset vector (0x100) to set up stack and frame pointers etc and then jump to _start. For an example take a look at the Embecosm application note on SystemC modeling using the OpenRISC SoC. Section 5.4 includes an example test program implementing a minimal bootloader (start.s) and library (utils.c) that can be linked with C programs with absolutely no other libraries. You need to take some care when linking, to ensure the right code ends up in the right place.

Hope this gives you some ideas.

Jeremy

--
Tel: +44 (1590) 610184
Cell: +44 (7970) 676050
SkypeID: jeremybennett
Email: jeremy.bennett@embecosm.com
Web: www.embecosm.com

RE: regd Using or1ksim
by ag1986 on Dec 4, 2009
ag1986
Posts: 10
Joined: May 22, 2009
Last seen: Dec 18, 2009
Hi,

I think i didnt get you properly. In terms of running in some operating system do u mean the linux shell which gets installed when we download the tool chain or any Linux os would do. As I am using "ubuntu's" terminal and running it so still would i have to link it. If so wwhere could i get to download the OS that will support open risc.

Thanks

Aravindh
RE: regd Using or1ksim
by jeremybennett on Dec 7, 2009
jeremybennett
Posts: 815
Joined: May 29, 2008
Last seen: Jun 13, 2019

I think i didnt get you properly. In terms of running in some operating system do u mean the linux shell which gets installed when we download the tool chain or any Linux os would do. As I am using "ubuntu's" terminal and running it so still would i have to link it. If so wwhere could i get to download the OS that will support open risc.

Hi Aravindh

I was referring to the operating system (if any) running on the Or1ksim itself. You can load a complete Linux image compiled for the OpenRISC 1000 and execute it on Or1ksim.

HTH

Jeremy

RE: regd Using or1ksim
by rfajardo on Dec 7, 2009
rfajardo
Posts: 306
Joined: Jun 12, 2008
Last seen: Jan 6, 2020
Hi Jeremy, ag1986,

as Jeremy said at the beginning, you need a "bootloader" in order to make your software work.

I will try to clearly explain its task in the following lines by comparing it to you running a program on your own operating system.

When you type in the "linux shell" "ls" or "dir" in "windows command prompt", the operating system creates a new process for this program; set a runnable environment for it, with stack, registers and memory; and then at some point set the program counter to the start of your program. (http://en.wikipedia.org/wiki/Process_fork).

The key points here are, you are creating a binary which:
-does not have any information about position in memory
-you are not initializing a stack
-you are not initializing registers
-you are not saying how much memory is available

And without these, your software will simply not work. For instance, if your binary will be located starting at address 0x00, your software will not be ever executed from the beginning by the OpenRISC since it resets to 0x100 and go then onwards until memory finishes.

So, how do I solve this? Generally you cannot dictate where code will be inserted to in C, so you actually need sort of a C assembly mix and then link them together. Furthermore a linker script is used to create memory spaces so you can actually organize the memory dividing data from instruction, exceptions from code and so on.

Attached you get a very compact working "Makefile project".

orp.lp is the linker script. There you find the definitions for memory areas:
-the reset area is for the reset handler, everytime you hard-reset your OpenRISC it goes back to instruction 0x100. Even if here the area starts at 0 it is offset to 0x100 inside of the reset handler.
-the vector area is for the exception handlers, when interrupts are asserted on the OpenRISC it jump to specific addresses which are defined inside of this specific area.
-the ram area, here you can put your code, variables and define your stack.

boot.S is the reset handler, it resets the registers, sets the stack and jump into the main function. Depending if you give the values -DIC=1 -DDC=1 or -DIC=0 -DDC=0 on compilation it will or will not initialize the instruction and data caches.

I kicked out all file dependencies for this handler so people can have a complete overview of the process. For example, the line .org 0x100 defines that the code under it will go to memory address 0x100. Another important aspect is that by object creation the _main function or memory position is not defined so this information is postponed to be filled out by the linker. When the main.c is compiled there will be this definition and when you link main.o with boot.o both will be connected.

I also added to the project a support directory where the actual implementation of printing out stuff through uart is found. This is linked together with main.c on the last step of the root Makefile so the uart_print_long and uart_print_str have defined implementations.

Also included in the small project is a sim.cfg configuration file for the OpenRISC simulator. If you call "or32-elf-sim -f sim.cfg main.or32" you will get the output 0x00000003.

To demonstrate that the "bootloader" is necessary you can try to simply compile the code as: or32-elf-gcc main.c support/uart.o support/uart_basic.o -o main.or32 and try to run that. You will see that you will not get the result output as when you link orp.lp + boot.o + main.o together.

I hope that gives you an insight about the problems being discussed in this thread and help you to bootstrap your program :-P.

Best regards,
Raul
boot.tar.gz (24 kb)
RE: regd Using or1ksim
by ag1986 on Dec 9, 2009
ag1986
Posts: 10
Joined: May 22, 2009
Last seen: Dec 18, 2009
Hi,

Raul anjd Jeremy, thanks a lot for your explanation. It really helped me to understand what i was missing. I have a few more queries though. I executed the code given by you as such, i get the answer correctly but then i find that the system doesnt exots the appln. The answer is printed out and it continues to wait there. Should i insert a break in the code by any chance.

I was trying to create a sim profile by using the command ./or32-elf-sim -f sim.cfg --enable-profile main.or32 but i got an empty simprofile. Is it something to do with that the operation isn't getting terminated or am i missing something.

Thanks for your time

Aravindh
RE: regd Using or1ksim
by jeremybennett on Dec 9, 2009
jeremybennett
Posts: 815
Joined: May 29, 2008
Last seen: Jun 13, 2019

Hi Aravindh

I've done no work on the profiling in Or1ksim - I just took the code that was there. You may need to do some experimenting, and possibly look at the Or1ksim source to see if there is a problem. It may be something missing in the documentation. You probably need to change something in sim.cfg to ensure profile data is collected.

If you do find out, either post it here, or if appropriate file a bug.

Jeremy

--
Tel: +44 (1590) 610184
Cell: +44 (7970) 676050
SkypeID: jeremybennett
Email: jeremy.bennett@embecosm.com
Web: www.embecosm.com

RE: regd Using or1ksim
by rfajardo on Dec 9, 2009
rfajardo
Posts: 306
Joined: Jun 12, 2008
Last seen: Jan 6, 2020
After the program run to the point you wanted, type CTRL+C. Input q and hit ENTER.

orpsocv2 exits the simulation when the firmware run till the end.

I'm not totally sure of how this works but it seems to me that, after the firmware reports (outputs) the "deaddead" message, the script exits the simulation.

Is it really like that?

ln -s $$CURRENT_TEST_SW_DIR/$$TEST.or32 $(SIM_RUN_DIR)/.; \
echo;echo "\t#### Launching architectural simulator ####"; \
time -p $(ARCH_SIM_EXE) --nosrv -f $(SIM_BIN_DIR)/$(ARCH_SIM_CFG_FILE) $$TEST.or32 > $(SIM_RESULTS_DIR)/$$TEST-or1ksim.log 2>&1; \
if [ $$? -gt 0 ]; then exit $$?; fi; \
if [ `tail -n 10 $(SIM_RESULTS_DIR)/$$TEST-or1ksim.log | grep -c $(SIM_SUCCESS_MESSAGE)` -gt 0 ]; then \
TEST_RESULT=1; \
fi; \
echo; echo "\t####"; \
if [ $$TEST_RESULT -gt 0 ]; then \
echo "\t#### Test $$TEST PASSED ####";TESTS_PASSED=`expr $$TESTS_PASSED + 1`;\
else echo "\t#### Test $$TEST FAILED ####";\
fi; \
echo "\t####"; echo; \
TESTS_PERFORMED=`expr $$TESTS_PERFORMED + 1`;\
unlink $(SIM_RUN_DIR)/$$TEST.or32; \

Best regards,
Raul
RE: regd Using or1ksim
by julius on Dec 9, 2009
julius
Posts: 363
Joined: Jul 1, 2008
Last seen: May 17, 2021
I'm not totally sure of how this works but it seems to me that, after the firmware reports (outputs) the "deaddead" message, the script exits the simulation. Is it really like that?
See the ORPSoC page http://opencores.org/openrisc,orpsocv2#usinglnop and the section on how the simulation models use the l.nop instruction with an immediate value to do certain things during simulation. There's a short explanation on that page, but I also link to Jeremy's Embecosm site which has a better explanation.

The test software included with ORPSoC has a standard way of signalling that everything went according to plan during the test. If everything was successful the value 0xdeaddead is signaled, or reported, using the l.nop with immediate value NOP_REPORT (defined in sw/support/spr_defs.h). When something is "reported" it is typically written out (logged) to a text file. There's a C function in sw/support/support.c which goes like this:

void report(unsigned long value)
{
asm("l.addi\tr3,%0,0": :"r" (value));
asm("l.nop %0": :"K" (NOP_REPORT));
}

This is two assembly instructions in C code, one to copy the argument/value to r3, and the other is a l.nop instruction with immediate value of NOP_REPORT (0x2). You'll see throughout the C test software calls to the report() function, passing a value. The simulators have a way of checking each instruction, and when l.nop instructions are executed, the immediate value is checked to see if it's one of these special controlling instructions. Note that the compiler will never output l.nop instructions with immediate values other than 0, so in every case where the l.nop's immediate is not zero it's usually our doing.

We do a similar thing to cause the simulation to end, this time we have a l.nop instruction with immediate value equal to NOP_EXIT (0x1). The RTL, cycle accurate and architectural simulators all know how to handle these special l.nop instructions, or have a way of checking them when they are executed.

This is handy because you can add your own special signalling instructions in the code - for instance I have added one in the h264 project which dumps and resets the memory access statistics of a particular module on the bus.

But, in ORPSoC's case, it's used mainly to report values and exit the simulation.

The bash script which performs the tests, waits until the simulation has exited, by use of a l.nop with NOP_EXIT immediate, and then checks the simulation's log file, typically in sim/results/test-name-general.log or something, and greps for the "deaddead" string - if it's found then we know the test was successful, otherwise it failed.

So the bash loop running the simulations has nothing to do with stopping the simulation. The simulations are all controlled via use of the l.nop instruction. If you're confused about something, go and read the part of the ORPSoC page I linked to earlier, and definitely read Jeremy's page for a good explanation.

Julius
RE: regd Using or1ksim
by ag1986 on Dec 10, 2009
ag1986
Posts: 10
Joined: May 22, 2009
Last seen: Dec 18, 2009
Hi,

Thanks for your reply raul and julius. I was just wondering whether i could get the number of clock cycles taken to simulate using or1ksim? I have been trying to find something related to it through the day but with no success.

Thanks

Regds

Aravindh
RE: regd Using or1ksim
by julius on Dec 10, 2009
julius
Posts: 363
Joined: Jul 1, 2008
Last seen: May 17, 2021
number of clock cycles taken to simulate using or1ksim?

When or1ksim exits it prints the number of instructions executed and an estimated number of cycles this would have taken.

Since or1ksim is a transactional/instruction level model it can only guess about the exact number of cycles taken to do things, such as poke different memory locations and peripherals in the system. Therefore its cycle numbers aren't precise, but you can tune or1ksim using the configuration file, setting numbers for memory access cycles (delayr and delayw in memory section configs, plus others like cache miss costs etc) and the like to make the cycle numbers more accurate.

I have played with this recently and found that configuring the main simulated on-chip SRAM in ORPSoC to have delayr=2 and delayw=4 made cycle counts more like those from the RTL model, but as soon as other peripherals come into play then the counts between RTL and or1ksim diverge.

But if your question is simply how do you get a cycle count then when or1ksim exits normally you should see something like this:

@exit : cycles 386486, insn #267792

and you can even make the simulator print out the cycles during the simulation using an l.nop instruction with the NOP_CNT_RESET (0x5) immediate value, one of the many uses of the l.nop instruction I mentioned before.

Julius
RE: regd Using or1ksim
by rfajardo on Dec 10, 2009
rfajardo
Posts: 306
Joined: Jun 12, 2008
Last seen: Jan 6, 2020
Thanks Julius, that is indeed very useful and I wasn't aware of.
RE: regd Using or1ksim
by jeremybennett on Dec 10, 2009
jeremybennett
Posts: 815
Joined: May 29, 2008
Last seen: Jun 13, 2019

Hi Aravindh, Raul,

Use the clock counts from Or1ksim with extreme caution. They are calculated as one clock cycle for each instruction + clock cycles for each memory access as specified in the config file for the memory. However the code is very flakey, and I'm not sure it even gets this right in all circumstances. No concept of processor stalling at all. I wouldn't trust the absolute figures within a factor of 10 either way. Perhaps use the data for relative comparisons, but even there be cautious about any effects of stalls.

If you want cycle counts, use the Verilator model. That will give you an exact model. Of course you had better use an accurate Verilog implementation of your memory when doing this...

HTH

Jeremy

--
Tel: +44 (1590) 610184
Cell: +44 (7970) 676050
SkypeID: jeremybennett
Email: jeremy.bennett@embecosm.com
Web: www.embecosm.com

RE: regd Using or1ksim
by ag1986 on Dec 11, 2009
ag1986
Posts: 10
Joined: May 22, 2009
Last seen: Dec 18, 2009
Hi,
I got the cycle count once i started using the l.nop for exit. I am uaing a very simple c program as of now where i am just adding two numbers and multiplying them as shown below.

#include "support/uart.h"
#include "support/spr_defs.h"

int main()
{ asm("l.nop %0"::"K" (0x5));
int a, b, c, d;

a = 4;
b = 2;

c = a + b;
d = c * a;
// uart_print_long(c);
// uart_print_str("\n");
// uart_print_long(d);
// uart_print_str("\n");

asm("l.nop %0"::"K" (NOP_EXIT));


}


Now i have used the delays of delayr as2 and delayw as 4. Now when i run the program i get the following results.

exit(1)
@reset : cycles 92, insn #47
@exit : cycles 240, insn #103
diff : cycles 148, insn #56

The point of reset is the start of the C program. Now seeing this main i assume there would be 2 load instructions 1 register add, 1 register multiply and 2 store instructions. But the results say that there are a total of 56 instruction. Now even if the multiplication is treated differently i thought ther might be a total of 20 insn. I am a bit confused by this really high number. It would be great if some one could explain this to me.

Regds

Aravindh

no use no use 1/1 no use no use
© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.