Skip to content

Repository files navigation

VHDL Pipeline 32-bit ModelSim

🚀 PipeLord

A 32-bit 5-Stage Pipelined Processor in VHDL
Complete with Hazard Detection, Data Forwarding, Interrupts, and a Custom Assembler


📖 Overview

PipeLord is a fully-functional 32-bit pipelined RISC processor implemented in VHDL. It features a classic 5-stage pipeline architecture with comprehensive hazard handling, interrupt support, and a Python-based assembler for program development.

✨ Key Features

Feature Description
5-Stage Pipeline IF → ID → EX → MEM → WB stages for maximum throughput
Von Neumann Architecture Unified memory with split-cycle access for instruction fetch and data operations
8 General-Purpose Registers R0–R7, each 32-bits wide
32-bit Immediate Support Two-word instructions with full 32-bit immediate values
Data Forwarding EX→EX and MEM→EX forwarding to minimize stalls
Hazard Detection Automatic stalling for load-use hazards
Hardware & Software Interrupts INT instruction + external interrupt line with shadow flag register
Stack Operations Hardware stack pointer with PUSH/POP support (initialized at 0x3FFFF, the highest address in the 18-bit 256K-word space, and growing downward)
Custom Assembler Python tool to convert assembly to machine code

🏗️ Architecture

PipeLord Architecture Diagram

Pipeline Stages

┌─────────┐   ┌─────────┐   ┌─────────┐   ┌─────────┐   ┌─────────┐
│  FETCH  │──▶│ DECODE  │──▶│ EXECUTE │──▶│ MEMORY  │──▶│WRITEBACK│
│  (IF)   │   │  (ID)   │   │  (EX)   │   │  (MEM)  │   │  (WB)   │
└─────────┘   └─────────┘   └─────────┘   └─────────┘   └─────────┘
     │             │             │             │             │
   IF/ID         ID/EX        EX/MEM       MEM/WB         RegFile
   Reg           Reg           Reg          Reg           Write
Stage Key Components Responsibilities
Fetch (IF) PC Register, HLT Module Fetches instruction from memory, manages PC (halt, jump, interrupt)
Decode (ID) Control Unit, Register File Decodes opcode, reads registers, generates all control signals
Execute (EX) ALU, ALU Controller, Muxes Performs arithmetic/logic operations, branch evaluation, address calculation
Memory (MEM) Memory Interface, SP Module Accesses data memory for LDD/STD/PUSH/POP, manages stack pointer
Writeback (WB) Writeback Mux, Swap FSM Writes results back to register file, handles 2-cycle SWAP instruction

Pipeline Registers

Each pipeline register can be stalled (hold value) or flushed (insert NOP bubble) for hazard handling:

Register Width Key Fields
IF_ID_Reg ~64b Instruction, PC+1
ID_EX_Reg ~180b Operands, control signals, immediate, register addresses
EX_MEM_Reg ~120b ALU result, write data, control signals
MEM_WB_Reg ~80b Memory data, ALU result, destination register

🎯 Instruction Set Architecture (ISA)

PipeLord uses a custom 32-bit instruction format with 5-bit opcode. Instructions requiring immediate values or offsets use two consecutive 32-bit words.

Instruction Formats

Single-Word Instructions:

┌───────────┬───────┬───────┬───────┬────────────────────────┐
│  Opcode   │  Rd   │  Rs1  │  Rs2  │       (unused)         │
│  [31:27]  │[26:24]│[23:21]│[20:18]│        [17:0]          │
└───────────┴───────┴───────┴───────┴────────────────────────┘

Two-Word Instructions (with 32-bit Immediate):

Word 1:
┌───────────┬───────┬───────┬───────┬────────────────────────┐
│  Opcode   │  Rd   │  Rs1  │  Rs2  │       (unused)         │
└───────────┴───────┴───────┴───────┴────────────────────────┘

Word 2:
┌────────────────────────────────────────────────────────────┐
│               32-bit Immediate / Offset                    │
└────────────────────────────────────────────────────────────┘

