Commit b30e7db
fix(load_unit): move flush_i branch after ldbuf_w to prevent phantom writeback (#3309)
In ldbuf_comb the flush_i "set-all-flushed" branch appeared before the
ldbuf_w "allocate-slot" branch. When both are asserted in the same cycle
(ldbuf_w = data_req & data_gnt, flush_i = flush_ex_o from controller), the
allocation write wins for the new slot via lexical last-assignment semantics:
if (flush_i) ldbuf_flushed_d = '1; // (a)
...
if (ldbuf_w) ldbuf_flushed_d[windex] = 1'b0; // (b) overrides (a) for windex
Result: flushed_q[windex]=0, valid_q[windex]=1 — a slot that survived the
flush. When data_rvalid arrives N cycles later the FSM is in IDLE
(kill_req=0) and ldbuf_flushed_q[slot]=0, so valid_o=1. The flushed load's
result is forwarded to scoreboard writeback with a potentially recycled
trans_id, corrupting an unrelated instruction's result.
Trigger: an exception or fence commits (flush_ex_o=1 → flush_i=1) while the
load unit is in WAIT_GNT and the dcache arbiter grants the same cycle.
A concrete sequence: an older store faults (store page-fault) at the commit
head while a younger speculative load has been held in WAIT_GNT waiting for
the dcache arbiter. If the arbiter grants on the same cycle the fault
commits, flush_i and data_gnt are simultaneously high.
Fix: move if (flush_i) to after if (ldbuf_w) so the flush unconditionally
wins for every slot, including the one just allocated.
Verified with a standalone Verilator simulation of the isolated ldbuf_comb /
ldbuf_ff logic. Pre-fix: valid_o=1 on rvalid (BUG-CONFIRMED).
Post-fix: valid_o=0 (correctly suppressed).
Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>1 parent a31b556 commit b30e7db
1 file changed
Lines changed: 9 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
156 | 156 | | |
157 | 157 | | |
158 | 158 | | |
159 | | - | |
160 | | - | |
161 | | - | |
162 | | - | |
163 | 159 | | |
164 | 160 | | |
165 | 161 | | |
| |||
170 | 166 | | |
171 | 167 | | |
172 | 168 | | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
173 | 178 | | |
174 | 179 | | |
175 | 180 | | |
| |||
0 commit comments