2026-07-02
A classic 5-stage pipeline (IF, ID, EX, MEM, WB) has a problem: an instruction produces its result in EX (or MEM for loads), but the next instruction needs that result in its own EX stage — one cycle later. Without help, the consumer reads a stale value from the register file, because the producer hasn't reached WB yet.
The naive fix is to stall the pipeline for 2-3 cycles until WB completes. That murders IPC. The real fix is forwarding (also called bypassing): route the result directly from the producer's pipeline latch into the consumer's ALU input muxes, before it ever hits the register file.
The forwarding network is a set of multiplexers in front of the ALU inputs. Each ALU operand mux picks from:
A small hazard detection unit compares the current instruction's source register numbers against the destination registers sitting in EX/MEM and MEM/WB. If they match and the producer will actually write that register, the mux select flips to grab the forwarded value.
The load-use case is the one exception you can't forward away. A load produces its data at the end of MEM, but the next instruction needs it at the start of EX — that's negative time. The hazard unit detects this and inserts exactly 1 bubble, after which MEM/WB forwarding covers the rest. This is why compilers reorder code to put an independent instruction after every load.
Concrete example. In a MIPS-style pipeline:
add $t0, $s1, $s2 — writes $t0 in WBsub $t1, $t0, $s3 — needs $t0 in EX, one cycle after the add's EXWithout forwarding: stall 2 cycles. With EX/MEM→ALU forwarding: zero stalls. The sub's ALU input mux selects the EX/MEM latch instead of the register file.
Rule of thumb. A classic 5-stage pipeline needs 2 forwarding paths per ALU operand (from EX/MEM and MEM/WB), so a 2-input ALU needs 4 forwarding sources total. Deeper or superscalar pipelines multiply this fast: a 4-wide out-of-order machine with 6 pipeline stages between issue and writeback can have dozens of bypass paths, and the forwarding mux tree itself becomes a critical timing path — often the reason a design misses its target frequency.
