A fully functional 5-stage pipelined RISC processor implementation in VHDL, featuring advanced pipeline hazard handling, branch prediction, and comprehensive instruction set support.
This project implements a 32-bit pipelined RISC processor with a Harvard architecture. The processor features a complete 5-stage pipeline (Fetch, Decode, Execute, Memory, Write-back) with sophisticated hazard detection and forwarding mechanisms to maximize throughput while maintaining correctness.
-
5-Stage Pipeline Architecture
- Instruction Fetch (IF)
- Instruction Decode (ID)
- Execute (EX)
- Memory Access (MEM)
- Write-back (WB)
-
Advanced Pipeline Control
- Data hazard detection and forwarding
- Control hazard handling
- Pipeline stalling and flushing mechanisms
- Branch prediction support
-
Comprehensive Instruction Set
- Two-operand instructions (ADD, SUB, AND, OR, etc.)
- One-operand instructions (INC, DEC, NOT, NEG, etc.)
- Memory operations (LOAD, STORE, PUSH, POP)
- Branch and jump instructions (JZ, JN, JC, JMP, CALL, RET)
- Special instructions (NOP, SWAP, IN, OUT)
- Interrupt handling (INT, RTI)
-
Hardware Features
- 8 general-purpose 32-bit registers (R0-R7)
- Stack pointer (SP) management
- Condition Code Register (CCR) with Zero, Negative, and Carry flags
- External interrupt support
- I/O port interface (IN/OUT instructions)
-
Memory System
- 1 MB addressable memory space
- Separate instruction and data memory interfaces
- Hardware interrupt vector support
pipelined-risc-processor/
├── docs/ # Documentation and diagrams
├── src/
│ ├── assembler/ # Assembly language toolchain
│ │ └── assembler.py # Assembler for converting assembly to machine code
│ └── rtl/ # VHDL source files
│ ├── stages/ # Pipeline stage implementations
│ │ ├── 1-fetch/ # Fetch stage
│ │ ├── 2-decode/ # Decode stage
│ │ ├── 3-execute/ # Execute stage
│ │ ├── 4-memory/ # Memory stage
│ │ └── 5-writeback/ # Write-back stage
│ ├── processor.vhd # Top-level processor integration
│ └── ... # Supporting components
├── testcases/ # Assembly test programs
│ ├── Branch.asm # Branch instruction tests
│ ├── BranchPrediction.asm # Branch prediction tests
│ ├── Memory.asm # Memory operation tests
│ ├── OneOperand.asm # One-operand instruction tests
│ └── TwoOperand.asm # Two-operand instruction tests
└── build/ # Build artifacts and simulation files
- ModelSim, Vivado, or any VHDL-compatible simulator
- Python 3.x (for the assembler)
-
Assemble Test Programs
python src/assembler/assembler.py testcases/TwoOperand.asm
-
Simulate in ModelSim/Vivado
- Open your VHDL simulator
- Add all VHDL files from
src/rtl/to your project - Set
processor.vhdas the top-level entity - Load the assembled machine code into memory
- Run the simulation
-
Run Test Cases
- Each test case in
testcases/validates specific processor functionality - Monitor register values and memory contents during simulation
- Verify CCR flags and pipeline behavior
- Each test case in
- Fetch Stage: Retrieves instructions from memory using the Program Counter (PC)
- Decode Stage: Decodes instructions, reads register file, and handles hazard detection
- Execute Stage: Performs ALU operations and calculates branch targets
- Memory Stage: Handles memory reads/writes and stack operations
- Write-back Stage: Writes results back to the register file
- Data Hazards: Resolved through forwarding paths and pipeline stalling
- Control Hazards: Managed with branch prediction and pipeline flushing
- Structural Hazards: Eliminated through separate instruction and data memory
The processor supports external hardware interrupts with the following mechanism:
- Interrupt signal (
int) triggers interrupt handling - Current PC and CCR are saved to the stack
- PC is loaded from interrupt vector (memory location M[1])
RTIinstruction restores PC and CCR from the stack
The testcases/ directory contains comprehensive assembly programs to validate processor functionality:
- TwoOperand.asm: Tests arithmetic and logical operations (ADD, SUB, AND, OR, etc.)
- OneOperand.asm: Tests unary operations (INC, DEC, NOT, NEG, etc.)
- Memory.asm: Tests LOAD, STORE, PUSH, and POP instructions
- Branch.asm: Tests conditional and unconditional branch instructions
- BranchPrediction.asm: Validates branch prediction mechanisms
- Data Width: 32 bits
- Address Width: 32 bits (1 MB addressable space)
- Register File: 8 × 32-bit general-purpose registers
- Pipeline Depth: 5 stages
- Instruction Format: Variable (1-word and 2-word instructions)
- Clock: Single-phase synchronous design
Abdallah Farag |
Youssef Wafa |
Loay Ahmed |
Tasneem Mohammed |