— here’s a clear, no-BS PicoRV32 tutorial to get you from “what is this” → “I can run it on FPGA / simulate it”.
🧠 PicoRV32 Tutorial (Practical + Beginner-Friendly)
🔗 0. Get the code
👉 Official repo:
https://github.com/YosysHQ/picorv32
Clone it:
git clone https://github.com/YosysHQ/picorv32.git
cd picorv32
🧩 1. What PicoRV32 actually is
👉 A tiny RISC-V CPU core in Verilog
- File to focus on:
picorv32.v
👉 It is:
- multi-cycle CPU
- FSM-controlled
- not pipelined
- not “textbook style”
🏗️ 2. Minimal System Architecture
PicoRV32 alone is just a CPU — you need to wrap it:
+-------------+
| PicoRV32 |
+-------------+
| memory interface
v
+-------------+
| Memory |
+-------------+
|
+-------------+
| Program |
+-------------+
👉 Key idea:
CPU talks to memory via a simple interface (no AXI by default)
🔌 3. Understanding the Memory Interface (CRITICAL)
This is THE most important part.
Signals:
output mem_valid
output mem_instr
input mem_ready
output [31:0] mem_addr
output [31:0] mem_wdata
output [3:0] mem_wstrb
input [31:0] mem_rdata
🧠 What it means:
| Signal | Meaning |
|---|---|
mem_valid |
CPU requests memory access |
mem_ready |
Memory responds |
mem_addr |
Address |
mem_wdata |
Data to write |
mem_rdata |
Data read |
mem_wstrb |
Write enable (byte mask) |
🔁 Handshake logic:
👉 CPU says:
“I want data” →
mem_valid = 1
👉 Memory replies:
“Here you go” →
mem_ready = 1
⚙️ 4. Minimal Working Example (Simulation)
Here’s a super simple memory module:
reg [31:0] memory [0:1023];
always @(posedge clk) begin
mem_ready <= 0;
if (mem_valid && !mem_ready) begin
mem_ready <= 1;
if (mem_wstrb != 0) begin
memory[mem_addr >> 2] <= mem_wdata;
end else begin
mem_rdata <= memory[mem_addr >> 2];
end
end
end
👉 This is enough to run PicoRV32.
🧪 5. Run the built-in test
Inside repo:
make test
👉 This runs:
- simulation
- test programs
- verifies CPU works
🧠 6. How PicoRV32 Executes Instructions
Unlike your diagram (single-cycle):
👉 PicoRV32 does:
FETCH → DECODE → EXECUTE → MEMORY → WRITEBACK
But:
- one stage at a time
- controlled by FSM
⚡ 7. Key Parameters (very useful)
Inside picorv32.v:
parameter ENABLE_MUL = 1;
parameter ENABLE_DIV = 1;
parameter ENABLE_IRQ = 1;
👉 You can:
- disable features → save area
- enable features → more capability
🔧 8. Optional Interfaces
PCPI (co-processor interface)
👉 For custom instructions (AI / crypto etc.)
IRQ
👉 Interrupt support
🚀 9. Run on FPGA (high level)
Steps:
- Add:
- PicoRV32
- RAM
- clock/reset
- Load program:
- compiled
.hexor.bin
- compiled
- Connect:
- memory interface
🧠 10. Mental Model (SUPER IMPORTANT)
👉 Think of PicoRV32 as:
A state machine that walks through instructions step by step
NOT:
- ❌ parallel datapath
- ❌ one-cycle execution
🔥 Common Beginner Mistakes
❌ Treating it like textbook CPU
❌ Ignoring mem_valid / mem_ready
❌ Expecting pipeline behavior
❌ Not aligning memory (addr >> 2)