Day 44: Data hazards and the forwarding paths
Data hazards and forwarding
A data hazard happens when an instruction needs a register value that an earlier, still-in-flight instruction hasn't written back yet. Example: add x1, x2, x3 immediately followed by sub x4, x1, x5 — the sub reads x1 in ID while the add is only in EX/MEM, so the register file still holds the *old* x1. Forwarding (bypassing) routes the fresh result directly from EX/MEM or MEM/WB back to the ALU inputs, no stall needed.
A forwarding unit compares the destination registers of instructions in EX/MEM and MEM/WB against the source registers of the instruction in EX, and drives forwarding muxes on the ALU inputs when they match. Priority matters: if both stages could forward the same register, the *most recent* (EX/MEM) value wins. Most back-to-back dependencies resolve this way with zero penalty.
Muxes again
Those forwarding muxes are the exact 'muxes are everywhere in a CPU' payoff promised in Stage 0. The forwarding unit is a small comparison-and-select block — Stage-0 combinational logic — bolted onto the datapath. When you build it in RTL (Stage 2), it's a dozen lines that eliminate most stalls.
Key terms
- Data hazard
- A dependency where an instruction needs a result not yet written back by an earlier instruction.
- Forwarding (bypassing)
- Routing a result directly from a later pipeline stage to a dependent instruction’s input.
- Forwarding unit
- Logic comparing destination vs source registers to drive the forwarding muxes.
- RAW dependency
- Read-after-write: the true data dependency forwarding addresses.
Before moving on, you should be able to
Given add x1,x2,x3 then sub x4,x1,x5 in a 5-stage pipeline, how is the dependency on x1 usually resolved?