How jayjain2365/risc-v-pipelined-processor-verilog- works
This repository is a 5-stage pipelined RV32I processor written in Verilog. The architecture is centered around top_riscv.v, which wires together the stage modules, hazard logic, and shared pipeline state into one CPU datapath.
1. Top-level composition
- top_riscv.v is the integration boundary for the whole processor.
- It connects the five pipeline stages (if_stage, id_stage, ex_stage, mem_stage, wb_stage) and the control helpers (hazard_unit, forwarding_unit).
- The design follows a Harvard-style split between instruction fetch and data access, with separate instruction and data memory paths.
2. Instruction Fetch (IF)
- if_stage.v owns the program counter and instruction fetch path.
- It selects the next PC based on sequential flow, branch control, and stall/flush signals coming from the hazard/control logic.
- The fetched instruction is passed forward into the decode stage through the pipeline boundary.
3. Instruction Decode + Register Read (ID)
- id_stage.v decodes the instruction fields, generates immediates, and reads the register file.
- It also produces control signals used later in the pipeline, such as ALU operation selection, memory read/write intent, and register write-back enable.
- This is the main control-generation boundary for the processor.
4. Execute stage (EX)
- ex_stage.v performs the ALU work for arithmetic and logical operations such as ADD, SUB, AND, OR, and ADDI.
- It also handles branch comparison for BEQ and computes branch-related results.
- Operand selection here is affected by forwarding, so the EX stage is the main consumer of bypassed data.
5. Memory stage (MEM)
- mem_stage.v interfaces with data memory for LW and SW.
- For loads, it forwards the loaded value toward write-back.
- For stores, it commits the ALU-computed address and write data to memory.
- This stage is where the data-side Harvard boundary is most visible.
6. Write-back stage (WB)
- wb_stage.v selects what value gets written into the register file: either the ALU result or loaded memory data.
- It finalizes architectural state updates by asserting register write-back for the destination register.
- This is the last stage of the pipeline and the point where results become visible to later instructions.
7. Pipeline register flow
- The design is organized as a classic 5-stage pipeline, so data and control move stage-to-stage through internal pipeline latches.
- These registers preserve instruction context as it advances from IF → ID → EX → MEM → WB.
- The README notes future work around “full pipeline registers,” but the current file structure indicates the pipeline is already staged and coordinated across modules.
8. Data hazard handling
- hazard_unit.v detects conditions where the pipeline must stall or flush, especially load-use hazards.
- This unit prevents incorrect execution when an instruction needs a value that has not yet been produced by an earlier stage.
- It also contributes to pipeline control during branches or other situations requiring invalidation of speculative work.
9. Forwarding / bypass network
- forwarding_unit.v reduces RAW stalls by routing results from later pipeline stages back to EX when possible.
- This is the main performance mechanism that avoids waiting for register write-back when the result is already available in EX/MEM or MEM/WB.
- In architecture terms, it is the bypass path that connects later stages back to the execute stage.
10. Control of branches and flushing
- The processor has basic BEQ support, so branch decisions are resolved through the pipeline control path.
- When a branch is taken, the control logic must redirect the PC and flush wrong-path instructions.
- This makes branch resolution a cross-cutting concern between IF, EX, and the hazard/control units.
11. Verification boundary
- tb_top_riscv.v is the verification harness for the whole CPU.
- It exercises the integrated top-level design in simulation, likely driving instruction and data memories and checking register outcomes.
- The README indicates simulation was run in Xilinx Vivado, so the repo is oriented around RTL simulation rather than software execution.
12. Observed technology and scope
- The project is pure Verilog HDL with no software runtime or external system dependencies beyond the simulator/toolchain.
- The implemented ISA subset is small and focused: integer ALU ops, immediate add, loads/stores, and a basic branch.
- The architectural emphasis is on teaching and demonstrating pipeline organization, hazard detection, and forwarding rather than completeness of the RISC-V spec.
Main entry points: top_riscv.v Top CPU · ex_stage.v Execute · hazard_unit.v Hazard unit · id_stage.v Decode
Components 9
Pipeline datapath
The five-stage RV32I execution path and its stage-to-stage flow.
- Top CPU · Top-level integration boundary wiring the pipeline stages and control units.
top_riscv.v - Fetch · Program counter and instruction fetch stage.
if_stage.v - Decode · Instruction decode, immediate generation, and register read/control generation.
id_stage.v - Execute · ALU operations, operand selection, and branch compare.
ex_stage.v - Memory · Data memory access for loads and stores.
mem_stage.v - Write-back · Selects the result written back into the register file.
wb_stage.v
Control logic
Stall, flush, and bypass mechanisms that coordinate the pipeline.
- Hazard unit · Detects pipeline hazards and drives stall/flush behavior.
hazard_unit.v - Forwarding · Bypasses later-stage results back to execute to reduce RAW stalls.
forwarding_unit.v
Verification
Simulation harness for the integrated CPU.
- Testbench · Top-level RTL testbench for simulation and verification.
tb_top_riscv.v
Connections 18
- Top CPU → Fetch: inst fetch · Instruction path into the fetch stage.
- Top CPU → Decode: decode inputs · Instruction and pipeline state flow into decode.
- Top CPU → Execute: execute inputs · Operands and control flow into execute.
- Top CPU → Memory: mem interface · Data-side memory path through the top-level datapath.
- Top CPU → Write-back: write-back · Final result selection returns to architectural state.
- Top CPU → Hazard unit: stall/flush · Central control signals for hazard handling.
- Top CPU → Forwarding: bypass control · Forwarding decisions are wired through the top-level CPU.
- Fetch → Decode: instr + pc · Fetched instruction and program counter advance to decode.
- Decode → Execute: decoded ops · Operands, immediates, and control signals advance to execute.
- Execute → Memory: alu result · Execute results and branch outcomes move to memory stage.
- Memory → Write-back: load data · Loaded data or pass-through ALU result advances to write-back.
- Write-back → Decode: reg write data · Architectural write-back feeds future register reads.
- Hazard unit → Fetch: stall/flush · Controls PC hold and wrong-path invalidation.
- Hazard unit → Decode: stall/flush · Freezes or clears decode-side pipeline state when needed.
- Hazard unit → Execute: stall/flush · Coordinates pipeline control around hazards and branches.
- Forwarding → Execute: bypass sel · Selects forwarded operands for execute stage inputs.
- Execute → Hazard unit: branch result · Branch decisions inform pipeline flush/redirection.
- Testbench → Top CPU: stimulus · Testbench instantiates and drives the integrated CPU.