RISC-V processor in RTL
A 32-bit RV32I processor in Verilog, built one stage at a time. Fetch, decode, the register file, and the ALU with branch logic are implemented and checked against golden traces in Verilator. It doesn't run programs end to end yet: write-back and PC updates on branches and jumps are next.
Fetch to ALU, in RTL.
Instruction memory
Byte-addressable, little-endian storage built from 8-bit elements. A 32-bit read assembles four bytes, and writes land on the rising clock edge. $readmemh loads the program as hex words and splits each word into four bytes. Capacity is configurable, 1 MiB by default in simulation.
Fetch
A 32-bit program counter resets synchronously to 0x01000000 and advances 4 bytes on every clock edge, streaming instruction words out of memory in order.
Decode
A combinational decoder extracts opcode, register, and function fields for all six RV32I formats (R, I, S, B, U, and J), covering the 37-instruction subset the core targets.
Immediate generation
Five immediate layouts, selected by opcode, reassembled from their scattered instruction bits, sign-extended, and padded to 32 bits.
Register file
32 registers of 32 bits with two combinational read ports and one write port on the rising clock edge. x0 ignores writes and always reads zero, and x2, the stack pointer, starts at the top of memory. Initialized in an initial block so it can map onto FPGA block RAM later.
ALU and branches
A fully combinational execute stage: arithmetic, logic, shifts, and signed and unsigned compares for register and immediate operands, load and store addresses, LUI and AUIPC, jump targets, and all six branch conditions with the branch target.
Five layouts, one 32-bit value.
RISC-V scatters immediate bits across the instruction so the register fields stay in fixed positions. The decoder reverses that: the opcode picks the layout, the bit slices are copied into place, bit 31 is sign-extended, and the low bits are zero-filled where the format requires it.
Each cell names the instruction bits it copies · all five share the sign at inst[31]
Checked against golden traces.
The register file passes the course's register file test.
Register reads, ALU results, and branch decisions match the golden traces in Verilator, alongside fetch and decode.
Instruction memory passed its tests, and the fetch trace matched a 400-line golden reference exactly.
Signal-level debugging in GTKWave waveforms, from the first memory tests onward.
21 probes across fetch, decode, the register file, and execute expose internal signals to the testbench.
The current build is reproducible from a single Git commit.
From fetch to FPGA.
Memory & fetch
Byte-addressable instruction memory and a 32-bit PC stepping through the program.
Decode & immediates
Field extraction for six formats and five immediate layouts, integrated with fetch.
Register file & ALU
Two-read, one-write register file and a combinational ALU that also resolves branches.
Write-back & control flow
Data memory, write-back to rd, and PC updates on taken branches and jumps, so the core runs all 37 instructions.
Five-stage pipeline
Pipeline registers, data forwarding, and hazard stalls to keep instructions moving correctly.
FPGA bring-up
Synthesize the pipelined core and bring it up on a PYNQ-Z1 board.
Write-back comes next.
With write-back and PC updates in place, the core runs real programs and this page gets its first full execution traces.