Complete Instruction Table

Data Transfer Instructions

Mnemonic Opcode Format Description
MOV Rd, Rs 01011 R-Type Copy Rs → Rd
LDM Rd, Imm 01110 I-Type (2-word) Load 32-bit immediate → Rd
LDD Rd, Off(Rs) 01111 I-Type (2-word) Load M[Rs + Offset] → Rd
STD Rs, Off(Rb) 10000 I-Type (2-word) Store Rs → M[Rb + Offset]
IN Rd 00110 Special Read input port → Rd
OUT Rs 00101 Special Write Rs → output port
PUSH Rs 01100 Stack Push Rs to stack (SP decrements)
POP Rd 01101 Stack Pop from stack → Rd (SP increments)

Arithmetic & Logic Instructions

Mnemonic Opcode Format Description Flags
ADD Rd, Rs1, Rs2 01000 R-Type Rd = Rs1 + Rs2 Z, N, C
SUB Rd, Rs1, Rs2 01001 R-Type Rd = Rs1 - Rs2 Z, N, C
AND Rd, Rs1, Rs2 01010 R-Type Rd = Rs1 AND Rs2 Z, N
NOT Rd 00011 R-Type Rd = NOT Rd Z, N
INC Rd 00100 R-Type Rd = Rd + 1 Z, N, C
IADD Rd, Rs, Imm 11001 I-Type (2-word) Rd = Rs + Immediate Z, N, C
SETC 00010 Special Set Carry Flag = 1 C
SWAP R1, R2 00111 R-Type Exchange R1 ↔ R2

Control Flow Instructions

Mnemonic Opcode Format Description
JMP Addr 10100 J-Type (2-word) Unconditional jump
JZ Addr 10001 J-Type (2-word) Jump if Zero flag = 1
JN Addr 10010 J-Type (2-word) Jump if Negative flag = 1
JC Addr 10011 J-Type (2-word) Jump if Carry flag = 1
CALL Addr 10101 J-Type (2-word) Call subroutine (push address of next instruction)
RET 10110 Special Return from subroutine (pop PC)
NOP 00000 Special No operation
HLT 00001 Special Halt processor

Interrupt Instructions

Mnemonic Opcode Format Description
INT Index 11000 Special Software interrupt (push PC+1, save flags)
RTI 10111 Special Return from interrupt (pop PC, restore flags)

⚠️ Hazard Handling

Data Hazards

PipeLord implements full data forwarding to minimize pipeline stalls:

Hazard Type Solution Implementation
EX→EX Forward from EX/MEM to EX Forwarding_Unit.vhd
MEM→EX Forward from MEM/WB to EX Forwarding_Unit.vhd
Load-Use Stall 1 cycle Hazard_Unit.vhd

Forwarding Datapath:

                    ┌────────────────┐
                    │ Forwarding Unit│
                    └───────┬────────┘
                            │ Forward Sel
        ┌───────────────────┼───────────────────┐
        ▼                   ▼                   ▼  
    ┌───────┐          ┌─────────┐         ┌─────────┐
    │ ID/EX │────────▶ │   ALU   │ ◀────── │ EX/MEM  │
    └───────┘          └─────────┘         └─────────┘
                            ▲
                            │
                       ┌─────────┐
                       │ MEM/WB  │
                       └─────────┘

Control Hazards

Hazard Type Solution Penalty
Unconditional Jump Jump resolved in ID, flush IF/ID 1 cycle
Conditional Branch Branch resolved in EX, flush IF/ID & ID/EX 2 cycles
RET/RTI Stall until PC loaded from memory 3+ cycles

Structural Hazards

The Von Neumann Memory is shared between Fetch and Memory stages. This is handled via split-cycle access:

  • First half of clock: Instruction Fetch
  • Second half of clock: Data Memory Access (LDD/STD)

🔌 Interrupts

Interrupt Vector Table

