5.2.6Processor Datapath & Pipelining

Data hazards and forwarding - bypassing

3,883 words18 min readdifficulty · medium6 backlinks

What Are Data Hazards?

Why RAW Hazards Dominate

In a classic 5-stage pipeline (IF → ID → EX → MEM → WB):

Instruction 1: ADD R1, R2, R3    # R1 = R2 + R3
Instruction 2: SUB R4, R1, R5    # R4 = R1 - R5  (needs R1 from I1)

Timeline without forwarding:

Clock: 1    2    3    4    5    6    7
ADD:   IF   ID   EX   MEMWB
SUB:        IF   ID   EX   MEM  WB
              ↑
         Reads R1 here (cycle 3)
         But R1 written in cycle 5!

The SUB instruction reads R1 in the ID stage (cycle 3), but ADD writes R1 in the WB stage (cycle 5). Two-cycle gap = wrong data.

Solution1: Stalling (The Naive Fix)

Derivation of stall cycles needed:

  • Data produced in EX stage (for ALU ops) → available in cycle n+2n + 2 (EX at nn, MEM at n+1n+1, WB at n+2n+2)
  • Data needed in ID stage by dependent instruction
  • If dependent instruction is in cycle mm, it needs data by cycle m+1m + 1 (ID stage)
  • Stalls required: (n+2)(m+1)=nm+1(n + 2) - (m + 1) = n - m + 1

For consecutive instructions (m=n+1m = n + 1): Stalls = n(n+1)+1=0n - (n+1) + 1 = 0 stalls? Wrong! This ignores that data isn't written to register file until WB completes.

Correct calculation: If instruction ii is in EX at cycle nn, result written at cycle n+2n + 2 (end of WB). If instruction i+1i+1 is in ID at cycle n+1n+1, it reads at cycle n+1n+1. Gap = (n+2)(n+1)=1(n+2) - (n+1) = 1 cycle... but register file read happens before clock edge where write occurs. Actual gap = 2 cycles for ALU-to-ALU dependency.

Solution 2: Forwarding/Bypassing (The Smart Fix)

Forwarding Paths: The Architecture

Key components:

  1. Forwarding unit (hazard detection + control logic)
  2. Multiplexers at ALU inputs (select between register file data vs. forwarded data)
  3. Pipeline registers that carry result values forward (EX/MEM, MEM/WB)

Derivation of forwarding logic:

Start with the hazard condition: instruction in EX stage needs data from instruction in EX, MEM, or WB stage.

Case 1: EX-to-EX forwarding (1 cycle away)

ADD R1, R2, R3    # Cycle n: EX stage computes R1
SUB R4, R1, R5    # Cycle n: ID stage, cycle n+1: EX stage needs R1

At cycle n+1n+1:

  • ADD result is in EX/MEM pipeline register (just came out of EX stage)
  • SUB is in EX stage, needs R1 for ALU input

Forward from EX/MEM.ALUOutput → ALU input MUX.

Case 2: MEM-to-EX forwarding (2 cycles away)

ADD R1, R2, R3    # Cycle n: EX, cycle n+1: MEM
AND R6, R7, R8    # Cycle n+1: EX (doesn't use R1)
SUB R4, R1, R5    # Cycle n+2: EX stage needs R1

At cycle n+2n+2:

  • ADD result is in MEM/WB pipeline register
  • SUB is in EX stage

Forward from MEM/WB.ALUOutput → ALU input MUX.

Priority rule derivation: If both EX/MEM and MEM/WB have data for the same register, which do we forward?

ADD R1, R2, R3    # I1: Cycle n+1: MEM stage (result in MEM/WB)
ADD R1, R6, R7    # I2: Cycle n+1: EX stage (result in EX/MEM)
SUB R4, R1, R5    # I3: Cycle n+1: ID stage, cycle n+2: EX stage

Both I1 and I2 write R1, but I2 is more recent. I3 should use I2's result.

Rule: EX/MEM forwarding (more recent) overides MEM/WB forwarding.

