Skip to content

Commit 8beff79

Browse files
committed
forwarding_unit: fix stale cache-hit load data in int->fp forwarding
Use MA-stage load data as the single source of truth for dependent load forwarding into int->fp conversions and MA bypass paths. Root cause: - On cache-hit load dependencies, forwarding selected i_from_cache.data_loaded_from_cache_reg. - That registered cache value can be stale relative to the current MA load result, causing incorrect operands for dependent fcvt.d.w operations. Fix: - Set int_capture_bypass_data to i_from_ma_comb.data_loaded_from_memory. - For forward_data_ma cache-hit forwarding, use i_from_ma_comb.data_loaded_from_memory instead of i_from_cache.data_loaded_from_cache_reg. - Keep cache-hit dependency detection logic, but source forwarded data from MA. Validation: - test_run_cocotb.py --sim verilator cpu --random-seed=1772418093 - CPU cocotb regression summary: TESTS=21 PASS=21 FAIL=0
1 parent af53f90 commit 8beff79

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

hw/rtl/cpu_and_mem/cpu/control/forwarding_unit.sv

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,16 +134,30 @@ module forwarding_unit #(
134134

135135
// Int -> FP capture bypass: when a load-use hazard is detected and the
136136
// current EX instruction is int->fp, feed MA load data directly so the
137-
// FPU captures the correct operand at the stall edge.
137+
// FPU captures the correct operand at the EX-entry edge.
138+
// For cache-hit paths, use MA load data (same value that WB sees) rather
139+
// than the cache-forward register to avoid stale-cache forwarding.
138140
logic int_capture_bypass_valid;
141+
logic int_capture_bypass_from_cache;
142+
logic int_capture_dep_match;
139143
logic [XLEN-1:0] int_capture_bypass_data;
144+
assign int_capture_dep_match =
145+
(i_from_ex_to_ma.instruction.dest_reg != 0) &&
146+
(i_from_ex_to_ma.instruction.dest_reg ==
147+
i_from_id_to_ex.instruction.source_reg_1);
148+
149+
assign int_capture_bypass_from_cache =
150+
i_from_cache.cache_hit_on_load_reg &&
151+
i_from_ex_to_ma.is_load_instruction &&
152+
i_from_id_to_ex.is_int_to_fp &&
153+
int_capture_dep_match;
154+
140155
assign int_capture_bypass_valid =
141156
i_pipeline_ctrl.load_use_hazard_detected &&
142157
i_from_ex_to_ma.is_load_instruction &&
143158
i_from_id_to_ex.is_int_to_fp &&
144-
(i_from_ex_to_ma.instruction.dest_reg != 0) &&
145-
(i_from_ex_to_ma.instruction.dest_reg ==
146-
i_from_id_to_ex.instruction.source_reg_1);
159+
int_capture_dep_match ||
160+
int_capture_bypass_from_cache;
147161

148162
assign int_capture_bypass_data = i_from_ma_comb.data_loaded_from_memory;
149163

0 commit comments

Comments
 (0)