OpenRisc Verilog simulation of serial port communication

Posted on 2009/12/17

1


OpenRisc is an open source microprocessor architecture; being it open source, one of the key benefits is the possibility to examine it, compile it and make it work. OpenCores provides an environment to compile the Verilog RTL description of a OpenRisc system (called ORPSoC) and run tests using Icarus Verilog, that is a quite mature FLOSS Verilog compiler and event-driven simulator. Here is what I did to set up the simulation environment, following the guidelines in the ORPSoCv2 page:

  • Download the OpenRisc toolchain and install it using the provided script
  • Download the Orpsocv2 system from Subversion repository
  • Install Icarus Verilog and GTKWave (using “sudo apt-get install verilog gtkwave” on my Ubuntu box)
  • Open a terminal and setup the environment, which consists only in adding the “or32-elf/bin” directory to the PATH environment variable (export PATH=”${HOME}/src/openrisc/or32-elf/bin:${PATH}”)

With the environment ready, I got into the directory “orpsocv2/sim/run” and run:

make rtl-tests TESTS=uart-nocache UART_PRINTF=1 VCD=1

the command launches the “uart-nocache” test, printing on the terminal the bytes coming from the UART and dumping the waveforms into a VCD format file. The following is the output on-screen of the simulation:

Beginning loop that will complete the following tests: uart-nocache

################################################################################

 #### Current test: uart-nocache ####

 #### Compiling software ####

make[1]: Entering directory `/home/francesco/src/openrisc/orpsocv2/sw/uart'
or32-elf-gcc -O2 -mhard-mul -g -DUART_PRINTF uart.c -c -o uart.o
In file included from uart.c:1:
../support/support.h:18: warning: conflicting types for built-in function ‘printf’
or32-elf-gcc -mhard-mul -g -DUART_PRINTF  -T ../support/orp.ld uart.o ../support/reset-nocache.o ../support/libsupport.a ../support/except.o -o uart-nocache.or32
or32-elf-objcopy -O binary uart-nocache.or32 uart-nocache.bin
../utils/bin2hex uart-nocache.bin 1 -size_word > uart-nocache-twobyte-sizefirst.hex
../utils/bin2vmem uart-nocache.bin > uart-nocache.vmem
make[1]: Leaving directory `/home/francesco/src/openrisc/orpsocv2/sw/uart'

 #### Compiling RTL ####
/home/francesco/src/openrisc/orpsocv2/sim/run/../../rtl/verilog/components/or1200r2/or1200_cfgr.v:185: warning: Numeric constant truncated to 3 bits.

 #### Beginning simulation ####

Starting RTL simulation of uart-nocache test

VCD in /home/francesco/src/openrisc/orpsocv2/sim/run/../../sim/results/uart-nocache.vcd

VCD info: dumpfile /home/francesco/src/openrisc/orpsocv2/sim/run/../../sim/results/uart-nocache.vcd opened for output.

Hello World.
real 40.16
user 39.58
sys 0.52

 ####
 #### Test uart-nocache PASSED ####
 ####

Test results: 1 out of 1 tests passed

What happened? Here is a diagram:

OpenRisc Hardware/Software cosimulation

OpenRisc Hardware/Software co-simulation

A test program (uart.c) is compiled using the OpenRisc toolchain (or32-elf-gcc), and a memory image is generated (uart-nocache.vmem); the program takes a string “Hello World.\n” and sends it through the UART one byte at a time. The program image is used in simulation to fill the RAM. The Verilog RTL sources, including the OpenRisc core, the UART and the testbench that checks the results, are compiled and then simulated; the software runs and the simulator prints the characters composing “Hello World.” that have been sent to the serial port. It is shown that the simulation took about 40 seconds to run.

After the simulation is completed, it is possible to examine the waveforms of the digital circuit using the graphical software GTKWave to open “../results/uart-nocache.vcd“; this is a screenshot of a part of the simulation (click it to enlarge):

GTKWave display of OpenRisc UART simulation

GTKWave display of OpenRisc UART simulation

In the image it is captured the printing of the “H” character, that in ASCII is coded as 0x48. The red vertical line shows the instant in which the OpenRisc writes 0x48 to the UART. The “Signals” panel shows that “dwb_dat_o” contains the hexadecimal value “48480048”  written in the hexadecimal address “dwb_adr_o = 9000000” that is the zone of memory that contains the UART. The byte is then transmitted serially (and slooowly) up to the most external signal which is “uart0_stx_o“, that can be seen as an external pin of a microchip. This signal is read by a dedicated UART decoder whose purpose is to construct the transmitted data into the “tx_byte” register and print the character to the terminal. Rightmost in the window , in the last line, the character “H” can be seen completely reconstructed, and it will be printed on-screen.

I think that these simulations can be really interesting for those who want to learn about digital electronics, hardware description languages and embedded software development. It is quite easy, and absolutely free, to start toying with this environment, but the concepts are very similar to the digital design of real chips. I can picture students using this as a base for a thesis about hardware IP design, or verification methodology, or optimization of simulators.

Posted in: Embedded, Hardware