FPGA RISC-V Open-sourced in SystemVerilog by TwoSigma
FROST is a two-wide, out-of-order RISC-V processor for FPGAs, written in SystemVerilog. It implements RV64GCB with machine, supervisor, and user modes and Sv39 virtual memory. The AMD Alveo X3522PV configuration targets 322 MHz and boots Debian 13 with Debian's unmodified riscv64 kernel, mounting its root filesystem over NFS through its own 10 Gigabit Ethernet NIC. It runs CoreMark at 4.51 CoreMark/MHz, 1,453 CoreMark at 322 MHz.
The diagram shows the X3 configuration; click it for the full-size version.
- Debian 13 with systemd on an NFS root filesystem; the Debian guide walks through the setup. A Linux driver for the memory error unit reports DDR ECC errors, scrubs corrected lines, and patrols memory in the background.
- A 10 Gigabit Ethernet NIC with FROST's own MAC and PCS, descriptor-ring DMA that is coherent with the data caches, and a Linux driver.
- Continuous testing on pull requests and pushes to
main: the RISC-V architecture tests and random riscv-torture programs checked against Spike, the riscv-tests suites, and TestRIG, which compares FROST with the Sail RISC-V model one instruction at a time on random sequences drawn anew on every run. Formal proofs, unit benches for the hardware blocks, and whole programs from BRAM and DDR run alongside, and CI merges simulation coverage, including cover points for microarchitectural corner cases, into one report. - A reusable CPU:
cpu_toppackages the core, its MMUs, and the caches as one single-clock module with an AXI4 memory master. In the SoC, the NIC and the DMA test engine attach over AXI4: their DMA bursts enter the coherent data caches through a bridge, and their registers sit on AXI4-Lite. - An open-source flow: simulation (Verilator and cocotb), synthesis checks (Yosys), and formal proofs (SymbiYosys) run in a pinned Docker image, and OpenROAD takes the design from synthesis to GDS on the FreePDK45 process, with SRAM macros that OpenRAM generates for the caches, the instruction and data memories, and the NIC's buffers; the ASIC guide lists what the flow reduces or mocks. AMD Vivado is needed only for the FPGA itself: building bitstreams and programming and loading the board.
- A cycle-approximate performance model of the CPU and memory system for design-space sweeps, with RTL event capture and a CoreMark IPC comparison against the RTL. Optional hardware performance counters report stall causes, occupancy, and cache traffic.
- FreeRTOS and all nine EEMBC CoreMark-PRO workloads.
- A VS Code extension that programs the FPGA, builds and loads software, and debugs it with source breakpoints and a two-way serial console, locally or over Remote-SSH.
- Native SystemVerilog rather than RTL generated from Chisel or SpinalHDL, with optional Xilinx primitives and board integration kept separate.
- The Apache 2.0 license.
You don't need an FPGA to try FROST. On an x86-64 Linux host with Git, Docker, and Python 3.12 or newer:
git clone --recurse-submodules https://github.com/twosigma/frost.git
cd frost
docker build -t frost . # build the toolchain image
./scripts/frost.py doctor # check the setup (read-only)
./scripts/frost.py cocotb hello_world # simulate the SoC running Hello WorldThe first image build compiles GCC, Verilator, Yosys, QEMU, Spike, and other
tools from source, so expect it to take a while; doctor reports when a
change to the Dockerfile calls for a rebuild. The last command compiles the
program, simulates the full SoC in Verilator, and prints Frost: Hello, world!
from the simulated UART. scripts/frost.py runs each tool inside the image as
your user, so build outputs stay yours. Use it for every simulation, formal,
and lint run.
Other programs to simulate:
./scripts/frost.py cocotb directed_traps # directed M-mode trap and interrupt tests
./scripts/frost.py cocotb isa_test # ISA self-test
./scripts/frost.py cocotb coremark # CoreMark benchmark
./scripts/frost.py cocotb coremark_pro_core # CoreMark-PRO core workload
./scripts/frost.py cocotb freertos_demo # FreeRTOS demo
./scripts/frost.py cocotb ddr_heap_test # multi-MB malloc through the caches into DDR
./scripts/frost.py cocotb frost_cache # cache hierarchy unit bench
./scripts/frost.py cocotb --list-tests # every simulation target
# Run a program from cached DDR instead of on-chip BRAM
FROST_COCOTB_MEM_CONFIG=ddr ./scripts/frost.py cocotb hello_world
# Write waveforms (tests/dump.fst)
WAVES=1 ./scripts/frost.py cocotb directed_traps
# Open a shell inside the image
./scripts/frost.py shellFPGA builds and board tools run natively on a host with Vivado 2025.2 and the RISC-V toolchain:
# 1. Build the bitstream (takes hours)
./fpga/build/build.py x3
# 2. Program the FPGA
./fpga/program_bitstream/program_bitstream.py x3
# 3. Load software; this doesn't touch the bitstream
./fpga/load_software/load_software.py x3 hello_world
./fpga/load_software/load_software.py x3 coremark
./fpga/load_software/load_software.py x3 isa_test
# CoreMark-PRO: -v1 validates results, -v0 measures performance
./fpga/load_software/load_software.py x3 coremark_pro_core -v1
./fpga/load_software/load_software.py x3 coremark_pro_radix2 -v1The UART console runs at 115200 baud, 8N1; the VS Code extension has a built-in serial terminal. The FPGA guide covers target selection, debugging, and the hardware regression, and the Debian guide covers booting Linux.
FROST implements RV64GCB (G = IMAFD, Zicsr, and Zifencei). The table lists every supported extension and privilege mode.
| Extension | Description |
|---|---|
| RV64I | Base 64-bit integer instruction set |
| M | Integer multiply/divide |
| A | Atomic memory operations (LR/SC, AMO; word and doubleword) |
| F | Single-precision floating-point (32-bit) |
| D | Double-precision floating-point (64-bit) |
| C | Compressed instructions (16-bit encodings) |
| B | Bit manipulation (B = Zba + Zbb + Zbs) |
| Zicsr | CSR access instructions |
| Zicntr | Base counters (cycle, time, instret) |
| Zifencei | Instruction fence |
| Zicond | Conditional zero |
| Zbkb | Bit manipulation for crypto |
| Zbc | Carry-less multiplication (clmul, clmulh, clmulr) |
| Zbkc | Carry-less multiplication for crypto (clmul, clmulh) |
| Zihintpause | Pause hint for spin-wait loops |
| Machine Mode | M-mode privilege (mret, wfi, ecall, ebreak) |
| Supervisor Mode | S-mode privilege, trap delegation, Sv39 virtual memory, Sstc timers |
| Smaia, Ssaia | AIA CSRs and machine/supervisor IMSIC files with 63 identities |
| Svade | Software-managed accessed and dirty bits: an access that needs one set raises a page fault |
| User Mode | U-mode privilege and system calls |
- Tomasulo out-of-order execution with two-wide decode, rename, and commit, a 32-entry reorder buffer, and precise exceptions.
- Four reservation stations, two integer ALUs, a multiply and divide unit that also performs carry-less multiplication, and an iterative single- and double-precision floating-point unit. A load result can wake dependent integer and memory operations a cycle before the common data bus broadcasts it.
- Branch prediction with a 256-entry BTB, a bimodal and a tagged path-history direction predictor, and an 8-entry return stack. A mispredicted conditional branch redirects fetch and restores the rename tables the cycle after it resolves.
- Sv39 virtual memory with hardware page-table walks and separate instruction and data TLBs.
- Separate instruction and data paths into a cache hierarchy. On X3: 16 KiB L1I, 128 KiB L1D, and 2 MiB L2, all four-way, and a 256-entry L0 cache in the load queue. The L1D holds 32-byte sectors in I, S or M states, with eight read slots and up to eight misses in flight to the L2, seven of them for loads. The L2's coherence home orders the L1s, page-table walks and DMA by sector and has four fills. Low BRAM uses an 8 KiB instruction cache and L0 data reads with write-through stores. DMA is coherent with the data caches.
- 256 KiB of on-chip BRAM and 1 GiB of cached DDR4, with the same memory map in simulation and on hardware.
- UART, CLINT-compatible timer, an APLIC interrupt controller that delivers interrupts directly or as MSIs to the CPU's IMSIC files, a memory error unit, and 10GBASE-R Ethernet.
- JTAG debugging with halt, resume, and single-step through OpenOCD and GDB.
The design documentation below explains how each part works.
| Board | FPGA | Ethernet | Cache hierarchy → main memory |
|---|---|---|---|
| Alveo X3522PV | UltraScale+ (xcux35) | 10GBASE-R | 128 KiB L1D + 16 KiB L1I → 2 MiB URAM L2 → 1 GiB DDR4 |
| VCU118 Evaluation Board | Virtex UltraScale+ (xcvu9p) | 1 Gb/s RJ-45 and 10GBASE-R on QSFP1 lane 0 | 128 KiB L1D + 16 KiB L1I → 2 MiB URAM L2 → 2 GiB DDR4 |
See the board guide for pinouts, clocking, and adding a board.
Alveo X3522PV (Virtex UltraScale+ @ 322 MHz; post-route report)
| Resource | Used | Available | Util% |
|---|---|---|---|
| CLB LUTs | 164,531 | 1,029,600 | 16.0% |
| LUT as Logic | 145,078 | 1,029,600 | 14.1% |
| LUT as Distributed RAM | 18,718 | — | — |
| LUT as Shift Register | 735 | — | — |
| CLB Registers | 103,332 | 2,059,200 | 5.0% |
| Block RAM Tile | 263 | 2,112 | 12.4% |
| URAM | 68 | 352 | 19.3% |
| DSPs | 27 | 1,320 | 2.0% |
| CARRY8 | 1,997 | 128,700 | 1.6% |
| F7 Muxes | 1,970 | 514,800 | 0.4% |
| F8 Muxes | 930 | 257,400 | 0.4% |
| Bonded IOB | 132 | 364 | 36.3% |
| MMCM | 1 | 11 | 9.1% |
| PLL | 3 | 22 | 13.6% |
./scripts/frost.py check # CI's lint and fast Python test jobs
./scripts/frost.py pytest # the cocotb targets registered for pytest
./scripts/frost.py cocotb directed_traps # a single target
./scripts/frost.py formal # formal proofs
./scripts/frost.py synthesis # open-source synthesis checks (Yosys)
./asic/orfs.py run # OpenROAD flow from synthesis to GDSThe lint hooks in check can modify files, so review the diff afterwards.
Use ./scripts/frost.py lint for lint alone, or add --fail-fast to check
to stop at the first failing phase.
CI runs on pushes and pull requests to main. It runs the RISC-V
architecture tests and riscv-torture programs against Spike reference
results, the riscv-tests suites, TestRIG's instruction-by-instruction
comparison with the Sail RISC-V model, unit benches for the CPU and SoC
blocks, full programs from on-chip BRAM and from cached DDR, formal proofs,
synthesis checks, the OpenROAD flow, the Ethernet MAC/PCS benches, and QEMU
boots of the Linux images, and it merges the coverage of its simulations,
cover points included, into one report. The
test guide has the details and the commands
for each suite.
Simulation, FPGA loading, and bitstream builds compile applications automatically. To compile by hand:
./scripts/frost.py run make -C sw/apps/hello_world # one application
./scripts/frost.py run python3 sw/apps/build_all_apps.py # every standalone applicationFor native builds outside the container, initialize the submodules first with
git submodule update --init --recursive.
| Directory | Contents |
|---|---|
| hw/rtl/ | CPU, caches, peripherals, and reusable hardware blocks |
| sw/ | Bare-metal libraries, applications, and benchmarks |
| linux/ | Linux boot images, firmware, and NIC driver |
| fpga/ | FPGA build, programming, and software-loading tools |
| boards/ | Board wrappers and pin constraints |
| tests/ | Test runners |
| verif/ | Cocotb tests, reference models, and monitors |
| formal/ | Formal verification |
| perf-modeling/ | Cycle-approximate performance model of the CPU and SoC, with RTL event capture and a CoreMark IPC check |
| asic/ | OpenROAD flow on FreePDK45 and its OpenRAM SRAM macros |
| tools/vscode-frost/ | VS Code extension |
| docs/ | Debian setup and toolchain guides; diagrams |
| scripts/ | Docker wrapper and development tools |
| Document | Covers |
|---|---|
| RTL overview | SoC structure, memory map, and the data bus rules |
| CPU integration boundary | Standalone CPU AXI, PMA, reset, debug and coherent ingress contract |
| SoC wrapper | MMIO decode, peripherals, and the AXI4 DMA and AXI4-Lite register paths |
| CPU | Front end, branch prediction, address translation, and debug |
| Out-of-order back end | Renaming, scheduling, memory ordering, and commit, with a README for each block |
| Cache hierarchy | Caches, coherence, and the DMA port |
| NIC and MAC/PCS | 10 Gigabit Ethernet |
The Docker image pins the tools CI uses. Vivado is installed separately on the host, and the ASIC flow runs in OpenROAD-flow-scripts' own image, which asic/orfs.py pins. docs/tooling.md covers native toolchain setup and updating the image.
| Category | Tool | Version |
|---|---|---|
| Image | Ubuntu | 26.04 |
| Runtime | Python | 3.14.9 (native scripts support 3.12+) |
| Node.js / npm | 26.12.1 / 12.2.1 | |
| Compiler | Native GCC / G++ | 16.2.0 |
| Clang / clang-tidy / clang-format | 23.1.4 | |
| RISC-V GCC for bare metal, OpenSBI and Linux (Bootlin musl) | 16.2.0 (2026.08-1 bleeding-edge) | |
| pip / setuptools / wheel | 26.2.2 / 84.2.1 / 0.48.0 | |
| Build | CMake / Meson / Ninja | 4.4.4 / 1.12.1 / 1.13.2 |
| Buildroot / OpenSBI | 2026.08.1 / 1.9 | |
| Debian Linux kernel | 6.12.113-1 (6.12.113+deb13-riscv64) |
|
| Testbench | Cocotb / pytest / pytest-cov | 2.1.0 / 9.1.1 / 7.1.0 |
| Simulator | Verilator / QEMU | 5.052 / 11.1.2 |
| Spike | 02b1dc182164bb73b19b050676dd89f0834f8b2e |
|
| Sail RISC-V model / QuickCheckVEngine | 0.16 / 5e15965a819ca1be9f14d2e8e319e98fd89a557f |
|
| Synthesis | Yosys / sv2v | 0.70 / 0.0.13 |
| Formal | SymbiYosys / Z3 / Boolector | 0.70 / 5.3.2 / 3.2.4 |
| Debug | OpenOCD | 0.12.0 (Ubuntu package) |
| FPGA | Vivado (native, separately installed and validated) | 2025.2 |
| ASIC | OpenROAD-flow-scripts (its own image) | 26Q4 |
| Linting | pre-commit / Ruff / mypy | 4.7.0 / 0.17.2 / 2.4.0 |
| Verible | 0.0-4296-g0f262651 | |
| CLI | Click | 8.5.0 |
| Extension | TypeScript / vsce | 7.0.2 / 4.0.0 |
FROST supports one hart on the Alveo X3522PV and VCU118 evaluation boards. Both provide coherent Ethernet DMA and the JTAG/OpenSBI boot path for Debian with an NFS root. The VCU118 has RJ-45 and QSFP1 Ethernet interfaces and can start OpenSBI and an interactive U-Boot console from SPI flash. See the VCU118 guide for its boot paths and ROADMAP.md for project work.
CONTRIBUTORS.md lists contributors. FROST is licensed under the Apache License 2.0. The Linux drivers are dual-licensed under GPL-2.0-only or BSD-2-Clause. The U-Boot drivers use GPL-2.0-or-later, and third-party code in submodules keeps its own license.