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:

  1. ADD R1, R2, R3
  2. SUB 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.