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:
- IF (Instruction Fetch): Reads the instruction from instruction memory.
- ID (Instruction Decode): Decodes the instruction and reads source registers from the register file.
- EX (Execute): Performs arithmetic or logic operations in the ALU, or computes a memory address.
- MEM (Memory Access): Reads from or writes to data memory.
- 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.