This is the mail archive of the crossgcc@sources.redhat.com mailing list for the crossgcc project.
See the CrossGCC FAQ for lots more information.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
>>> This is a system model that is in VHDL. It has the xscale model and the entire system peripherals including a memory model in VHDL/Verilog. VHDL/Verilog has it's own set of issues most people on this list probably have never been through, or seen. The biggest monkey is simulation speed. I've done several chips like this in the past. Below is an out line of the solution that I have used numerous times, it also leads to very fast simulation runs :-> -Duane. Do the following: a) Compile a single C function like this: (ie: foo.c -> foo.o) int foo( int x, y ) { return x + y; } b) Create a tiny startup code file has 2 instructions and lives at the reset vector. (ie: startup.s -> startup.o) reset_vector: ldr sp,=stack_space bl foo Later - you'll come back and expand this - but for now only do these 2 instructions. {Alternative - do your initial test in assembler - then the above C code test} c) Figure out how to compile and link the above. I create an ASCII dump of the rom image. I load it into verilog using the $readmemh() function This entire executable should require less then 40 to 50 bytes. You specifically *DO*NOT* want any libraries yet. Your code should be 100% self contained. You should be using only "arm-elf-ld" to link your file with a minimal LINKER SCRIPT. ie: arm-elf-gcc -c -o foo.o foo.c arm-elf-as -o startup.o startup.s arm-elf-ld -T my-ld-script -o test.axf startup.o foo.o Use OBJDUMP (and/or other tools) to convert/dump the ELF file into BINARY and finally into an ASCII hex text file. d) Run that code under your Verilog/VHDL simulation. In my case - I found this little file called "log.eis" that is *100%* not documented - stumbled across it.... It is a debug dump from the arm core model with a disassembly of all the instructions the cpu executes. Very helpful! Maybe you have this, maybe you don't Your milage may very. I wrote a little perl script that goes through and inserts symbols into the disassembly trace - Very Helpful! I also look at timing wave forms. It varies. e) Repeat the above - but instead of adding - divide x/y in the function - (this introduces the need for libgcc.a) Code size will increase a bit - maybe 1K bytes now. Slowly - add more stuff -- Ok - Now you have a the ability to do simple code. Now - the question is to expand to the standard C library (be it NEWLIB, or something else - or roll your own specific to your test requirements) The underlying question really is - How much simulation horse power do you have? In our case - 1second of verilog simulation time is a 36 to 40 hour run. printf() and the standard C library is *PAINFUL* Do you really want wait 20 minutes for the startup code to run? Do you you want to wait 30 minutes just to watch printf() slowly print "Starting simulation"? Or do you want to do this faster? What level of pain do you enjoy? What I do is create some functions like this: verilog_string( string ); verilog_string_hex32( string, value ); verilog_string_hex16( string, value ); verilog_string_hex8( string, value ); verilog_string_decimal( string, value ); verilog_time_of_event( string ); And use it them like this: verilog_event( "Starting simulation: " ); verilog_string_hex32("IRQ Bits are: ", x ); verilog_event("The time is now: "); I wrote these verilog_string functions in assembler. Why waste simulation time? Besides, they are short. Now - the majic of verilog - what these functions do is write to majic locations in our simulation ROM. Somewhere in the test bench the hardware guys insert some verilog code (see below) that looks for writes to the simulated ROM - when it finds a specific condition - it prints helpful things instead of error messages. Perhaps you want to make a "VerilogDebugUart" device - you can add to other test benches you might need to use. The important code snippit from verilog looks like this: case (Address[15:0]) 16'hf000: begin $fwrite(log, "Status: Failed\n"); $stop; end 16'hf004: begin $fwrite(log, "Status: Sucess\n"); $stop; end 16'hf008: begin // Write ascii byte, used for STRING printing $fwrite(log, "%s", Data[7:0] ); end 16'hf00c: begin // Write HEX 32 bit value // Faster then having the C code print it! $fwrite(log, "%h", Data[31:0]) end 16'hf010: //Write current time for verilog_event() // Helpful to relate code messages to a time // position in a long waveform run. begin $fwrite( log, "%d\n", $stime ); end ... you can add more ... endcase ------ Want more information? See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/ Want to unsubscribe? Send a note to crossgcc-unsubscribe@sources.redhat.com
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |