A 3-stage pipelined RISC-V processor implementing the RV32I base instruction set, written in Verilog.
Stage 1 Stage 2 Stage 3
(Fetch) (Decode/Exec) (Writeback)
┌─────────┐ ┌──────────┐ ┌─────────┐
│ PC_REG │ │ ID │ │ REGS │
│ │ │ (Decode)│ │ (Write) │
│ I FETCH │────▶│ EX │─────▶│ │
│ (Fetch) │ │ (ALU) │ └─────────┘
│ ROM │ │ Branch │
└─────────┘ │ LSU │
▲ └──────────┘
│ │
┌────┴────┐ ┌─────┴──────┐
│ IF/ID │ │ ID/EX │
│ Pipeline│ │ Pipeline │
│ Reg │ │ Reg │
└─────────┘ └────────────┘
Two pipeline registers (IF/ID and ID/EX) forward control and data signals between stages.
| Module | Stage | Description |
|---|---|---|
pc_reg |
Stage 1 | Program counter, holds current instruction address |
if_id |
Boundary | Stage 1→2 pipeline register |
ifetch |
Stage 1 | Fetches instruction from ROM |
id |
Stage 2 | Instruction decode, immediate extension, register read |
id_ex |
Boundary | Stage 2→3 pipeline register |
ex |
Stage 2 | ALU operations, branch condition evaluation, forwarding |
regs |
Stage 3 | Register file (32×32), writeback |
ctrl |
Global | Control signal generation: RegWrite, MemWrite, ALU op-select |
ram |
Global | Data memory (based on simple_dual_ram) |
rom |
Global | Instruction memory (read-only) |
riscv_top |
— | CPU top-level, integrates all pipeline stages |
open_risc_v_soc |
— | SoC wrapper, instantiates CPU + ROM + RAM |
- Data hazards: Forwarding from EX and REGS stages back to ALU inputs
- Control hazards: Branch resolved in EX stage; no stall on not-taken; flush IF/ID on taken
Two independent simulation environments are provided.
Best for rapid verification and command-line automation.
Prerequisites: Icarus Verilog (iverilog + vvp), Python 3
cd sim
# Directly specify a .bin file
python compile_and_sim.py generated/rv32ui-p-addi.bin
# Or search by instruction name
python test_one_inst.py addiFlow: python script → bin_to_mem conversion → iverilog compile (RTL + tb.v) → vvp simulation → [PASS]/[FAIL] verdict
cd sim && python test_all.pyExpected output:
add PASS
addi PASS
...
mul FAIL (not implemented)
...
38 / 47 passed, 9 failed
The 9 failures are M-extension (multiply/divide) and fence_i, not yet implemented.
Use GTKWave to inspect signal timing. Uncomment the $dumpfile/$dumpvars block in tb/tb.v (lines 31-37), then:
cd sim && python compile_and_sim.py generated/rv32ui-p-addi.bin
gtkwave tb.vcdBest for comprehensive regression testing. Runs all 47 tests in a single simulation with PASS/FAIL/SKIP classification.
- Open ModelSim, set working directory to
tb/ - Compile
tb_all.vand all RTL source files - Run simulation and observe the Transcript window
Sample output:
========================================
Phase2+ RISC-V Pipeline Test
Total: 47 test cases
========================================
[PASS] addi (xxx cycles)
[PASS] add (xxx cycles)
...
[SKIP] mul (timeout, unsupported)
...
========================================
PASS : 38 / 47
FAIL : 0
SKIP : 9 (M-type/FENCE)
========================================
ALL SUPPORTED TESTS PASSED!
Tests follow the riscv-tests compliance convention:
- x26 (s10): Non-zero signals test completion
- x27 (s11): 1 = PASS, 0 = FAIL
- x3 (gp): Sub-test number (for debugging)
- 38/47 riscv-tests passing (all RV32I base instructions)
- Not yet implemented: M-extension, CSR, exception handling
- Still under active development