CampusFlow

⚠️ Data Hazards

Data hazards occur when instructions depend on each other's results. Learn how to detect, avoid, and resolve them using forwarding, stalling, and hazard detection.

What Are Data Hazards?

ℹ️

Data Hazard Definition

A data hazard occurs when the pipeline changes the order of read/write accesses to operands so that the program produces incorrect results. The pipeline must be stalled or reordered to maintain correct data flow.
Data hazards arise from register dependencies between instructions.

Types of Data Hazards

Example: Read After Write (RAW)

assembly

ADD R1, R2, R3  ; R1 = R2 + R3
SUB R4, R1, R5  ; R1 needed here!

Explanation: RAW: ADD writes R1 in WB stage, but SUB needs R1 in EX stage. Without forwarding, SUB must stall 2 cycles.

Data Forwarding (Bypassing)

💡

Forwarding

Forwarding (or bypassing) sends the result of an instruction directly from the EX or MEM stage back to the ALU input of a dependent instruction, avoiding a stall. The result is "forwarded" before it's written to the register file.
Key insight: The ALU output from EX stage contains the result before WB. Forwarding routes this value back to the next instruction's ALU input in the same cycle.

assembly

// LW -> ADD hazard: R1 needed immediately
LW R1, 0(R2)    ; Mem[R2] → R1 (result in MEM)
ADD R3, R1, R4  ; Needs R1 in EX stage

// Without forwarding: 2-cycle stall (bubbles)
// With forwarding: R1 forwarded from MEM stage output
//   directly to ADD's ALU input — 0 stall cycles

Interactive: Stall vs Forwarding

💡

Toggle Forwarding

See the difference between stalled and forwarded execution. With stalling, a "bubble" (STALL) is inserted into the pipeline. Forwarding eliminates the need for a stall.
LW R1,0(R2) → ADD R3,R1,R4

Pipeline without Forwarding — 2-Cycle Stall

CycleI1: LW R1,0(R2)I2: ADD R3,R1,R4I3: SUB R5,R6,R7I4: AND R8,R9,R10I5: OR R11,R12,R13
C1IF
C2IDIF
C3EXIDIF
C4MEMSTALLIDIF
C5WBSTALLIDIF
C6EXIDIF
C7MEMEXIDIF
STALL = Pipeline bubble (NOP inserted)

Hazard Detection Unit

ℹ️

Hardware Solution

The hazard detection unit monitors the pipeline registers (ID/EX, EX/MEM, MEM/WB) to detect RAW hazards. When it detects a read-after-write where the source register matches the destination of an instruction still in the pipeline, it either stalls (inserts bubble) or enables the forwarding unit.

Detection Logic

  • 1. Compare rs/rt of ID/EX instruction against rd of EX/MEM and MEM/WB
  • 2. If match found AND destination register write is enabled
  • 3. Activate forwarding mux to select bypassed value
  • 4. If LW followed by RAW dependency, stall for 1 cycle

Forwarding Paths

EX/MEM → EXALU result → next ALU input
MEM/WB → EXMemory result → next ALU input
MEM/WB → IDRegister write → next register read

Code Example: Hazard Detection

python

class HazardDetectionUnit:
    def __init__(self):
        self.forwardA = 0  # 0=reg, 1=EX/MEM, 2=MEM/WB
        self.forwardB = 0
        self.stall = False

    def check(self, id_ex_rs, id_ex_rt, ex_mem_rd, mem_wb_rd,
              ex_mem_regwrite, mem_wb_regwrite):
        # ForwardA: ALU input 1
        if ex_mem_regwrite and ex_mem_rd != 0 and ex_mem_rd == id_ex_rs:
            self.forwardA = 1
        elif mem_wb_regwrite and mem_wb_rd != 0 and mem_wb_rd == id_ex_rs:
            self.forwardA = 2
        else:
            self.forwardA = 0

        # ForwardB: ALU input 2
        if ex_mem_regwrite and ex_mem_rd != 0 and ex_mem_rd == id_ex_rt:
            self.forwardB = 1
        elif mem_wb_regwrite and mem_wb_rd != 0 and mem_wb_rd == id_ex_rt:
            self.forwardB = 2
        else:
            self.forwardB = 0

        # Stall detection (LW use)
        self.stall = (ex_mem_rd == id_ex_rs or ex_mem_rd == id_ex_rt)

Compiler Solutions (Software)

💡

Code Scheduling

Compilers can reduce hazards by reordering instructions. Independent instructions are moved between dependent ones to create distance. This is called instruction scheduling or pipeline scheduling.

assembly

// Before scheduling — stalls everywhere
LW R1, 0(R2)      ; load
ADD R3, R1, R4    ; RAW stall — needs R1
SUB R5, R6, R7    ; independent but blocked

// After scheduling — no stalls
LW R1, 0(R2)      ; load
SUB R5, R6, R7    ; moved up — independent work
ADD R3, R1, R4    ; RAW — R1 ready now (no stall!)

Interview Questions

What is a RAW hazard and how is it resolved?

RAW (Read After Write) is a true data dependency where an instruction reads a register that a previous instruction writes. It's resolved via forwarding/bypassing: the ALU result is routed directly from the EX or MEM stage output to the ALU input of the dependent instruction. When LW creates a RAW, a 1-cycle stall may still be needed.

How does a hazard detection unit work?

The HDU monitors pipeline registers and compares source register fields (rs, rt) of the ID/EX stage against destination register fields (rd) in EX/MEM and MEM/WB. If a match is found and RegWrite is active, the forwarding mux selects the bypassed value instead of the register file output.

What is the difference between WAR and WAW hazards?

WAR (Write After Read) or anti-dependency: an instruction writes a register that an earlier instruction reads. WAW (Write After Write) or output dependency: two instructions write the same register. Both are name dependencies (not true data dependencies) and can be eliminated by register renaming.

Why can't forwarding fully eliminate the LW-use stall?

A LW instruction reads memory in the MEM stage. The result is available at the end of MEM, but the dependent instruction needs it at the start of its EX stage (same cycle). Since MEM and EX overlap, forwarding can't bridge a 1-cycle gap. One stall cycle (bubble) is inserted between LW and its dependent instruction.