Why Does a Load-Use Hazard Still Require a Pipeline Stall?

A load-use hazard occurs when an instruction immediately following a memory load depends on the loaded value. Even in a classical pipelined processor equipped with full data forwarding paths, this specific hazard cannot be resolved by forwarding alone and still requires a one-cycle pipeline stall. The reason lies in the timing of when the loaded data becomes available compared to when the next instruction needs it.

How a Classical Five-Stage Pipeline Works

In a standard five-stage RISC pipeline, instructions pass through five sequential stages:

  1. IF (Instruction Fetch): Reads the instruction from instruction memory.
  2. ID (Instruction Decode): Decodes the instruction and reads source registers from the register file.
  3. EX (Execute): Performs arithmetic or logic operations in the ALU, or computes a memory address.
  4. MEM (Memory Access): Reads from or writes to data memory.
  5. WB (Write Back): Writes the result back into the register file.

Normally, if an instruction writes a result to a register in the WB stage, a subsequent instruction reading that register in the ID stage would get stale data. Data forwarding (bypassing) solves most of these data hazards by routing results directly from later pipeline registers back to the ALU inputs in the EX stage.

Why Forwarding Solves ALU-to-ALU Hazards

Consider two back-to-back arithmetic instructions, such as an ADD followed by a SUB that uses the sum:

ADD R1, R2, R3   (IF -> ID -> EX -> MEM -> WB)
SUB R4, R1, R5        (IF -> ID -> EX  -> MEM -> WB)

The ADD instruction computes the new value of R1 at the end of its EX stage. At that exact moment, the SUB instruction is finishing its ID stage and is about to enter its EX stage. Forwarding paths route the ALU output from the EX/MEM pipeline register directly into the ALU input of the SUB instruction. Because the data is ready before SUB needs it in EX, no stall is required.

The Timing Problem in a Load-Use Hazard

Now consider a load instruction followed immediately by an arithmetic instruction that uses the loaded value:

LW  R1, 0(R2)    (IF -> ID -> EX -> MEM -> WB)
ADD R3, R1, R4        (IF -> ID -> EX  -> MEM -> WB)

During the LW instruction's EX stage, the ALU only calculates the memory address 0 + R2. The actual data from memory is not read until the MEM stage, meaning the value of R1 is only available at the end of LW's MEM stage.

However, by the time LW is in its MEM stage, the ADD instruction is already in its EX stage. ADD needs the value of R1 at the beginning of its EX stage, whereas LW does not produce R1 until the end of its MEM stage. Forwarding cannot send data backward in time, so no forwarding path can deliver R1 to ADD without delaying ADD.

How the Pipeline Resolves It

To resolve a load-use hazard, the hazard detection unit inserts a one-cycle stall (a pipeline bubble or NOP) between the load and the dependent instruction:

LW  R1, 0(R2)    (IF -> ID -> EX  -> MEM -> WB)
[stall / bubble]      (IF -> ID  -> NOP -> NOP -> NOP)
ADD R3, R1, R4             (IF   -> ID  -> EX  -> MEM -> WB)

With the one-cycle stall, ADD enters its EX stage at the same time LW enters its WB stage. At that point, the loaded value is sitting in the MEM/WB pipeline register and can be forwarded directly to the ALU input of ADD in EX.

Summary

Forwarding paths eliminate stalls whenever an instruction produces its result in the EX stage, because that result is ready in time for the next instruction's EX stage. A load instruction, however, does not produce its data until the end of the MEM stage. Because the immediately following instruction reaches EX one cycle too early, a single-cycle stall is unavoidable before forwarding can complete the handoff.