A fully synthesizable 64-bit RISC-V processor core implementing RV64I with the Zba address-generation extension, designed in SystemVerilog with a classic 5-stage pipeline and a strong focus on verification and correctness.
Built for the LFX Mentorship Coding Challenge Author: Muhammad Talha Ayyaz
- ✅ RV64I base integer ISA
- ✅ Zba extension (SHxADD, SHxADD.UW, ADD.UW)
- ✅ 5-stage in-order pipeline (IF/ID/EX/MEM/WB)
- ✅ Separate instruction & data memories
- ✅ Forwarding, stalling, and flushing logic
- ✅ Fully synthesizable SystemVerilog RTL
- ✅ Deep, layered verification (unit → ISA → C programs)
- Arithmetic & logic operations (including word variants)
- Control flow: branches, jumps, AUIPC, LUI
- Loads/stores: byte → doubleword
- Standard RISC-V instruction formats (R/I/S/B/U/J)
Supported instructions:
SH1ADD,SH2ADD,SH3ADDSH1ADD.UW,SH2ADD.UW,SH3ADD.UWADD.UW
All Zba instructions execute in the EX stage, reusing the main ALU datapath.
| Stage | Responsibility |
|---|---|
| IF | PC update & instruction fetch |
| ID | Decode, register read, immediate generation |
| EX | ALU ops, branches, Zba execution |
| MEM | Data memory access |
| WB | Writeback to register file |
- Branch/jump resolution: EX stage
- No speculation or prediction (simple & correct by design)
-
Single shared ALU for RV64I + Zba
-
Operand sources:
- register–register
- register–immediate
- PC-relative
-
Writeback sources:
- ALU result
- Load data
- PC+4
- Immediate (LUI)
Data Hazards
- EX/MEM → EX forwarding
- MEM/WB → EX forwarding
Load-Use Hazard
- One-cycle stall
- Bubble insertion in EX
Control Hazards
- IF/ID flush on taken branch or jump
rtl/
├── rv_top.sv # Top-level pipeline integration
├── alu.sv # ALU + Zba logic
├── reg_file.sv # 32×64 register file
├── control_unit.sv # Instruction decode & control
├── imm_gen.sv # Immediate generator
├── hazard_unit.sv # Stall / flush logic
├── forwarding_unit.sv # Data forwarding
├── instr_mem.sv # Instruction memory
└── data_mem.sv # Data memory
All RTL is synthesizable, modular, and written with a strict RTL mindset.
Verification is performed bottom-up, increasing confidence at every level.
Each major RTL block is tested in isolation using self-checking SystemVerilog testbenches:
- ALU (including all Zba ops)
- Register file
- Immediate generator
- Control logic
- Pipeline registers
- Hazard & forwarding units
✔ Fast debug ✔ Deterministic pass/fail ✔ Assertions for corner cases
-
Hand-written RISC-V assembly programs
-
Covers:
- arithmetic
- branches
- memory access
- Zba instructions
-
Flow:
- ASM → object → ELF
- ELF → memory image
- Run on full top-level core
Tests are self-checking and validate architectural state.
Realistic programs compiled and executed on the processor:
Examples:
-
Factorial
- iterative
- recursive
-
Fibonacci
- iterative
- recursive
These stress:
- pipeline hazards
- branches & jumps
- stack behavior
- load/store correctness
Pass/fail is reported via memory-mapped testbench monitors.
- Toolchain:
riscv64-unknown-elf-gcc - ISA target:
rv64i_zba - ABI:
lp64 - Bare-metal, freestanding environment
All compilation and image-generation steps are documented in:
software/build_commands.txt
A detailed Makefile guide is provided here:
docs/manual/make.md
It explains:
- build targets
- simulation workflow
- regression testing
- debugging tips
This keeps the project reproducible and user-friendly.
- Tool: Xilinx Vivado 2019.2
- Target: Nexys A7 (Artix-7 xc7a100t)
- Clock constraint: 100 MHz
- ✔ Successful synthesis
- ✔ No timing violations
- ⏱ Max combinational delay ≈ 11.7 ns
- ⚡ Safe frequency ≈ 85 MHz
This core is intentionally:
- Simple rather than speculative
- Correct rather than over-optimized
- Readable rather than clever
Advanced features (caches, interrupts, CSRs, virtual memory, privileged modes) are intentionally out of scope.
This project delivers a clean, well-verified RV64I + Zba processor core with a strong emphasis on architectural correctness and verification depth.
It serves as a solid foundation for:
- further ISA extensions
- architectural exploration
- educational use