This repository contains the sources and helper scripts to build and run the CapliFive system (emulation and FPGA). The system can run either through QEMU-based emulation or on FPGA, and consists of components with the right versions that work together:
- QEMU-based emulator: hw/qemu
- Software stack and buildroot: sw/buildroot
- AnvilHDL compiler: hw/anvil
- RTL design: hw/rtl
The documentation provided here is intended to provide consistent and easy-to-follow instructions for building the whole system from scratch. For more detail on configuring each component or development setup, please refer to the README documents of individual components.
Operating system: a Debian-based GNU/Linux distribution (instructions provided in this document were tested on Ubuntu 22.04 LTS)
Recommended packages:
sudo apt update
sudo apt install -y git build-essential pkg-config meson ninja-build python3 \
python3-pip clang gcc-multilib g++-multilib bc bison flex libglib2.0-dev \
libpixman-1-dev libfdt-dev libaio-dev libcap-dev libseccomp-dev libslirp-dev \
device-tree-compiler help2man libncurses5-dev openjdk-11-jdk opam duneYou also need to install the Rust toolchain:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shInitialise all submodules contained in this repository:
git submodule update --init --recursive
source ~/.cargo/envThe scripts/ directory provides shell scripts and a Podman Containerfile that
automate the build steps described below. Using the container avoids installing
the build dependencies directly on your machine.
Build the image once (requires Podman):
scripts/build-image.shThis creates a caplifive-build:latest image with all required packages,
the Rust toolchain, and OCaml 5.2 (for Anvil). It also creates a named Podman
volume caplifive-opam pre-seeded with the opam state from the image.
The volume is mounted into every container run so that packages installed
by build-anvil.sh (e.g. the anvil binary) persist across container
invocations. If you rebuild the image, re-run build-image.sh to refresh
the volume, then re-run build-anvil.sh.
Use scripts/run-in-container.sh to run any build script inside the container
with the repository mounted at /workspace:
scripts/run-in-container.sh <command>scripts/run-in-container.sh scripts/setup.sh
scripts/run-in-container.sh scripts/build-qemu.sh
scripts/run-in-container.sh "scripts/build-software.sh --mode qemu"
# Run QEMU in the same container it was built in to avoid shared library
# mismatches (e.g. libslirp). SSH inside the guest is on host port 60022.
scripts/run.sh --containerVivado is bind-mounted into the container so that anvil and Vivado share the same environment, with no host-side tool installation needed beyond Vivado itself.
scripts/run-in-container.sh scripts/setup.sh
export VIVADO_HOME=/path/to/vivado
scripts/build-rtl.sh --container # mounts VIVADO_HOME into the container
scripts/run-in-container.sh "scripts/build-software.sh --mode fpga"Each script can also be run directly if the required packages are already installed. From the repository root:
scripts/setup.sh
scripts/build-qemu.sh
scripts/build-software.sh --mode qemu # or --mode fpga
scripts/build-anvil.sh
export VIVADO_HOME=/path/to/vivado
scripts/build-rtl.sh # FPGA only; needs VIVADO_HOME and anvil in PATH
scripts/run.shIf you only want to run the system on FPGA, please skip this part.
cd hw/qemu
sh configure.sh
make -C build install -j$(nproc)
sed -i 's:caplifive-buildroot:../sw/buildroot:' qemu-args.txtBuild the software stack:
cd sw/buildroot
make setup DEFCONFIG=$(pwd)/configs/qemu_capstone_defconfig
make build DEFCONFIG=$(pwd)/configs/qemu_capstone_defconfigYou can start the emulator with the provided scripts:
cd hw/qemu
./start.sh # start a QEMU instance using the built imagesIf you only want to run the system on Caplifive-QEMU, please skip this part.
This repository also includes an RTL design that can run on FPGA. It currently supports the Genesys 2 board. For this part, make sure you have a Genesys 2 board and a Vivado installation with a suitable licence.
Location: hw/anvil
A specific version of the Anvil compiler is needed to build the RTL design for running on FPGA.
cd hw/anvil
opam install . --deps-only
eval $(opam env)
dune build --release
opam install .Make sure now that anvil is in your PATH.
Location: hw/rtl
Point the VIVADO_HOME environment variable to the location of your
Vivado installation:
export VIVADO_HOME=/location/to/vivadoEdit hw/rtl/fpga-env.sh to point RISCV to the location of your RISC-V toolchain.
Next, generate the bitstream (it may take hours):
cd hw/rtl
bash run-synthesis.shThe generated bitstream can be found at hw/rtl/corev_apu/fpga/work-fpga/ariane_xilinx.bit.
Finally, configure the FPGA through the non-volatile SPI flash: connect the JTAG port
of the Genesys 2 board to the host and use openFPGALoader openFPGALoader -f -b genesys2 <bitstream-file>.
The software stack is located at sw/buildroot.
First, build the boot image:
cd sw/buildroot
make setup
make build
make build LINUX_PAYLOAD=1The generated image is located at
sw/buildroot/build/opensbi-custom/build/platform/generic/firmware/fw_payload.bin.
Next, write the boot image to a microSD card:
dd if=<image-file> of=/dev/sd<device> status=progress oflag=sync bs=4M conv=sparseInsert the microSD card into the SD card reader slot on the Genesys 2 board and connect the UART port to the host. Open the serial port with a terminal emulator
screen /dev/ttyUSB0 57600Power on the board. After booting (~10 minutes), you should be able to interact with the system through the terminal.