How Does Operand Forwarding Resolve Pipeline Data Hazards?
Operand forwarding, also known as bypassing, is a hardware technique used in pipelined processors to resolve read-after-write data hazards without stalling the pipeline. Instead of waiting for a producing instruction to write its result back to the register file, forwarding routes the computed value directly from an intermediate pipeline register to the execution inputs of a subsequent instruction. This eliminates unnecessary clock-cycle delays and preserves high instruction throughput.
Understanding Read-After-Write Data Hazards
In a classic five-stage RISC pipeline—Instruction Fetch (IF), Instruction Decode (ID), Execute (EX), Memory Access (MEM), and Write Back (WB)—instructions overlap in execution. A read-after-write (RAW) data hazard occurs when an instruction depends on the result of a preceding instruction that has not yet reached the WB stage.
Consider two consecutive instructions:
ADD R1, R2, R3SUB R4, R1, R5
The ADD instruction computes the new value of
$R_1$ during its EX stage, but it does not write that value
into the register file until its WB stage. Meanwhile, the
SUB instruction reads its source operands during its ID
stage—two cycles earlier than ADD writes back. Without
intervention, SUB would read the stale value of
$R_1$ from the register file.
How the Forwarding Path Works
Operand forwarding solves this problem by adding dedicated data paths
and multiplexers (MUXes) at the inputs of the Arithmetic Logic Unit
(ALU) in the EX stage. Because the result of ADD is already
available in the EX/MEM pipeline register at the end of its
EX stage, and in the MEM/WB pipeline register at the end of
its MEM stage, the hardware can tap into those registers directly.
A forwarding unit compares the destination register
address of instructions currently in the EX/MEM and
MEM/WB stages against the source register addresses of the
instruction in the ID/EX stage. When a match is
detected—and the producing instruction is set to write to a register—the
forwarding unit asserts control signals on the ALU input multiplexers.
Instead of selecting the value read from the register file, the
multiplexer selects the forwarded result from EX/MEM or
MEM/WB.
Forwarding Priority and Edge Cases
When multiple instructions in the pipeline write to the same
destination register, the forwarding unit must select the most recent
value. For example, if both the EX/MEM and
MEM/WB stages hold pending writes to $R_1$,
the value in EX/MEM is newer and takes priority over
MEM/WB.
While operand forwarding eliminates stalls for most ALU-to-ALU
dependencies, it cannot resolve every hazard on its own. A
load-use hazard occurs when a LOAD
instruction is immediately followed by an instruction that uses the
loaded value. Because data from memory is not available until the end of
the MEM stage, it cannot be forwarded backward in time to the EX stage
of the very next instruction. In this case, a hazard detection unit must
insert a single-cycle stall (a pipeline bubble) before forwarding the
loaded value from MEM/WB.