5.2.6 · D5Processor Datapath & Pipelining
Question bank — Data hazards and forwarding - bypassing
The five stages we keep referring to are : fetch the instruction, decode it and read registers, do the ALU work, touch memory, write the result back. Keep that order in your head — most traps hide in when a value is born and when it is read.
True or false — justify
A RAW (Read-After-Write) hazard means a later instruction tries to read a register before the earlier instruction has written it
True — "read after write" is the program order we want, and the hazard is that the pipeline lets the read happen too early, grabbing the stale value.
WAR and WAW hazards are common problems in a simple in-order 5-stage pipeline
False — because every instruction reads in ID and writes in WB in the same fixed order, an earlier instruction always reads before a later one writes; WAR/WAW only bite when instructions can reorder (see 5.3.02-Superscalar-out-of-order-execution).
Forwarding eliminates all stalls in a 5-stage pipeline
False — it eliminates ALU-to-ALU stalls, but a load feeds its data only after MEM, so a load followed immediately by a dependent instruction still needs exactly one stall (the load-use hazard).
A hazard where the destination register is R0 (hardwired zero) can be safely ignored
True — R0 always reads as zero regardless of any "write," so a producer targeting R0 changes nothing and no forwarding or stall is needed.
If the producing and consuming instructions are separated by three or more other instructions, no forwarding is needed
True — by the time the consumer reaches EX, the producer has finished WB, so a normal register-file read returns the fresh value.
Forwarding physically writes the result into the register file earlier than normal
False — forwarding routes the value straight to the ALU input mux and leaves the normal WB timing untouched; the register file is bypassed, not sped up.
Stalling and forwarding solve the same problem in the same way
False — both fix RAW hazards, but stalling delays the consumer until data is ready, while forwarding reroutes data so the consumer never has to wait (for ALU ops).
The forwarding unit lives in the EX stage and controls the ALU input multiplexers
True — it compares the destination registers sitting in the EX/MEM and MEM/WB pipeline registers against the source registers of the instruction now entering EX, and picks the mux setting accordingly.
Spot the error
"A single one-cycle bubble is always enough to fix an ALU-to-ALU RAW hazard."
Wrong — the result is produced at the end of EX but only lands in the register file at the end of WB, two stages later, while the consumer reads at the start of ID; a back-to-back dependency needs two stall cycles without forwarding, not one.
"We should forward from the MEM/WB register whenever it holds the needed value, since it is the most settled result."
Wrong — if EX/MEM also holds that register, EX/MEM is the more recent producer and must win; forwarding the older MEM/WB value would deliver a result the program already overwrote.
"The forwarding condition only needs EX/MEM.RegisterRd == ID/EX.RegisterRs."
Wrong — you must also require
RegWrite == 1 (the producer actually writes a register) and RegisterRd != 0 (not the zero register); otherwise you forward garbage from a store/branch or a phantom R0 write."Load results can be forwarded to the immediately following instruction just like ALU results."
Wrong — a load's data is not available until the end of MEM, one stage later than an ALU result; the next instruction's EX has already begun, so hardware must stall one cycle first, then forward from MEM/WB.
"Since the register file writes in WB and reads in ID, an instruction 4 cycles behind still risks a hazard."
Wrong — with a split-phase register file (write in the first half of WB, read in the second half of ID), a consumer whose ID overlaps the producer's WB reads the fresh value; only the closer distances (EX/MEM, MEM/WB) need forwarding.
"Because forwarding removes the stall, it makes the clock cycle time shorter."
Wrong — forwarding adds mux delay to the EX path and may lengthen the critical cycle; it improves the cycle count (fewer stalls), not the cycle duration.
"Two dependent instructions in a row means we forward from EX/MEM in both the Rs and Rt slots."
Wrong — you forward only into the operand slot that actually names the hazarded register; Rs and Rt are checked independently, and each may or may not match the producer's Rd.
Why questions
Why do RAW hazards dominate over WAR and WAW in a classic in-order pipeline?
Because reads (ID) and writes (WB) happen in a fixed relative order for every instruction, so anti- and output-dependencies resolve naturally; only the "read-too-early" case (RAW) survives that ordering.
Why must EX/MEM forwarding take priority over MEM/WB forwarding?
When both pipeline registers hold the same destination register, EX/MEM belongs to the younger instruction that executed later in program order, and the consumer must see the latest write, not an earlier stale one.
Why can't forwarding rescue a load-use dependency without any stall?
The load's value only exists after the MEM stage, but the dependent instruction needs it at the start of its EX — that timing gap of one stage cannot be closed by routing alone, so a single bubble is unavoidable.
Why do we check the destination register against both source operands (Rs and Rt)?
An instruction like
SUB R4, R1, R1 or AND R6, R1, R7 may depend on the same producer through either input; the ALU has two operand ports, so each must be independently eligible for forwarding.Why does the hazard-detection logic exclude writes to register R0?
R0 is hardwired to zero, so a "write" to it is meaningless; forwarding a supposed R0 result would inject a bogus value where the consumer should have simply read zero.
Why does adding forwarding paths reduce CPI but complicate the datapath?
Fewer stalls means closer-to-1 cycles-per-instruction, but each forwarding path needs extra wires, wider multiplexers, and comparison logic in the forwarding unit — a classic performance-vs-hardware-cost trade (see 5.2.09-Pipeline-performance-analysis).
Why can a good compiler sometimes remove a stall that hardware would otherwise insert?
By reordering independent instructions between the producer and consumer, the compiler widens their separation so the value is already in the register file when read, dodging the load-use bubble entirely (see 6.2.03-Compiler-optimization-techniques).
Edge cases
What happens when the producer writes R0 and the consumer reads R0?
No hazard and no forwarding: R0 is constant zero, so the consumer always reads the correct value with no intervention.
What if the consumer instruction is a branch that needs the operand in ID, not EX?
The standard EX-stage forwarding arrives too late; branch operands are needed earlier, so either extra forwarding to the ID/branch-compare unit or a stall is required — a boundary that spills into 5.2.07-Control-hazardsand-branch-prediction.
What if two consecutive instructions both write the same destination register, then a third reads it?
The third must receive the second writer's value; EX/MEM (holding the second writer) takes priority over MEM/WB (holding the first), so the more recent result forwards.
What if the "producing" instruction is a store or a branch (RegWrite = 0)?
No register is written, so no forwarding fires; the
RegWrite = 1 guard in the forwarding condition suppresses any false match on leftover Rd bits.What is the minimum instruction separation at which forwarding is never needed at all?
Roughly three instructions apart (or with a split-phase register file, the point where the consumer's ID no longer precedes the producer's WB completion) — beyond that a plain register read suffices.
What happens on the very first instructions after a pipeline flush or startup, when pipeline registers hold junk?
The RegWrite/Rd validity bits in those pipeline registers are cleared (or the bubbles carry RegWrite = 0), so the forwarding unit sees no valid match and correctly forwards nothing.
Does forwarding change anything for an instruction with no source register dependencies (e.g., ADDI R1, R0, 5)?
No — with sources equal to R0 or immediates, no destination-to-source match occurs, the forwarding conditions stay false, and operands come straight from the register file/immediate field.
Recall One-line self-test
Two back-to-back ALU instructions with a true dependency: stalls needed without forwarding? With forwarding? ::: Two stalls without forwarding; zero stalls with EX/MEM forwarding.
Recall One-line self-test
A load immediately followed by a dependent ALU instruction: can forwarding alone fix it? ::: No — exactly one stall is required first, then forward from MEM/WB.