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]

Re: gcc on an OS less system


>>> 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]