Simple RV32I core with extensions
  • SystemVerilog 62.1%
  • C 11.4%
  • Assembly 7.8%
  • Python 5.8%
  • Makefile 5.1%
  • Other 7.7%
Find a file
2026-11-11 17:03:13 -05:00
.devcontainer Move the sources to src, the tests to test and the board build to fpga, add a dev container, and rewrite the documentation for users 2026-11-08 18:10:32 -05:00
.vscode Move the sources to src, the tests to test and the board build to fpga, add a dev container, and rewrite the documentation for users 2026-11-08 18:10:32 -05:00
docs Mark the project as finished for now and list Zephyr and the Z80 emulator as future steps 2026-11-11 17:03:13 -05:00
fpga Keep the divide done flag until the next divide so a divide that ends during a cache miss is not lost 2026-11-08 18:14:28 -05:00
src Make the binary wire the default for the demos and keep ANSI as DEMO_WIRE=ansi 2026-11-09 19:46:42 -05:00
test Move the demo scenes by measured time so their speed does not follow the frame rate 2026-11-09 19:42:40 -05:00
third_party Move the sources to src, the tests to test and the board build to fpga, add a dev container, and rewrite the documentation for users 2026-11-08 18:10:32 -05:00
tools Add a binary demo wire with a host viewer that draws it as ANSI, selected with DEMO_WIRE=bin 2026-11-09 19:31:39 -05:00
.gitignore Move the sources to src, the tests to test and the board build to fpga, add a dev container, and rewrite the documentation for users 2026-11-08 18:10:32 -05:00
.gitmodules Move the sources to src, the tests to test and the board build to fpga, add a dev container, and rewrite the documentation for users 2026-11-08 18:10:32 -05:00
.rules.verible_lint Build the RV32I core, its tests and the Cmod A7 board top 2026-10-05 21:34:27 -04:00
.verible-verilog-format Build the RV32I core, its tests and the Cmod A7 board top 2026-10-05 21:34:27 -04:00
AGENTS.md Mark the project as finished for now and list Zephyr and the Z80 emulator as future steps 2026-11-11 17:03:13 -05:00
CLAUDE.md Reorganize the repository by block and correct the documented numbers 2026-11-01 14:05:23 -05:00
LICENSE Rebuild the pipeline as six bounded stages with a single-cycle TCM 2026-10-18 12:17:45 -04:00
Makefile Make the binary wire the default for the demos and keep ANSI as DEMO_WIRE=ansi 2026-11-09 19:46:42 -05:00
pyproject.toml Move the sources to src, the tests to test and the board build to fpga, add a dev container, and rewrite the documentation for users 2026-11-08 18:10:32 -05:00
README.md Mark the project as finished for now and list Zephyr and the Z80 emulator as future steps 2026-11-11 17:03:13 -05:00
uv.lock Move the sources to src, the tests to test and the board build to fpga, add a dev container, and rewrite the documentation for users 2026-11-08 18:10:32 -05:00

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
A first-person walk through a brick maze, with a minimap A lit cube, icosahedron and torus turning in turn
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

Block diagram of the core and the SoC

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.