Load-Use Hazards: When Forwarding Isn't Enough

Forwarding Unit Implementation

Derivation of control logic:

For ForwardA (ALU input 1, corresponds to Rs):

if (EX/MEM.RegWrite 
    and EX/MEM.RegisterRd ≠ 0 
    and EX/MEM.RegisterRd = ID/EX.RegisterRs)
then ForwardA = 10

else if (MEM/WB.RegWrite 
         and MEM/WB.RegisterRd ≠ 0
         and MEM/WB.RegisterRd = ID/EX.RegisterRs
         and not(EX/MEM hazard condition))  // Priority check
then ForwardA = 01

else ForwardA = 00

Why the priority check? If both EX/MEM and MEM/WB match, we want the more recent value (EX/MEM), so MEM/WB forwarding only happens when EX/MEM doesn't match.

ForwardB logic is identical, but compares with ID/EX.RegisterRt.

Performance Impact Analysis

Connections

  • 5.2.01-Five-stage-pipeline-basics - Foundation of the pipeline stages where hazards occur
  • 5.2.07-Control-hazardsand-branch-prediction - Other major hazard type (control flow)
  • 5.2.09-Pipeline-performance-analysis - How hazards impact overall CPI
  • 5.3.02-Superscalar-out-of-order-execution - Advanced forwarding in modern processors
  • 3.1.05-Register-file-design - Hardware that forwarding bypasses
  • 6.2.03-Compiler-optimization-techniques - Instruction scheduling to minimize hazards
Recall Explain to a 12-Year-Old

Imagine you're building Lego spaceships on an assembly line. You have 5 stations: grab pieces (IF), check instructions (ID), snap pieces together (EX), add special parts from a box (MEM), and put the finished section on the shelf (WB).

Now, Station 3 is building a red wing, and Station 2 (right behind it) needs that same red wing to attach to the body. But the wing isn't on the shelf yet—it's still being built at Station 3!

Bad solution: Stop the whole line and wait until the wing reaches the shelf. Slow!

Smart solution (forwarding): Station 3 just hands the wing directly to Station 2. Why put it on the shelf first if the next person needs it right now?

But sometimes you need a piece from the special parts box (memory). That box is slow—you have to walk over, unlock it, and find the piece. Even with forwarding, you still have to wait one turn because the piece literally doesn't exist until you open the box. That's a load-use hazard.

Forwarding is like teamwork: pass the result directly to whoever needs it next instead of following every rule about putting stuff away first.

#flashcards/hardware

What is a data hazard in a pipeline? :: When an instruction needs a register value that a previous instruction hasn't written yet, because the previous instruction is still in the pipeline. The dependent instruction would read stale data.