Vector Address Purpose
0 M[0] Reset vector
1 M[1] Hardware interrupt

Interrupt Mechanism

Software Interrupt (INT Index):

  1. Push PC+1 to stack
  2. Save flags to shadow register
  3. Jump to M[Index]

Hardware Interrupt (External intr Signal):

  1. Insert HW_INT instruction into pipeline
  2. Push PC+1 to stack
  3. Save flags to shadow register
  4. Jump to M[1]

Return from Interrupt (RTI):

  1. Restore flags from shadow register
  2. Pop return address from stack
  3. Resume execution

📁 Project Structure

pipelord/
├── 📄 README.md                    # This file
├── 📁 design/
│   └── 🖼️ design.png              # Architecture diagram
├── 📁 src/
│   ├── 📄 Processor.vhd            # Top-level processor entity
│   ├── 📄 Memory.vhd               # Main memory module
│   ├── 📁 stages/
│   │   ├── 📁 1-fetch/rtl/         # Fetch stage (PC, HLT)
│   │   ├── 📁 2-decode/rtl/        # Decode stage (Control, RegFile)
│   │   ├── 📁 3-execute/rtl/       # Execute stage (ALU, ALU Controller)
│   │   ├── 📁 4-memory/rtl/        # Memory stage (SP Module)
│   │   └── 📁 5-writeback/rtl/     # Writeback stage (Mux, SWAP FSM)
│   ├── 📁 pipeline_regs/           # IF/ID, ID/EX, EX/MEM, MEM/WB registers
│   ├── 📁 hazard_control/          # Hazard Unit, Forwarding Unit
│   └── 📁 utils/rtl/               # Muxes, Adders
├── 📁 Assembler/
│   ├── 📄 assembler.py             # Python assembler
│   ├── 📄 README.md                # Assembler documentation
│   └── 📁 tests/                   # Assembly test programs
├── 📁 do_files/                    # ModelSim simulation scripts
├── 📄 program.mem                  # Compiled program (hex)
└── 📄 program.bin                  # Compiled program (binary)

🛠️ Getting Started

Prerequisites

  • VHDL Simulator: ModelSim, GHDL, or Vivado
  • Python 3.x: For the assembler

1. Write Assembly Code

Create a file myprogram.asm:

.ORG 0
    JMP Main

.ORG 10
Main:
    LDM R1, 100       # Load 100 into R1
    LDM R2, 200       # Load 200 into R2
    ADD R3, R1, R2    # R3 = R1 + R2 = 300
    OUT R3            # Output R3
    HLT               # Stop

2. Assemble the Program

python3 Assembler/assembler.py myprogram.asm

This generates program.mem (hex format). For binary output:

python3 Assembler/assembler.py myprogram.asm --bin

3. Run Simulation (ModelSim)

# Navigate to project directory
cd pipelord

# Start ModelSim and run the testbench
vsim -do do_files/Processor_tb.do

4. Observe Results

  • View waveforms in ModelSim
  • Check register values, memory contents, and output port
  • Verify pipeline behavior with forwarding and stalls

🧪 Testing

The project includes comprehensive testbenches for each component:

Component Testbench
ALU src/stages/3-execute/tb/ALU_tb.vhd
Register File src/stages/2-decode/tb/RegisterFile_tb.vhd
Control Unit src/stages/2-decode/tb/Control_Unit_tb.vhd
Full Processor src/tb/Processor_tb.vhd

Run all tests:

vsim -do do_files/run_all_tests.do

📊 Performance

Metric Value
Pipeline Depth 5 stages
Clock Cycles per Instruction (CPI) ~1.0 (ideal)
Data Hazard Penalty 0 cycles (forwarded)
Load-Use Penalty 1 cycle
Branch Penalty 1-2 cycles
Memory Width 32 bits
Address Space 256K words (18-bit address)

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📜 License

This project is developed for educational purposes as part of a Computer Architecture course.


About

A 32-bit 5-Stage Pipelined Processor in VHDL

Resources

Stars

9 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages