§ 4.6.2. Load-Use Hazards¶
ALU forwarding removes most of the baseline's register-dependency waits. A load's data arrives one stage later, so a directly dependent instruction still needs a bubble with zero-wait data memory.
| Component | Description | Structural | Behavioral |
|---|---|---|---|
RV32IHazardDetectionUnit |
Match Decode's used sources against Execute's load destination | Yes | Yes |
IO pins¶
| Pin | Direction | Width | Description |
|---|---|---|---|
ID_VALID, EX_VALID |
Input | 1 each | Decode/Execute slot validity |
ID_RS1, ID_RS2, EX_RD |
Input | 5 each | Consumer sources and load destination |
ID_USES_RS1, ID_USES_RS2 |
Input | 1 each | Ignore encoded register fields unused by the instruction |
EX_MEM_READ |
Input | 1 | Execute instruction is a load |
LOAD_USE_HAZARD, STALL_FETCH, STALL_IF_ID, BUBBLE_ID_EX |
Output | 1 each | Same combinational hazard predicate; the coordinator applies priorities |
Behavior¶
Assert when both packets are valid, Execute is a load to a nonzero register, and Decode actually reads that register. An ordinary ALU producer, a destination of x0, or an unused encoded source does not assert it. Store data, branch operands, and JALR sources count as genuine reads.
inline bool load_use(bool id_valid,unsigned rs1,unsigned rs2,bool uses1,bool uses2,
bool ex_valid,bool ex_load,unsigned rd) {
rd&=31;rs1&=31;rs2&=31;
return id_valid&&ex_valid&&ex_load&&rd&&((uses1&&rs1==rd)||(uses2&&rs2==rd));
}
// STALL_FETCH = STALL_IF_ID = BUBBLE_ID_EX = LOAD_USE_HAZARD = load_use(...).
The detector does not stop the clock or mutate a packet. On an otherwise unblocked cycle, the coordinator holds Fetch and IF/ID, writes a bubble into ID/EX, and advances the load through EX/MEM. If an older memory request is still waiting, the whole pipeline waits first.
Example: load followed by use¶
For lw x1,0(x2); add x3,x1,x4, with zero-wait data memory:
| Current cycle | Load | Add | Ending-edge action |
|---|---|---|---|
| A | EX | ID | Hold Add in IF/ID; send load to MEM; bubble ID/EX |
| B | MEM | ID | Capture Add in ID/EX; capture loaded data in MEM/WB |
| C | WB | EX | Forward loaded value from MEM/WB into Add |
With a delayed endpoint, cycle B can repeat as memory waits. That extra delay is counted as a memory stall, not additional load-use bubbles.
Implementation¶
Structural implementation¶
Five-bit equality circuits compare both sources with EX_RD. Register-nonzero, source-use, valid and load gates qualify the result; the four outputs expose the same predicate.
Behavioral implementation¶
The direct implementation evaluates the displayed predicate after inputs settle. There is no storage or counter in this component.
Examples¶
All 7 recorded rows of RV32IHazardDetectionUnitTest, in checkpoint order. Outputs are test expectations verified against the simulation. Time is the absolute settled checkpoint time in simulator units, not milliseconds or CPU cycles.
Default scenario profile: rv32i-component-preview-preview / structural (c5b5fc4f0a8a750f). Changing fidelity or the circuit can change these times.
| Checkpointzero-based number · timeline label | Timesimulator units | EX_MEM_READInput · 1 bit |
EX_RDInput · 5 bit |
EX_VALIDInput · 1 bit |
ID_RS1Input · 5 bit |
ID_RS2Input · 5 bit |
ID_USES_RS1Input · 1 bit |
ID_USES_RS2Input · 1 bit |
ID_VALIDInput · 1 bit |
BUBBLE_ID_EXExpected output · 1 bit |
LOAD_USE_HAZARDExpected output · 1 bit |
STALL_FETCHExpected output · 1 bit |
STALL_IF_IDExpected output · 1 bit |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
#0no-valid-instructions | 9 | 1 |
0x01 |
0 |
0x01 |
0x02 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
#1rs1-load-use | 15 | 1 |
0x05 |
1 |
0x05 |
0x02 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
#2rs2-load-use | 25 | 1 |
0x06 |
1 |
0x01 |
0x06 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
#3unused-encoded-field-does-not-stall | 33 | 1 |
0x07 |
1 |
0x07 |
0x08 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
#4alu-producer-does-not-stall | 38 | 0 |
0x09 |
1 |
0x09 |
0x00 |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
#5different-register-does-not-stall | 48 | 1 |
0x0C |
1 |
0x0A |
0x0B |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
#6x0-never-stalls | 58 | 1 |
0x00 |
1 |
0x00 |
0x00 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
Scroll within the table for all rows and pins. Buses use hexadecimal; values containing X/Z use MSB-first binary. Inputs show the declared values in effect at each checkpoint, including retained inputs. Sequential tests also replay preparation changes between checkpoints, such as lowering the clock. Use the matching checkpoint label in the simulation below.
Tests¶
RV32IHazardDetectionUnitTest checks both fidelities. The shared program cases include a load-use chain and load-to-branch dependencies. RV32IAdvancedExamplesTest checks the exact C++ example against every detector row.