FPGA RISC-V Open-sourced in SystemVerilog by TwoSigma
A 6-stage pipelined RISC-V processor implementing RV32IMACB with full machine-mode privilege support for RTOS operation. Achieves 322 MHz on UltraScale+. Designed for FPGA deployment with clean, portable SystemVerilog.
There are many RISC-V cores. Here's what makes FROST different:
- Fully open-source toolchain — works with Verilator, Icarus Verilog, and Yosys. No vendor lock-in or expensive commercial tools required.
- Clean, readable SystemVerilog — not generated from Chisel or SpinalHDL. Every module is hand-written with extensive documentation, suitable for teaching, learning, and extending.
- Practical performance — 1.62 CoreMark/MHz (523 CoreMark at 322 MHz on UltraScale+) with branch prediction, L0 cache, and full data forwarding.
- Layered verification — constrained-random tests, directed tests, and real C programs all run in Cocotb simulation with pass/fail markers. Bugs that slip past one layer get caught by another. More accessible than SystemVerilog/UVM.
- Real workloads included — FreeRTOS demo, CoreMark benchmark, and ISA compliance suite all run in simulation and on hardware.
- No vendor primitives — pure portable RTL that works on any target. Synthesis tested via Yosys for generic (ASIC), Xilinx 7-series, UltraScale, and UltraScale+. Board wrappers provided for Artix-7, Kintex-7, and UltraScale+.
- Apache 2.0 licensed — permissive license suitable for commercial and academic use.
┌───────────────────────────────────────────────────────────────────────────┐
│ FROST RISC-V CPU │
├───────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 6-Stage Pipeline │ │
│ │ ┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │ │
│ │ │ IF │──>│ PD │──>│ ID │──>│ EX │──>│ MA │──>│ WB │ │ │
│ │ └────┘ └────┘ └────┘ └────┘ └────┘ └────┘ │ │
│ │ │ │ │ │ │ │
│ │ │ C-extension ┌──────┴────────┴──────┐ │ │
│ │ │ decompression │ Forwarding Unit │ │ │
│ │ │ └──────────────────────┘ │ │
│ │ v │ │
│ │ ┌──────────────┐ ┌─────────────┐ ┌──────────────────────┐ │ │
│ │ │ L0 Cache │ │ Regfile │ │ Trap Unit │ │ │
│ │ │ (load-use │ │ (32x32) │ │ (M-mode interrupts │ │ │
│ │ │ bypass) │ │ │ │ and exceptions) │ │ │
│ │ └──────────────┘ └─────────────┘ └──────────────────────┘ │ │
│ │ │ │
│ │ ┌──────────────┐ │ │
│ │ │ BTB │ (32-entry 2-bit saturating counter predictor) │ │
│ │ └──────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Peripherals │ │
│ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌──────────────┐ │ │
│ │ │ UART │ │ mtime/ │ │ FIFO0 │ │ FIFO1 │ │ │
│ │ │ (TX/RX) │ │ mtimecmp │ │ │ │ │ │ │
│ │ └────────────┘ └────────────┘ └────────────┘ └──────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└───────────────────────────────────────────────────────────────────────────┘
ISA: RV32IMACB plus additional extensions — 140+ instructions
| Extension | Description |
|---|---|
| RV32I | Base integer instruction set (37 instructions) |
| M | Integer multiply/divide |
| A | Atomic memory operations (LR/SC, AMO) |
| B | Bit manipulation (B = Zba + Zbb + Zbs) |
| C | Compressed instructions (16-bit encodings) |
| Zicsr | CSR access instructions |
| Zicntr | Base counters (cycle, time, instret) |
| Zifencei | Instruction fence |
| Zicond | Conditional zero |
| Zbkb | Bit manipulation for crypto |
| Zihintpause | Pause hint for spin-wait loops |
| Machine Mode | M-mode privilege (mret, wfi, ecall, ebreak) |
- 6-stage pipeline with full data forwarding (IF → PD → ID → EX → MA → WB)
- Branch prediction with 32-entry 2-bit saturating counter BTB (0-cycle penalty for correct predictions)
- L0 cache reduces load-use stalls (direct-mapped, write-through)
- M-mode trap handling for RTOS support (interrupts and exceptions)
- CLINT-compatible timer (mtime/mtimecmp) for preemptive scheduling
- Harvard architecture with separate instruction and data memory ports
- Portable design — pure generic RTL with no vendor-specific primitives, suitable for any FPGA or ASIC target
Validated with these tool versions:
| Category | Tool | Version |
|---|---|---|
| Compiler | RISC-V GCC | 15.2.0 |
| Testbench | Cocotb | 2.0.1 |
| Simulator | Verilator | 5.044 |
| Icarus Verilog | 12.0 | |
| Questa (optional) | 2023.1 | |
| Synthesis | Yosys | 0.60 |
| FPGA | Vivado (optional) | 2025.2 |
| Linting | pre-commit | 4.0 |
| clang-format | 19.0 | |
| clang-tidy | 19.0 | |
| Verible | 0.0-4051 |
A Docker image is provided with all tools pre-installed for reproducible development:
# Build the Docker image
docker build -t frost .
# Run interactively (mounts current directory to /workspace)
docker run -it --rm -v $(pwd):/workspace frost
# Inside container, run tests
pytest tests/
./tests/test_run_cocotb.py hello_worldThe Docker image includes:
- Verilator 5.044 (built from source)
- Icarus Verilog 12.0
- Yosys 0.60 (built from source)
- RISC-V GCC toolchain
- Cocotb and Python dependencies
- Pre-commit with all linters (clang-format, clang-tidy, Verible, ruff, mypy)
Pre-commit hooks run automatically on git commit to check code quality:
# Install hooks (one-time setup, or use Docker)
pre-commit install
# Run all hooks manually
pre-commit run --all-filesGet FROST running in simulation in one command:
# Run Hello World simulation (compiles automatically)
./tests/test_run_cocotb.py hello_worldYou should see "Hello, world!" in the output.
./tests/test_run_cocotb.py cpuThis runs constrained-random instructions through the CPU, verifying each against a software reference model.
frost/
├── README.md # This file
├── hw/ # Hardware (RTL)
│ ├── rtl/ # Synthesizable RTL source
│ │ ├── frost.sv # Top-level module
│ │ ├── frost.f # File list for synthesis/simulation
│ │ ├── cpu_and_mem/ # CPU core and memory subsystem
│ │ ├── lib/ # Generic FPGA library (RAM, FIFO)
│ │ └── peripherals/ # UART, etc.
│ └── sim/ # Simulation-only files (testbenches)
├── sw/ # Software
│ ├── common/ # Build infrastructure (linker, startup)
│ ├── lib/ # Libraries (uart, string, timer, etc.)
│ └── apps/ # Applications
│ ├── hello_world/ # Simple test program
│ ├── isa_test/ # ISA compliance suite
│ ├── coremark/ # CPU benchmark
│ ├── freertos_demo/ # FreeRTOS RTOS demo
│ └── ... # Other applications
├── verif/ # Verification infrastructure
│ ├── cocotb_tests/ # Cocotb test cases
│ ├── models/ # Software reference models
│ ├── encoders/ # Instruction encoding
│ └── monitors/ # Runtime verification
├── tests/ # Test runners (pytest integration)
├── scripts/ # Helper scripts (clang-tidy wrapper, etc.)
├── fpga/ # FPGA build and programming scripts
│ ├── build/ # Vivado synthesis scripts
│ ├── program_bitstream/ # FPGA programming
│ └── load_software/ # Software loading via JTAG
└── boards/ # Board-specific wrappers
├── x3/ # Alveo X3522PV
├── genesys2/ # Digilent Genesys2
└── nexys_a7/ # Digilent Nexys A7
Applications are compiled automatically when running simulations, loading to FPGA, or building bitstreams. Manual compilation is optional:
# Compile a specific application
make -C sw/apps/hello_world
# Compile all applications
./sw/apps/build_all_apps.py
# Initialize submodules first for coremark and freertos_demo
git submodule update --init# Using pytest (recommended)
pytest tests/ # Run all tests
pytest tests/ -s # With live output
pytest tests/ --sim=verilator # Use Verilator
# Standalone test runner
./tests/test_run_cocotb.py cpu # CPU verification
./tests/test_run_cocotb.py hello_world # Hello World program
./tests/test_run_cocotb.py isa_test # ISA compliance
./tests/test_run_cocotb.py coremark # CoreMark benchmark
./tests/test_run_cocotb.py freertos_demo # FreeRTOS demo
# With specific simulator
./tests/test_run_cocotb.py cpu --sim=verilator
./tests/test_run_cocotb.py cpu --sim=questa --gui# Open-source synthesis (Yosys)
./tests/test_run_yosys.py
# FPGA synthesis (Vivado)
./fpga/build/build.py x3 # Alveo X3
./fpga/build/build.py genesys2 # Genesys2
./fpga/build/build.py nexys_a7 # Nexys A7Running pytest tests/ exercises:
- CPU verification — constrained-random instruction sequences validated against Python reference models
- Directed tests — atomic operations (LR/SC), trap handling, compressed instructions
- C program simulation — all sample applications (hello_world, coremark, freertos_demo, etc.) run in simulation with pass/fail detection
- C compilation — all applications compile successfully with the RISC-V toolchain
- Yosys synthesis — RTL synthesizes cleanly for generic (ASIC), Xilinx 7-series, UltraScale, and UltraScale+ targets
# 1. Build bitstream (~15-30 min)
./fpga/build/build.py x3
# 2. Program FPGA
./fpga/program_bitstream/program_bitstream.py x3
# 3. Load software (fast - no re-synthesis)
./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| Board | FPGA | CPU Clock |
|---|---|---|
| Alveo X3522PV | UltraScale+ (xcux35) | 322 MHz |
| Digilent Genesys2 | Kintex-7 (xc7k325t) | 133 MHz |
| Digilent Nexys A7 | Artix-7 (xc7a100t) | 80 MHz |
- Add debugger support
- Superscalar execution
- Out-of-order execution
- F extension — single-precision floating-point
- D extension — double-precision floating-point
| Term | Definition |
|---|---|
| RV32I | RISC-V 32-bit base integer instruction set |
| M extension | Multiply/divide instructions |
| A extension | Atomic memory operations (LR/SC, AMO) |
| B extension | Bit manipulation (Zba + Zbb + Zbs) |
| C extension | Compressed 16-bit instructions |
| IF | Instruction Fetch stage |
| PD | Pre-Decode stage (C extension decompression) |
| ID | Instruction Decode stage |
| EX | Execute stage |
| MA | Memory Access stage |
| WB | Write Back stage |
| L0 Cache | Level-0 cache for load-use bypass |
| BTB | Branch Target Buffer (32-entry branch predictor) |
| MMIO | Memory-Mapped I/O |
| CLINT | Core Local Interruptor (timer/software interrupts) |
| Cocotb | Python-based verification framework |