Day 89: The hazard unit: stalls and load-use
The hazard unit: stalls and load-use
Add the hazard-detection unit (Stage 1, Day 45/47): detect the load-use case — a load in EX whose destination is a source of the instruction in ID — and insert exactly one stall (freeze PC and IF/ID, inject a bubble into ID/EX). After that cycle, MEM/WB forwarding covers the dependency. This is the one stall forwarding can't avoid.
// idex.mem_read == load in EX; compare its dest to ID's sources
wire load_use = idex.mem_read &&
((idex.rd == instr_id[19:15]) || // rs1 in ID
(idex.rd == instr_id[24:20])); // rs2 in ID
assign stall = load_use; // freeze PC and IF/ID this cycle
// and inject a bubble: clear ID/EX control (nop) for one cycle
always @(posedge clk)
if (stall) idex.ctrl <= '0; // bubbleStall + bubble, together
A stall has two halves: freeze the front (hold PC and IF/ID so the dependent instruction re-decodes next cycle) and bubble the middle (turn the ID/EX control into a nop so nothing wrong commits). Doing only one causes either a lost instruction or a spurious write. Both together = one clean lost cycle, after which forwarding resolves it.
Progress for Day 89
A stall for a load-use hazard requires two coordinated actions. What are they?