A 32-bit RISC-V RV32I CPU core implemented in Transaction-Level Verilog (TL-Verilog). This implementation supports the complete RV32I instruction set and demonstrates fundamental processor design concepts through a single-cycle architecture.
Here's a pre-built logic diagram of the final CPU.
This image provides a high-level visualization of the CPU as seen in simulation.
The architecture's block diagram breaks down all major functional units. Ctrl-click here to explore in it's own tab.
The processor implements a Harvard architecture with separate instruction and data memory interfaces, enabling concurrent instruction fetch and data access operations.
-
Open Makerchip IDE Visit: https://makerchip.com
-
Load design file Copy contents of RV32I_Code.tlv
-
Compile and simulate Click "Compile" → "Simulate" → View results in VIZ tab
| Component | Specification |
|---|---|
| ISA | RISC-V RV32I Base Integer |
| Architecture | 32-bit Harvard |
| Register File | 32 × 32-bit (x0 hardwired to 0) |
| Instruction Memory | Read-only, word-addressed |
| Data Memory | 32 words × 32 bits |
| Pipeline | Single-cycle execution |
| ALU Width | 32-bit |
The core supports all six RISC-V instruction formats with the following operations:
Arithmetic Instructions
ADD,ADDI,SUBLUI,AUIPC
Logical Instructions
AND,ANDI,OR,ORI,XOR,XORI
Shift Instructions
SLL,SLLI,SRL,SRLI,SRA,SRAI
Comparison Instructions
SLT,SLTI,SLTU,SLTIU
Branch Instructions
BEQ,BNE,BLT,BGE,BLTU,BGEU
Jump Instructions
JAL,JALR
Memory Instructions
LW,SW
$next_pc[31:0] = $reset ? 0 :
$taken_br ? $br_tgt_pc :
$is_jal ? $br_tgt_pc:
$is_jalr ? $jalr_tgt_pc :
($pc[31:0] + 4);
$pc[31:0] = >>1$next_pc;// Instruction type detection
$is_u_instr = $instr[6:2] ==? 5'b0x101;
$is_i_instr = $instr[6:2] ==? 5'b0000x ||
$instr[6:2] ==? 5'b001x0 ||
$instr[6:2] == 5'b11001;
$is_r_instr = $instr[6:2] == 5'b01011 ||
$instr[6:2] == 5'b01100 ||
$instr[6:2] == 5'b10100 ||
$instr[6:2] == 5'b01110;
$is_s_instr = $instr[6:2] ==? 5'b0100x;
$is_b_instr = $instr[6:2] == 5'b11000;
$is_j_instr = $instr[6:2] == 5'b11011;$imm[31:0] = $is_i_instr || $is_load ? { {20 {$instr[31]}}, $instr[31:20] } :
$is_s_instr ? { {20 {$instr[31]}}, $instr[31:25], $instr[11:7] } :
$is_b_instr ? { {19 {$instr[31]}}, $instr[31], $instr[7], $instr[30:25], $instr[11:8], 1'b0 } :
$is_u_instr ? { $instr[31:12], 12'b0 } :
$is_j_instr ? { {11 {$instr[31]}}, $instr[31], $instr[19:12], $instr[20], $instr[30:21], 1'b0 } :
32'b0;$result[31:0] = $is_addi || $is_load || $is_s_instr ? ($src1_value + $imm):
$is_add ? ($src1_value + $src2_value):
$is_andi ? ($src1_value & $imm):
$is_ori ? ($src1_value | $imm):
$is_xori ? ($src1_value ^ $imm):
$is_slli ? ($src1_value << $imm[5:0]):
$is_srli ? ($src1_value >> $imm[5:0]):
$is_and ? ($src1_value & $src2_value):
$is_or ? ($src1_value | $src2_value):
$is_xor ? ($src1_value ^ $src2_value):
$is_sub ? ($src1_value - $src2_value):
// ... [additional operations]
32'b0;$taken_br = $is_beq ? ($src1_value == $src2_value) :
$is_bne ? ($src1_value != $src2_value) :
$is_blt ? (($src1_value < $src2_value) ^ ($src1_value[31] != $src2_value[31])) :
$is_bge ? (($src1_value >= $src2_value) ^ ($src1_value[31] != $src2_value[31])) :
$is_bltu ? ($src1_value < $src2_value) :
$is_bgeu ? ($src1_value >= $src2_value) :
1'b0;The processor implements a 32×32-bit register file with dual read ports and single write port:
// Register file interface
$rf1_wr_en = $wr_en;
$rf1_wr_index[4:0] = $rd[4:0];
$rf1_wr_data[31:0] = $wr_data[31:0];
$rf1_rd_en1 = $rs1_valid;
$rf1_rd_index1[4:0] = $rs1[4:0];
$rf1_rd_en2 = $rs2_valid;
$rf1_rd_index2[4:0] = $rs2[4:0];Data memory supports word-aligned load and store operations:
// Data memory interface
$dmem1_wr_en = $is_s_instr;
$dmem1_addr[4:0] = $result[6:2];
$dmem1_wr_data[31:0] = $src2_value[31:0];
$dmem1_rd_en = $is_load;The core verification uses a comprehensive test program that exercises all implemented instructions and validates processor functionality.
Pass Condition:
$passed_cond = (/xreg[30]$value == 32'b1) &&
(! $reset && $next_pc[31:0] == $pc[31:0]);
passed = >>2$passed_cond;Fail Condition:
failed = *cyc_cnt > 70;
Test Outcomes:
- PASSED: Register x30 contains expected value (0x1)
- Program Counter: Stable at completion
- Register File: All test registers verified
- Memory Operations: Load/store functionality confirmed
- Instruction Execution: Complete RV32I instruction set tested
| Component | Coverage |
|---|---|
| Instructions Implemented | 31 unique instructions |
| Register File Validation | x1-x30 functional |
| Memory Operations | Load/store verified |
| Branch Instructions | All variants tested |
| ALU Operations | Complete arithmetic/logic coverage |
| Control Flow | Jump/branch target calculation verified |
- Navigate to Makerchip.com
- Create new TL-Verilog project
- Copy content from
RV32I_Code.tlv - Compile and simulate
- View results in VIZ tab
- Single-cycle execution for educational clarity and simplified debugging
- Harvard architecture eliminates structural hazards between instruction fetch and data access
- TL-Verilog implementation provides enhanced readability and debugging capabilities
| Metric | Value |
|---|---|
| Maximum Frequency | Synthesis-dependent |
| Instructions per Cycle | 1.0 (single-cycle) |
| Simulation Cycles | 70 maximum |
| Resource Usage | Implementation-dependent |
- Single-cycle implementation limits maximum operating frequency
- No pipeline hazard detection (not applicable to single-cycle)
- Basic memory interface without burst or cache support
- No interrupt or exception handling
- Limited to RV32I base instruction set
- 5-stage pipeline implementation with hazard detection
- Cache hierarchy integration
- RV32M extension (multiply/divide operations)
- Interrupt controller and exception handling
- AXI4 memory interface
- FPGA synthesis optimization
This implementation demonstrates:
- Computer architecture fundamentals
- Instruction set architecture implementation
- Digital design methodology
- Hardware description language proficiency
- Verification and validation techniques
- Fork the repository
- Create feature branch (
git checkout -b feature/enhancement) - Commit changes (
git commit -m 'Add enhancement') - Push to branch (
git push origin feature/enhancement) - Open Pull Request
- RISC-V ISA Specification v2.2
- TL-Verilog Language Reference
- Building a RISC-V CPU Core - Linux Foundation Course
- Makerchip Platform Documentation

