Skip to content

Repository files navigation

RV32I Single-Cycle CPU

A fully functional single-cycle RISC-V processor implementing the RV32I base integer instruction set, written in Verilog. The design is structured as a clean controller-datapath split and has been simulated and verified against a comprehensive assembly test suite with zero errors.


Features

  • Complete RV32I instruction set coverage
  • Single-cycle execution — one instruction completes per clock cycle
  • Classic controller + datapath microarchitecture
  • Parameterised components (register file, memories, ALU, muxes, flip-flops)
  • Instruction and data memory included
  • Verified with ModelSim-Altera; simulation reports "No Errors"
  • Intel Quartus Prime project targeting the Cyclone IV E FPGA family

Supported Instructions

Type Instructions
I-type ALU ADDI, SLTI, SLTIU, XORI, ORI, ANDI, SLLI, SRLI, SRAI
R-type ADD, SUB, SLL, SLT, SLTU, XOR, SRL, SRA, OR, AND
Load LB, LH, LW, LBU, LHU
Store SB, SH, SW
Branch BEQ, BNE, BLT, BGE, BLTU, BGEU
Jump JAL, JALR
Upper Imm LUI, AUIPC

Repository Structure

riscv32I-single-cycle/
├── code/
│   ├── riscv_cpu.v          # Core CPU module (controller + datapath instantiation)
│   ├── t1c_riscv_cpu.v      # Top-level testbench wrapper (CPU + memories)
│   ├── instr_mem.v          # Instruction memory (ROM, 512×32-bit, hex-initialised)
│   ├── data_mem.v           # Data memory (RAM, 64×32-bit, synchronous write)
│   ├── rv32i_test.s         # Assembly test program (full RV32I coverage)
│   ├── rv32i_test.hex       # Assembled hex image for simulation
│   ├── rv32i_book.hex       # Alternate hex image (textbook examples)
│   └── components/
│       ├── controller.v     # Top-level controller
│       ├── main_decoder.v   # Opcode → control signals decoder
│       ├── alu_decoder.v    # ALUOp + funct3/funct7 → ALU control
│       ├── datapath.v       # Datapath (PC logic, register file, ALU, muxes)
│       ├── alu.v            # 32-bit ALU
│       ├── reg_file.v       # 32×32-bit register file (2R/1W)
│       ├── imm_extend.v     # Immediate sign/zero extender (I/S/B/U/J types)
│       ├── reset_ff.v       # Synchronous resettable D flip-flop (PC register)
│       ├── adder.v          # 32-bit adder (PC+4 and branch target)
│       ├── mux2.v           # Parameterised 2-to-1 mux
│       ├── mux3.v           # Parameterised 3-to-1 mux
│       └── mux4.v           # Parameterised 4-to-1 mux
├── simulation/
│   └── modelsim/            # ModelSim-Altera simulation files and waveforms
├── output_files/            # Quartus compilation reports
├── t1c_riscv_cpu.qpf        # Quartus project file
└── t1c_riscv_cpu.qsf        # Quartus settings file

Architecture

The processor follows a two-block microarchitecture:

         ┌──────────────────────────────────────────┐
         │                riscv_cpu                 │
         │                                          │
  Instr ─►  ┌─────────────┐     ┌──────────────┐    │
         │  │  Controller │────►│   Datapath   │    │
         │  │             │     │              │    │
         │  │ main_decoder│     │ PC / reg_file│    │
         │  │ alu_decoder │     │ ALU / muxes  │    │
         │  └─────────────┘     │ imm_extend   │    │
         │                      └──────────────┘    │
         └──────────────────────────────────────────┘

Controller

  • main_decoder decodes the 7-bit opcode (and funct3 for branches/loads) into control signals: RegWrite, ALUSrc, MemWrite, ResultSrc, Branch, Jump, ImmSrc, ALUOp.
  • alu_decoder maps ALUOp + funct3 + funct7[5] to the 4-bit ALUControl signal.
  • Branch resolution logic in controller.v handles all six branch conditions (BEQ/BNE/BLT/BGE/BLTU/BGEU) and drives PCSrc.

Datapath

  • PC register: resettable flip-flop; resets to 0x00000000.
  • PC adders: PC+4 and PC+ImmExt (branch target), selected by PCSrc.
  • Register file: 32×32-bit, two combinational read ports, one synchronous write port. x0 is hardwired to zero.
  • Immediate extender: supports I, S, B, U, and J encoding formats.
  • ALU: supports ADD, SUB, AND, OR, XOR, SLT, SLTU, SLL, SRL, SRA; drives Zero, less, and lessu flags.
  • Result mux (4-to-1): selects between ALU result, load data (with sign/zero extension), PC+4 (for JAL/JALR link), and upper-immediate result (for LUI/AUIPC).
  • Load byte/halfword sign- and zero-extension is handled combinationally based on funct3.

Memory Interface

The top-level module t1c_riscv_cpu.v wires the CPU core to separate instruction and data memories, with an external write port (Ext_MemWrite) that allows pre-loading data memory during reset for testbench use.


Simulation

Simulation is done with ModelSim-Altera via Intel Quartus Prime NativeLink.

The test program rv32i_test.s exercises every instruction class in sequence, with explicit expected values annotated in comments. The testbench checks results and writes "No Errors" to a result file on success.

To run simulation from within Quartus:

  1. Open t1c_riscv_cpu.qpf in Quartus Prime.
  2. Go to Tools → Run Simulation Tool → RTL Simulation.
  3. The ModelSim .do script in simulation/modelsim/ will run automatically.

Alternatively, from a ModelSim terminal:

cd simulation/modelsim
do t1c_riscv_cpu_run_msim_rtl_verilog.do

To switch between the two hex images, edit instr_mem.v:

// $readmemh("rv32i_book.hex", instr_ram);   // textbook examples
$readmemh("rv32i_test.hex", instr_ram);      // full RV32I test suite

Tools

Tool Version
Intel Quartus Prime Lite 20.1
ModelSim-Altera (bundled with Quartus 20.1)
Target FPGA family Cyclone IV E

About

This is the single cycle RiscV RV32I ISA following CPU unit written in verilog.

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages