blob: bc8e03e3e5bd5716bdbf1bddbfb1c9c4baa48da1 [file] [log] [blame] [view]
---
title: "FPGA Setup"
aliases:
- /doc/ug/getting_started_fpga
---
_Before following this guide, make sure you've followed the [dependency installation and software build instructions]({{< relref "getting_started" >}})._
Do you want to try out OpenTitan, but don't have a couple thousand or million dollars ready for an ASIC tapeout?
Running OpenTitan on an FPGA board can be the answer!
<!-- TODO: Switch all calls to fusesoc and the Verilated system to refer to Meson, once it supports fusesoc. -->
## Prerequisites
To use the OpenTitan on an FPGA you need two things:
* A supported FPGA board
* A tool from the FPGA vendor
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 on what exactly is needed.
* [Obtain an FPGA board]({{< relref "fpga_boards.md" >}})
## Obtain an FPGA bitstream
To run OpenTitan on an FPGA, you will need an FPGA bitstream.
You can either download the latest bitstream for the ChipWhisperer CW310 board or build it yourself.
### Download a Pre-built Bitstream
If you are using the ChipWhisperer CW310 board with the Xilinx Kintex 7 XC7K410T FPGA, you can download the latest passing [pre-built bitstream](http://storage.googleapis.com/opentitan-bitstreams/master/bitstream-latest.tar.gz).
For example, to download and unpack the bitstream, run the following:
```console
mkdir -p /tmp/bitstream-latest
cd /tmp/bitstream-latest
curl https://storage.googleapis.com/opentitan-bitstreams/master/bitstream-latest.tar.gz -o bitstream-latest.tar.gz
tar -xvf bitstream-latest.tar.gz
```
By default, the bitstream is built with a version of the boot ROM used for testing (called the _test ROM_; pulled from `sw/device/lib/testing/test_rom`).
There is also a version of the boot ROM used in production (called the _mask ROM_; pulled from `sw/device/silicon_creator/mask_rom`).
This can be spliced into the bitstream to overwrite the testing boot ROM as described in the [FPGA Reference Manual]({{< relref "ref_manual_fpga.md#boot-rom-development" >}}).
However, if you do not want to do the splicing yourself, both versions of the bitstream are available in the download as `*.bit.orig` and `*.bit.splice` (containing the test ROM and the mask ROM respectively).
The metadata for the latest bitstream (the approximate creation time and the associated commit hash) is also available as a text file and can be [downloaded separately](https://storage.googleapis.com/opentitan-bitstreams/master/latest/latest.txt).
### Create an FPGA bitstream
Synthesizing a design for an 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/lib/testing/test_rom` directory (see the `parameters:` section of the `hw/top_earlgrey/chip_earlgrey_cw310.core` file).
To build it:
```console
cd $REPO_TOP
./meson_init.sh
ninja -C build-out all
```
Next, the actual FPGA implementation can be started.
In the following example we synthesize the Earl Grey design for the ChipWhisperer CW310 board using Xilinx Vivado {{< tool_version "vivado" >}}.
```console
. /tools/Xilinx/Vivado/{{< tool_version "vivado" >}}/settings64.sh
cd $REPO_TOP
./meson_init.sh
ninja -C build-out all
fusesoc --verbose --cores-root . run --flag=fileset_top --target=synth lowrisc:systems:chip_earlgrey_cw310
```
The `fileset_top` flag used above is specific to the OpenTitan project to select the correct fileset.
The resulting bitstream is located at `build/lowrisc_systems_chip_earlgrey_cw310_0.1/synth-vivado/lowrisc_systems_chip_earlgrey_cw310_0.1.bit`.
See the [reference manual]({{< relref "ref_manual_fpga.md" >}}) for more information.
#### Dealing with FPGA Congestion Issues
The default Vivado tool placement may sometimes result in congested FPGA floorplans.
When this happens, the implemenation time and results become unpredictable.
It may become necessary for the user to manually adjust certain placement.
See [this comment](https://github.com/lowRISC/opentitan/pull/8138#issuecomment-916696830) for a thorough analysis of one such situation and what changes were made to improve congestion.
#### Opening existing project with the Vivado GUI
Sometimes, it may be desirable to open the generated project in the Vivado GUI for inspection.
To this end, run:
```console
. /tools/Xilinx/Vivado/{{< tool_version "vivado" >}}/settings64.sh
cd $REPO_TOP
make -C build/lowrisc_systems_chip_earlgrey_cw310_0.1/synth-vivado build-gui
```
Now the Vivado GUI opens and loads the project.
#### Develop with the Vivado GUI
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 not start the synthesis process.
```console
# only create Vivado project directory
cd $REPO_TOP
fusesoc --cores-root . run --flag=fileset_top --target=synth --no-export --setup lowrisc:systems:chip_earlgrey_cw310
```
You can then navigate to the created project directory, and open Vivado
```console
. /tools/Xilinx/Vivado/{{< tool_version "vivado" >}}/settings64.sh
cd $REPO_TOP/build/lowrisc_systems_chip_earlgrey_cw310_0.1/synth-vivado/
vivado
```
Finally, using the tcl console, you can kick off the project setup with
```console
source lowrisc_systems_chip_earlgrey_cw310_0.1.tcl
```
## Connecting the ChipWhisperer CW310 board
The ChipWhisperer CW310 board supports different power options.
It is recommended to power the board via the included DC power adapter.
To this end:
1. Set the *SW2* switch (to the right of the barrel connector) up to the *5V Regulator* option.
1. Set the switch below the barrel connector to the right towards the *Barrel* option.
1. Set the *Control Power* switch (bottom left corner, *SW7*) to the right.
1. Ensure the *Tgt Power* switch (above the fan, *S1*) is set to the right towards the *Auto* option.
1. Plug the DC power adapter into the barrel jack (*J11*) in the top left corner of the board.
1. Use a USB-C cable to connect your PC with the *USB-C Data* connector (*J8*) in the lower left corner on the board.
You can now use the following to monitor output from dmesg:
```console
sudo dmesg -Hw
```
This should show which serial ports have been assigned, or if the board is having trouble connecting to USB.
If `dmesg` reports a problem you can trigger a *USB_RST* with *SW5*.
When properly connected, `dmesg` should identify the board, not show any errors, and the status light should flash.
They should be named `'/dev/ttyACM*'`, e.g. `/dev/ttyACM1`.
To ensure that you have sufficient access permissions, set up the udev rules as explained in the [Vivado installation instructions]({{< relref "install_vivado" >}}).
## Flash the bitstream onto the FPGA
Note: The following examples assume that you have a `~/.config/opentitantool/config` with the proper `--interface` and `--conf` options.
For CW310, its contents would look like:
```
--interface=cw310
--conf=<ABS_PATH_TO_YOUR_CLONE>/sw/host/opentitantool/config/opentitan_cw310.json
```
To flash the bitstream onto the FPGA using `opentitantool`, use the following command:
```console
cd $REPO_TOP
# If you downloaded the bitstream:
bazel run //sw/host/opentitantool load-bitstream /tmp/bitstream-latest/lowrisc_systems_chip_earlgrey_cw310_0.1.bit.orig
# If you built the bitstream yourself:
bazel run //sw/host/opentitantool load-bitstream $(ci/scripts/target-location.sh //hw/bitstream/vivado:fpga_cw310_test_rom)
```
Depending on the FPGA device, the flashing itself may take several seconds.
After completion, a message like this should be visible from the UART:
```
I00000 test_rom.c:81] Version: earlgrey_silver_release_v5-5886-gde4cb1bb9, Build Date: 2022-06-13 09:17:56
I00001 test_rom.c:87] TestROM:6b2ca9a1
I00002 test_rom.c:118] Test ROM complete, jumping to flash!
```
## Testing the demo design
The `hello_world` demo software shows off some capabilities of the design.
To load `hello_world` into the FPGA on the ChipWhisperer CW310 board follow the steps shown below.
1. Generate the bitstream and flash it to the FPGA as described above.
1. Open a serial console (use the device file determined before) and connect.
Settings: 115200 baud, 8 bits per byte, no software flow-control for sending and receiving data.
```console
screen /dev/ttyACM1 115200,cs8,-ixon,-ixoff
```
1. Run `opentitantool`.
```console
cd ${REPO_TOP}
bazel run //sw/host/opentitantool set-pll # This needs to be done only once.
bazel build //sw/device/examples/hello_world:hello_world_fpga_cw310_bin
bazel run //sw/host/opentitantool bootstrap $(ci/scripts/target-location.sh //sw/device/examples/hello_world:hello_world_fpga_cw310_bin)
```
and then output like this should appear from the UART:
```
I00000 test_rom.c:81] Version: earlgrey_silver_release_v5-5886-gde4cb1bb9, Build Date: 2022-06-13 09:17:56
I00001 test_rom.c:87] TestROM:6b2ca9a1
I00000 test_rom.c:81] Version: earlgrey_silver_release_v5-5886-gde4cb1bb9, Build Date: 2022-06-13 09:17:56
I00001 test_rom.c:87] TestROM:6b2ca9a1
I00002 test_rom.c:118] Test ROM complete, jumping to flash!
I00000 hello_world.c:66] Hello World!
I00001 hello_world.c:67] Built at: Jun 13 2022, 14:16:59
I00002 demos.c:18] Watch the LEDs!
I00003 hello_world.c:74] Try out the switches on the board
I00004 hello_world.c:75] or type anything into the console window.
I00005 hello_world.c:76] The LEDs show the ASCII code of the last character.
```
1. Observe the output both on the board and the serial console. Type any text into the console window.
1. Exit `screen` by pressing CTRL-a k, and confirm with y.
### Troubleshooting
If the firmware load fails, try pressing the "USB RST" button before loading the bitstream.
## Connect with OpenOCD and debug
To connect the ChipWhisperer CW310 FPGA board with OpenOCD, run the following command
```console
cd $REPO_TOP
openocd -s util/openocd -f board/lowrisc-earlgrey-cw310.cfg
```
See the [install instructions]({{< relref "install_openocd" >}}) for guidance on installing OpenOCD.
To actually debug through OpenOCD, it must either be connected through telnet or GDB.
### Debug with OpenOCD
The following is an example for using telnet
```console
telnet localhost 4444 // or whatever port that is specificed by the openocd command above
mdw 0x8000 0x10 // read 16 bytes at address 0x8000
```
### Debug with GDB
An example connection with GDB, which prints the registers after the connection to OpenOCD is established
```console
cd $REPO_TOP
/tools/riscv/bin/riscv32-unknown-elf-gdb -ex "target extended-remote :3333" -ex "info reg" build-bin/sw/device/lib/testing/test_rom/test_rom_fpga_cw310.elf
```
#### Common operations with GDB
Examine 16 memory words in the hex format starting at 0x200005c0
```console
(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
```console
(gdb) disassemble 0x200005c0,0x200005c0+16*4
```
Displaying the memory content can also be delegated to OpenOCD
```console
(gdb) monitor mdw 0x200005c0 16
```
Use `monitor help` to get a list of supported commands.
To single-step use `stepi` or `step`
```console
(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.
```console
(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.