Run on FPGA
This project offers X-HEEP implementations on Xilinx FPGAs.
Set-up
In this version, the X-HEEP architecture is implemented on the programmable logic (PL) side of the FPGA, and its input/output are connected to the available headers on the FPGA board.
The following FPGA boards are supported:
Vendor |
Board |
BOARD_NAME |
|---|---|---|
TUL |
pynq-z2 |
|
AMD |
zcu104 |
|
AMD |
zcu102 |
|
Digilent |
nexys-a7-100t |
|
Digilent |
genesys2 |
|
RealDigital |
aup-zu3 |
Make sure you have the FPGA board files installed in your Vivado.
For example, for the Pynq-Z2 board, use the documentation provided at the following link to download and install them.
Make sure you set up the Vivado environments by running
source <vivado-installation-path>/settings64.sh
We recommend adding this command to your
.bashrcInstall the Xilinx cable drivers.
Follow the instructions for Linux
Restart your PC
Building and programming the FPGA
To build and program the bitstream for your FPGA with vivado, make sure you have run mcu-gen and then run:
make vivado-fpga FPGA_BOARD=<BOARD_NAME>
where <BOARD_NAME> can be chosen among the supported boards from the above table. From now on we will refer to it as <BOARD_NAME>.
Adding the fusesoc flag use_bscane_xilinx enables the native Xilinx scanchain for the JTAG interface in the on chip debug module (Currently only supported for the pynq-z2 board):
make vivado-fpga FPGA_BOARD=pynq-z2 FUSESOC_FLAGS=--flag=use_bscane_xilinx
To program the bitstream, open Vivado,
open --> Hardware Manager --> Open Target --> Autoconnect --> Program Device
and choose the file openhwgroup.org_systems_core-v-mini-mcu_<version>.bit in the build/openhwgroup.org_systems_core-v-mini-mcu_<version>/<BOARD_NAME>-vivado.
Or simply type:
make vivado-fpga-pgm FPGA_BOARD=<BOARD_NAME>
Build and program the FPGA using the Processing System
The Processing System (PS) enables remote access to the SoC over SSH. With the PYNQ utilities, you can connect to the board and program the FPGA by loading the bitstream from Python.
Setting the PS_ENABLE argument instantiates the PS in the design for the supported boards:
make vivado-fpga FPGA_BOARD=pynq-z2 FUSESOC_PARAM="--PS_ENABLE"
Upload the bitstream to the remote board
To program the bitstream upload both the .bit and the .hwh file to the board,
scp ./build/<project_name>_<version>/<board_target>-vivado/<project_name>.runs/impl_1/<project_name>_wrapper.bit board@remote-host:/path/to/bitstream/
scp ./build/<project_name>_<version>/<board_target>-vivado/<project_name>.gen/sources_1/bd/<project_name>/hw_handoff/xilinx_ps_wizzard.hwh board@remote-host:/path/to/bitstream/<project_name>_wrapper.hwh
Or simply type:
make vivado-fpga-remote-pgm FPGA_BOARD=<BOARD_NAME> REMOTE=board@remote-host REMOTE_DIR=/path/to/bitstream
Warning
Important: The *.bit and *.hwh files must:
Have the same base name (
ex.bit&ex.hwh).Be in the same directory. This ensure the bitstream to be loaded correctly through the PYNQ drivers.
Program the FPGA on the remote board
SSH into the board, activate the PYNQ environment, and load the overlay:
$ ssh board@remote-host
$ sudo -i
# source /etc/profile.d/pynq-venv.sh
# python
>>> from pynq import Overlay
>>> ol = Overlay("/path/to/bitstream.bit")
Additionally, you can find utilities to program the bitstream on the FPGA and run programs from the Processing System in the following repository: xheep-Xilinx-SoCs-interface.
Running firmware on the FPGA
To run SW, follow the Debug guide to load the binaries with the HS2 cable over JTAG, or follow the ExecuteFromFlash guide if you have a FLASH attached to the FPGA.
Do not forget that the pynq-z2 board requires you to have the ethernet cable attached to the board while running.
For example, if you want to run your application using flash_exec, do as follow:
compile your application, e.g. make app PROJECT=example_matfadd TARGET=pynq-z2 ARCH=rv32imfc LINKER=flash_exec
and then follow the ExecuteFromFlash to program the flash and set the boot buttons on the FPGA correctly.
To look at the output of your printf, run in another terminal:
picocom -b 9600 -r -l --imap lfcrlf /dev/ttyUSB2
Please be sure to use the right ttyUSB number (you can discover it with dmesg --time-format iso | grep FTDI for example).
To get X-HEEP running on the FPGA, you need to program the FPGA with the bitstream generated by the make vivado-fpga command. After that, you can run the software application on it.
On Xilinx FPGAs, the JTAG, UART, and SPI interfaces of X-HEEP are exposed on PMODs. Once that you have identified the pinout of the PMODS you can connect to them your preferred JTAG connector, UART to USB converter, and SPI flash programmer.
To run the software application on the FPGA, you can use the HS2 cable to load the binaries over JTAG, or you can use the SPI flash programmer to program the flash and set the boot switches on the FPGA correctly.
Both the JTAG, UART and SPI interfaces are mapped to be compliant with the ESL iceprog compatible programmer.
To interface with the jtag one can use openocd, to interface with the UART one can use picocom, and to interface with the SPI flash one can use iceprog (from the icestorm project) already shipped and built in X-HEEP main repo.
Check the Debug and ExecuteFromFlash guides for more details.
FPGA Utilizations
X-HEEP is a continuously evolving design, therefore these numbers need to be updated from time to time.
As of today (29.01.2025), on a pynq-z2 FPGA, X-HEEP utilizes:
Small configuration
It contains few peripherals, 64kB of SRAM, the small bus, and the CV32E2 CPU with RV32IMC ISA extensions.
Generated as:
make mcu-gen MCU_CFG_PERIPHERALS=mcu_cfg_minimal.hjson
make vivado-fpga FPGA_BOARD=pynq-z2
Resource |
Quantity |
Utilization (%) |
|---|---|---|
Slice LUTs |
12.1K |
22.7 |
Slice Registers |
12.1K |
11.3 |
RAM |
16 |
11.4 |
DSP |
1 |
0.5 |
Bigger configuration
It contains more peripherals, 64kB of SRAM, the wider bus, and the CV32E40P CPU with RV32IMFCXpulp ISA extensions.
Generated as:
make mcu-gen CPU=cv32e40p BUS=NtoM
make vivado-fpga FPGA_BOARD=pynq-z2 FUSESOC_PARAM="--COREV_PULP=1 --FPU=1"
Resource |
Quantity |
Utilization (%) |
|---|---|---|
Slice LUTs |
33.5K |
62.9 |
Slice Registers |
28.8K |
27.1 |
RAM |
16 |
11.4 |
DSP |
9 |
4.1 |
Note
The FUSESOC_PARAM="--COREV_PULP=1 --FPU=1" is an old way to enable the CV32E40P CPU with FPU and PULP extensions.
Now you can check the CPU Configuration docs to see how to enable those features using the make mcu-gen command.