What are the three types of data hazards?
RAW (Read After Write - true dependency), WAR (Write After Read - anti-dependency), WAW (Write After Write - output dependency). RAW is the most common in simple pipelines.
What is forwarding/bypassing?
A technique that routes computed results directly from pipeline registers (EX/MEM or MEM/WB) to the ALU inputs of dependent instructions, avoiding the need to wait for write-back to the register file.
What is a load-use hazard?
When an instruction immediately following a load needs the loaded value. Even with forwarding, one stall cycle is required because the data doesn't exist until the load's MEM stage completes.
What are the two main forwarding paths in a 5-stage pipeline?
EX/MEM to EX stage (for results one cycle old) and MEM/WB to EX stage (for results two cycles old). EX/MEM has priority when both match.
Why can't forwarding eliminate load-use hazards?
The loaded data doesn't exist until the end of the MEM stage, but the dependent instruction needs it at the start of the EX stage (one stage earlier). The data can't be forwarded before it exists.
How many stall cycles are needed for a load-use hazard with forwarding?
One stall cycle. Without forwarding, it would be two or three cycles depending on the architecture.
What is the forwarding unit?
Combinational logic that monitors pipeline registers, compares destination and source registers, and generates ForwardA/ForwardB control signals for ALU input multiplexers.
Why does EX/MEM forwarding have priority over MEM/WB forwarding?
Because EX/MEM contains the more recent result. If two instructions write the same register, the dependent instruction should use the newer value.
What does ForwardA = 10 mean?
Forward the ALU result from the EX/MEM pipeline register to ALU input A (the first operand). 10 is the encoding for EX/MEM forwarding.
What is instruction scheduling in the context of hazards?
A compiler optimization that reorders independent instructions to fill load delay slots and minimize pipeline stalls while preserving program semantics.
What condition creates an EX-to-EX forwarding opportunity?
When EX/MEM.RegWrite = 1, EX/MEM.RegisterRd ≠ 0, and EX/MEM.RegisterRd equals either ID/EX.RegisterRs or ID/EX.RegisterRt.
Why do we check RegisterRd ≠ 0 in forwarding logic?
Register 0 is hardwired to zero in architectures like MIPS and RISC-V, so writes to it don't create real dependencies. No forwarding is needed for R0.
What is a pipeline bubble?
A NOP (no operation) inserted into the pipeline to stall execution, effectively creating an empty pipeline stage where no useful work is done.
How does forwarding improve CPI?
By eliminating most ALU-to-ALU data hazard stalls. Typical improvement: from CPI ≈ 1.975 (stall-only) to CPI ≈ 1.125 (with forwarding) a 1.76× speedup.

Concept Map

creates

violated by

main type

rare type

rare type

detected by

because

fixed by

inserts

cost

better fix

routes

avoids

Pipeline stage overlap

Data dependencies

Data hazard

RAW read after write

WAR anti-dependency

WAW output dependency

Dest i equals Src j and not R0

Reads stale register value

Stalling with bubbles

NOP delays until WB

Lost cycles hurt performance

Forwarding bypassing

EX or MEM result to EX input

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho yaar, pipeline ek assembly line jaisa hai jahan multiple instructions ek saath different stages mein chal rahe hote hain. Problem tab aati hai jab ek instruction ko previous instruction ka result chahiye, lekin wo result abhi tak register mein likha hi nahi gaya. Jaise agar ADD instruction R1 mein answer daal raha hai, aur uske turant baad SUB ko wahi R1 padhna hai, toh SUB apne ID stage mein pahunch jaata hai lekin ADD ne abhi tak WB (write back) kiya hi nahi hota. Isko hum data hazard kehte hain, aur sabse common type hai RAW (Read After Write) jahan ek instruction wahi cheez padhna chahta hai jo dusra abhi likh raha hai. Bina kisi fix ke, SUB purana ya stale data utha lega aur galat computation ho jaayega.

Ab iska ek seedha-saada solution hai stalling — matlab pipeline mein "bubbles" ya NOPs daal do taaki dependent instruction thoda wait kare jab tak data ready na ho jaaye. 5-stage pipeline mein ALU-to-ALU dependency ke liye tumhe roughly 2 cycles rukna padta hai, kyunki data tab tak register file mein properly write nahi hota jab tak WB stage complete na ho jaaye. Lekin dhyaan rakho — ye maan lena ki "sirf ek cycle stall karna kaafi hai" ek common galti hai, kyunki register file ka read write se pehle ho jaata hai clock edge par, isliye actual gap zyada hota hai. Ye samajhna zaroori hai warna tum stall count galat lagaoge.

Ye topic isliye matter karta hai kyunki stalling se performance kaafi gir jaati hai — 3 wasted cycles ka matlab hai teen guna slowdown sirf ek chhoti si instruction sequence ke liye. Real processors mein isiliye forwarding (ya bypassing) use hoti hai, jahan result ko directly EX stage se le liya jaata hai bina register file ka wait kiye. Agar tum data hazards ki root cause samajh loge, toh aage forwarding, pipeline optimization, aur modern CPU design ke concepts bahut aasaan lagenge. Ye foundation hai jispe pura efficient processor performance khada hota hai.

Go deeper — visual, from zero

Test yourself — Processor Datapath & Pipelining

Connections