Question bank — Hazard detection units
Before the questions, this page builds every piece of vocabulary it uses from scratch. Read this setup once; the whole bank rests on it.
The five lanes (pipeline stages)
Picture the pipeline as five lanes, and an instruction sliding one lane to the right every clock tick:
- IF — instruction fetch: grab the next instruction from memory.
- ID — instruction decode: figure out what it is and read its source registers.
- EX — execute: the ALU does the arithmetic.
- MEM — memory: touch data memory (only loads and stores do real work here).
- WB — write-back: write the result into the register file.
Pipeline registers (the ID/EX-style names)
Between each pair of lanes sits a pipeline register — a latch that carries an instruction's data from one stage into the next at every clock edge. They are named by the two stages they sit between:
A field inside such a register is written with a dot: ID/EX.MemRead means "the MemRead control bit of whatever instruction is currently in EX".
Register fields Rs, Rt, Rd
Every MIPS instruction names up to three registers by number:
The control signals used in this bank
Where a bubble comes from — the control mux
Forwarding vs. stalling (the two cures)
- Forwarding = a shortcut wire that carries a freshly-computed value backward to an instruction that needs it now, instead of waiting for it to reach the register file. Handled by the forwarding unit out of EX/MEM or MEM/WB.
- Stall = freezing the front of the pipeline for one tick and injecting a bubble so a not-yet-ready value has time to appear.
The load-use detection condition, spelled out
Every stall in this bank comes from one Boolean expression. Here it is fully written:
Why exactly one bubble is enough
Trace the load lw and its consumer add, tick by tick, with a bubble inserted:
| Cycle | IF | ID | EX | MEM | WB |
|---|---|---|---|---|---|
| 1 | lw |
— | — | — | — |
| 2 | add |
lw |
— | — | — |
| 3 | add |
bubble | lw |
— | — |
| 4 | … | … | bubble | lw |
— |
| 5 | … | add |
… | bubble | lw |
In cycle 3 the hazard unit detects lw in EX and add in ID, so it freezes add (holds it in ID) and injects a bubble. By cycle 5 the load's value has reached MEM/WB, which is exactly a stage the forwarding unit can bypass from into add's EX. One bubble is the minimum delay that lifts the load into a forwardable position — hence exactly one suffices.
The hazard detection unit only ever fires when forwarding cannot save you. That single sentence is the key that unlocks most of these traps.
True or false — justify
The forwarding unit and the hazard detection unit are the same block of logic
Every data hazard forces a pipeline stall
The hazard detection unit lives in the EX stage where the ALU is
Rs, Rt) are decoded. Detecting the dependency in ID lets us stall before EX ever consumes a stale value.The hazard detection unit must be combinational, not clocked
A load-use stall of one bubble is always enough for the dependent instruction to get correct data
Flushing an instruction and stalling an instruction are the same operation
Writing to register 0 in MIPS can create a false load-use hazard
Rd != 0 check. Register 0 is hardwired to zero; a "dependency" on it is meaningless, so treating it as a hazard would insert pointless bubbles.WAR and WAW hazards are common in the simple 5-stage in-order pipeline
Structural hazards can be detected by the same load-use comparison logic
Resolving branches in the ID stage instead of EX reduces the number of instructions we must flush
Spot the error
Claim: "We forward the load's result straight from the ID/EX register into the next instruction's ALU, so no stall is ever needed." — what's wrong?
Claim: "On a stall we set PCWrite = 1 so the PC keeps moving." — what's wrong?
PCWrite = 0 (the freeze setting from the definitions above). If the PC advanced during the stall we'd fetch and then lose the next instruction. Freezing the PC and IF/ID is what makes the front of the pipe wait.Claim: "To insert a bubble we freeze the ID/EX control signals so they hold their old value." — what's wrong?
Claim: "During a load-use stall we hold the load instruction in ID." — what's wrong?
Claim: "A flush after a taken branch just requires setting Stall = 1." — what's wrong?
Claim: "The detection condition only checks Rs, since that's the first operand." — what's wrong?
MemRead with an OR over both Rs and Rt, because the dependent instruction could read the load's destination through either source operand. Missing Rt would let a real hazard slip past on second-operand dependencies.Claim: "Since forwarding handles EX/MEM and MEM/WB hazards, the hazard unit can check those too and skip the load case." — what's wrong?
Why questions
Why does the hazard detection unit specifically watch ID/EX.MemRead rather than the opcode?
MemRead = 1 is the clean, decoded flag that identifies a load — the only instruction whose result isn't ready by end of EX. Watching one control bit is cheaper and faster than re-decoding the opcode inside the hazard unit.Why must the stall decision finish inside a single clock cycle?
Why is forwarding preferred over stalling whenever it's possible?
Why does moving branch resolution earlier (into ID) need extra hardware, and is it worth it?
Why can't the hazard detection unit alone eliminate all pipeline stalls?
Why does the control-signal path need a mux that can force all signals to zero?
Why is branch prediction (5.2.11-Branch-prediction) a complement to, not a replacement for, control-hazard flush logic?
Edge cases
If the load's destination register equals the dependent instruction's Rs and Rt (both operands), how many bubbles are inserted?
What happens if the instruction after a load reads a different register than the load's Rd?
Rd == Rs / Rd == Rt comparison fails, so Stall = 0 and the pipeline runs at full speed. The mere presence of a load nearby is harmless without a matching register.A load is followed by a store that uses the loaded value as its data-to-store — is it still a load-use hazard?
Rd through Rt (the store-data register). The consumer being a store doesn't change the timing: the value still isn't ready, so a stall is required just the same.What if a taken branch is immediately followed by another branch on the wrong path?
A branch is resolved in ID and turns out not taken — what does the hazard unit do?
Flush = Branch AND BranchTaken evaluates false and no bubble is inserted.Two independent loads back-to-back, where the second instruction after the first load uses the value — is a stall needed?
If ID/EX.MemRead = 1 but the loaded value is never used by any following instruction, does the unit stall?
Rs or Rt, the detection condition is false. A load with no dependent consumer flows through with zero penalty — the unit reacts to dependencies, not to loads themselves.Recall One-line summary to lock it in
The hazard detection unit stalls only for the load-use case (value not yet produced), flushes only for wrong-path branch instructions, and stays silent whenever the forwarding unit can already reroute the data.