Do you want to try out the lowRISC chip designs, but don't have a couple thousand or million dollars ready for an ASIC tapeout? Running lowRISC designs on an FPGA board can be the answer!
To use the lowRISC Comportable designs on an FPGA you need two things:
Depending on the design/target combination that you want to synthesize you will need different tools and boards. Refer to the design documentation for information what exactly is needed.
Follow the install instructions to [prepare the system]({{< relref “install_instructions#system-preparation” >}}) and to install the [software development tools]({{< relref “install_instructions#software-development” >}}) and [Xilinx Vivado]({{< relref “install_instructions#xilinx-vivado” >}}).
Synthesizing a design for a FPGA board is done with the following commands.
The FPGA build will pull in a program to act as the boot ROM. This must be built before running the FPGA build. This is pulled in from the sw/device/boot_rom
directory (see the parameters:
section of the hw/top_earlgrey/top_earlgrey_nexysvideo.core
file).
To build it:
$ cd $REPO_TOP $ make -C sw/device SW_DIR=boot_rom clean all
At the moment there is no check that the rom.vmem
file is up to date, so it is best to follow the instructions to [Build software]({{< relref “getting_started_sw.md” >}}) and understand the FPGA's overall software flow.
In the following example we synthesize the Earl Grey design for the Nexys Video board using Xilinx Vivado 2018.3.
$ . /tools/xilinx/Vivado/2018.3/settings64.sh $ cd $REPO_TOP $ make -C sw/device SW_DIR=boot_rom clean all $ fusesoc --cores-root . run --target=synth lowrisc:systems:top_earlgrey_nexysvideo
The resulting bitstream is located at build/lowrisc_systems_top_earlgrey_nexysvideo_0.1/synth-vivado/lowrisc_systems_top_earlgrey_nexysvideo_0.1.bit
. See the [reference manual]({{< relref “ref_manual_fpga.md” >}}) for more information.
dmesg
to determine which serial port was assigned. It should be named /dev/ttyUSB*
, e.g. /dev/ttyUSB0
.ls -l /dev/ttyUSB*
. The udev rules given in the Vivado installation instructions ensure this.To flash the bitstream onto the FPGA you need to use either the Vivado GUI or the command line.
Use the following command to program the FPGA with fusesoc.
$ . /tools/xilinx/Vivado/2018.3/settings64.sh $ cd $REPO_TOP $ fusesoc --cores-root . pgm lowrisc:systems:top_earlgrey_nexysvideo:0.1
Note: fusesoc pgm
is broken for edalize versions up to (and including) v0.1.3. You can check the version you're using with pip3 show edalize
. If you have having trouble with programming using the command line, try the GUI.
$ . /tools/xilinx/Vivado/2018.3/settings64.sh $ cd $REPO_TOP $ make -C build/lowrisc_systems_top_earlgrey_nexysvideo_0.1/synth-vivado build-gui
Now the Vivado GUI opens and loads the project.
lowrisc_systems_top_earlgrey_nexysvideo_0.1.bit
as Bitstream file, and leave the Debug probes file empty.The hello_world
demo software shows off some capabilities of the design. In order to load hello_world
into the FPGA, both the binary and the [loading tool]({{< relref “/sw/host/spiflash/README.md” >}}) must be compiled. Please follow the steps below.
$ screen /dev/ttyUSB0 230400Note that the Nexsys Video demo program that comes installed on the board runs the UART at 115200 baud; expect to see garbage characters if that is running. This can happen if you connect the serial console before using Vivado to program your new bitstream or you press the PROG button that causes the FPGA to reprogram from the code in the on-board SPI flash.
$ cd ${REPO_TOP} $ make -C sw/device SW_DIR=examples/hello_world SW_BUILD_DIR=out clean all $ make -C sw/host/spiflash clean all $ ./sw/host/spiflash/spiflash --input=sw/device/out/sw.bin Running SPI flash update. Image divided into 6 frames. frame: 0x00000000 to offset: 0x00000000 frame: 0x00000001 to offset: 0x000003d8 frame: 0x00000002 to offset: 0x000007b0 frame: 0x00000003 to offset: 0x00000b88 frame: 0x00000004 to offset: 0x00000f60 frame: 0x80000005 to offset: 0x00001338
screen
by pressing CTRL-a k, and confirm with y.Sometimes it is helpful to use the Vivado GUI to debug a design. fusesoc makes that easy, with one small caveat: by default fusesoc copies all source files into a staging directory before the synthesis process starts. This behavior is helpful to create reproducible builds and avoids Vivado modifying checked-in source files. But during debugging this behavior is not helpful. The --no-export
option of fusesoc disables copying the source files into the staging area, and --setup
instructs fusesoc to only create a project file, but not to run the synthesis process.
$ # only create Vivado project file $ fusesoc --cores-root . build --no-export --setup lowrisc:systems:top_earlgrey_nexysvideo
To connect the FPGA with OpenOCD, run the following command
$ cd $REPO_TOP $ /tools/openocd/bin/openocd -s util/openocd -f board/lowrisc-earlgrey-nexysvideo.cfg
To actually debug through OpenOCD, it must either be connected through telnet or GDB.
The following is an example for using telnet
$ telnet localhost 4444 // or whatever port that is specificed by the openocd command above $ mdw 0x8000 0x10 // read 16 bytes at address 0x8000
An example connection with GDB, which prints the registers after the connection to OpenOCD is established
$ cd $REPO_TOP $ /tools/riscv/bin/riscv32-unknown-elf-gdb -ex "target extended-remote :3333" -ex "info reg" sw/device/boot_rom/rom.elf
Note that debug support is not yet mature (see https://github.com/lowRISC/opentitan/issues/574). In particular GDB cannot set breakpoints as it can't write to the (emulated) flash memory. HW breakpoint support is planned for Ibex to allow breakpointing code in flash.
Examine 16 memory words in the hex format starting at 0x200005c0
(gdb) x/16xw 0x200005c0
Press enter again to print the next 16 words. Use help x
to get a description of the command.
If the memory content contains program text it can be disassembled
(gdb) disassemble 0x200005c0,0x200005c0+16*4
Displaying the memory content can also be delegated to OpenOCD
(gdb) monitor mdw 0x200005c0 16
Use monitor help
to get a list of supported commands.
To single-step use stepi
or step
(gdb) stepi
stepi
single-steps an instruction, step
single-steps a line of source code. When testing debugging against the hello_world binary it is likely you will break into a delay loop. Here the step
command will seem to hang as it will attempt to step over the whole delay loop with a sequence of single-step instructions which may take quite some time!
To change the program which is debugged the file
command can be used. This will update the symbols which are used to get information about the program. It is especially useful in the context of our rom.elf
, which resides in the ROM region, which will eventually jump to a different executable as part of the flash region.
(gdb) file sw/device/examples/hello_world/sw.elf (gdb) disassemble 0x200005c0,0x200005c0+16*4
The output of the disassemble should now contain additional information.