- SystemVerilog 62.1%
- C 11.4%
- Assembly 7.8%
- Python 5.8%
- Makefile 5.1%
- Other 7.7%
|
|
||
|---|---|---|
| .devcontainer | ||
| .vscode | ||
| docs | ||
| fpga | ||
| src | ||
| test | ||
| third_party | ||
| tools | ||
| .gitignore | ||
| .gitmodules | ||
| .rules.verible_lint | ||
| .verible-verilog-format | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| LICENSE | ||
| Makefile | ||
| pyproject.toml | ||
| README.md | ||
| uv.lock | ||
rv32i
A RISC-V CPU and a small system-on-chip, written in SystemVerilog, that runs on a Digilent Cmod A7-35T FPGA board at 100 MHz. The core is a seven-stage, in-order RV32IMAC pipeline with caches, interrupts, user mode and memory protection. It passes the official RISC-V architecture tests, matches the Spike reference simulator instruction by instruction, scores 2.867 CoreMark/MHz on the board and runs FreeRTOS.
Programs are loaded over the board's USB cable, so trying a new one takes seconds and no FPGA rebuild. Two demos run on the board and draw in your terminal in 24-bit colour:
| Raycast maze | Rotating solids |
|---|---|
![]() |
![]() |
make demo-load DEMO=raycast |
make demo-load DEMO=spin |
The animations come from the host build of the demo code. The simulation check
make demo-sim confirms that the core draws exactly the same pixels.
At a glance
| ISA | RV32IMAC with Zba, Zbb, Zbs, Zcb, Zicbom, Zicbop, Zicboz, Zicsr, Zifencei, Zicntr, Zihpm, Zihintpause, M and U mode, PMP |
| Pipeline | IF, IA, ID, EX1, EX2, MEM, WB. Single issue, in order, with a BTB and a return stack |
| Memory | 64 KiB TCM, 16 KiB I-cache, 8 KiB write-back D-cache, 512 KiB external SRAM |
| Peripherals | UART, GPIO, CLINT timer and PLIC, with SiFive-compatible register maps |
| Board | Cmod A7-35T at 100 MHz, timing met with +0.008 ns of slack. 9772 LUT, 47 percent of the FPGA |
| CoreMark | 2.867 CoreMark/MHz, CPI 1.182, measured on the board from the TCM and from the SRAM |
| Tests | 44 unit tests, 202 of 202 riscv-arch-test ELFs, 20 random programs in lockstep with Spike |
Quick start
1. Get the code
git clone --recursive https://forge.db-serve.com/dbajan/rv32i.git
cd rv32i
--recursive also fetches CoreMark and the FreeRTOS kernel into
third_party/. In a clone made without it, run git submodule update --init.
2. Get the tools
The easiest way is the dev container, which has every tool at the right
version. Open the folder in VS Code with the Dev Containers extension, accept
"Reopen in Container" and wait for the image to build the first time. It works
with Docker and with Podman. .devcontainer/README.md
covers Podman and use without VS Code.
To install the tools on your own machine instead, follow docs/getting-started.md. You need Verilator 5, Verible, a RISC-V GCC with newlib, Python 3 and, for co-simulation, Spike.
Either way, check what make can find:
make print-tools
3. Run the tests
make test # the 44 unit and instruction tests, about two minutes
make regress # everything that runs without a board, with a summary table
make regress adds the architecture tests, CoreMark, FreeRTOS, the boot ROM
programs, the demos and the Spike co-simulation. It skips a check whose input is
missing and says which one. docs/simulation.md explains
each check, how to run a single test, how to look at waveforms and how to run
your own C program.
Run it on the board
You need the board, a micro-USB cable and Vivado 2025.2, either installed
locally or as the container image from
.devcontainer/vivado/. make uses whichever
it finds.
make fpga # build the bitstream, about 10 minutes
make fpga-program # program the board over USB
The bitstream holds a UART loader, so from here on every program is one command. Press BTN0 on the board before each one:
make demo-load DEMO=raycast # the maze demo
make demo-load DEMO=spin # the rotating solids
make load ELF=build/freertos/freertos.elf # FreeRTOS
make coremark-fpga-hex && make load ELF=build/coremark_fpga/coremark.elf # CoreMark
Each one opens the board's console in your terminal. Ctrl-C leaves it. Run these from a terminal on the host, because the dev container cannot see the USB serial port. docs/board.md walks through every step, what each program prints, and what to do when something does not work.
Common commands
| Command | What it does |
|---|---|
make test |
Unit and instruction tests |
make run-<name> |
One test, for example make run-dcache |
make run-<name> WAVES=1 |
The same, and write build/waves/tb_<name>.fst for Surfer |
make run PROG=src/sw/examples/hello.c |
Compile a C program and run it on the simulated core |
make test-arch |
The riscv-arch-test suite |
make cosim-regress |
20 random programs compared with Spike |
make coremark |
CoreMark in simulation |
make regress |
All of the above that your tools allow |
make lint, make format |
Verible lint and format |
make fpga, make fpga-program |
Build the bitstream and program the board |
make clean-vivado |
Remove Vivado's logs and temporary files, keep the bitstreams |
make load ELF=<file> |
Send a program to the board and open its console |
make print-tools |
Show which tools were found |
Repository layout
src/rtl/ the CPU and the SoC in SystemVerilog, listed in order in src/rtl/rtl.f
src/sw/ software for the board: boot ROM, CoreMark port, FreeRTOS demo, ANSI demos
test/ testbenches (tb/), whole-system tests (system/), riscv-arch-test (arch/),
Spike co-simulation (cosim/) and the test programs (programs/)
fpga/ board top level, pin constraints and Vivado scripts
tools/ host tools: the program loader, the demo renderer, timing summaries
third_party/ CoreMark and the FreeRTOS kernel, as git submodules
.devcontainer/ the dev container, and the Vivado image in vivado/
docs/ documentation, with the development notes in docs/dev/
build/ everything generated, not tracked
Documentation
| Document | Read it to |
|---|---|
| docs/getting-started.md | Install the tools, natively or with the dev container |
| docs/simulation.md | Run tests, look at waveforms, run programs, co-simulate with Spike |
| docs/board.md | Build the bitstream, program the board, load and run programs |
| docs/architecture.md | Understand how the core and the SoC are built |
| docs/isa.md | See which instructions and extensions are implemented |
| docs/peripherals.md | Write software: the memory map and the register maps |
| src/sw/demos/README.md | Learn how the ANSI demos work |
| docs/dev/ | Change the design: decisions, measurements, plans |
Status
The project is finished for now. The core, the SoC, the tests and the demos are done and run on the board. Two extensions may follow: Zephyr, to show that its stock drivers work with the SiFive-compatible peripherals, and a Z80 emulator running CP/M. docs/dev/plan.md lists them with the smaller open items.
License
Apache License 2.0, see LICENSE. CoreMark and FreeRTOS in
third_party/ keep their own licenses.
Copyright 2026 Dragos Bajanica.

