Skip to content

§ 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-instructions9 1 0x01 0 0x01 0x02 1 1 0 0 0 0 0
#1rs1-load-use15 1 0x05 1 0x05 0x02 1 0 1 1 1 1 1
#2rs2-load-use25 1 0x06 1 0x01 0x06 0 1 1 1 1 1 1
#3unused-encoded-field-does-not-stall33 1 0x07 1 0x07 0x08 0 0 1 0 0 0 0
#4alu-producer-does-not-stall38 0 0x09 1 0x09 0x00 1 0 1 0 0 0 0
#5different-register-does-not-stall48 1 0x0C 1 0x0A 0x0B 1 1 1 0 0 0 0
#6x0-never-stalls58 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.