Skip to content

lsu: don't start a misaligned spill when the access faults - #1986

Merged
rosethompson merged 3 commits into
openhwfoundation:mainfrom
davidharrishmc:dh/spill-fault-defer
Oct 16, 2026
Merged

rosethompson merged 3 commits into
openhwfoundation:mainfrom
davidharrishmc:dh/spill-fault-defer

Conversation

@davidharrishmc

Copy link
Copy Markdown
Contributor

A page-crossing misaligned store whose first half faults can retire with no trap and only its second half written: while a committed I$ fill defers the trap, the align FSM advances to the second-half address, and the fault, recomputed combinationally from the address, vanishes. This gates ValidSpillM with the access's page and access faults so a faulting access keeps presenting the original address until the trap is taken. The new tests/coverage/spillfaultdefer.S sweeps the faulting store across an I$ line with cold caches and TLB; it fails on main at one alignment (fault missed, second half written) and passes with the fix.

🤖 Generated with Claude Code

A page-crossing misaligned store whose first half faults could retire with
no trap and only its second half written: while a committed I$ fill deferred
the trap, the align FSM advanced to the second-half address and the fault,
recomputed combinationally from the address, vanished.  Gate ValidSpillM
with the access's page and access faults so a faulting access keeps
presenting the original address until the trap is taken.

Add tests/coverage/spillfaultdefer.S, which sweeps the faulting store across
an I$ line with cold caches and TLB; it fails on main at one alignment with
the fault missed and the second half written.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@davidharrishmc

Copy link
Copy Markdown
Contributor Author

Review notes: one more fault class should gate the spill.

  • DataFaultM (lsu.sv:175) lists LoadPageFaultM | StoreAmoPageFaultM | LoadAccessFaultM | StoreAmoAccessFaultM but not LoadMisalignedFaultM | StoreAmoMisalignedFaultM. Those are recomputed per address too: MisalignedFaultAllowedM = ~Cacheable & ~TLBMiss & Idempotent & ~Atomic (mmu.sv:150) depends on the current address's PBMT, PMA and TLB hit, so they can vanish the same way. Scenario, under the same CommittedF deferral: a line- and page-crossing misaligned sd from an Svpbmt=NC page (misaligned fault on the first half) into a cacheable page. ValidSpillM is still 1, the FSM advances to the second-half address, the misaligned fault disappears, and the second half is written without a trap. I traced this statically; it isn't simulated.
  • Fix: mirror SelfFaultM's term list (lsu.sv:309-310), which already includes both misaligned faults. This creates no loop: the misaligned faults depend on the registered SelSpillM, PMA and TLB, not on ValidSpillM.
  • The added fault → ValidSpillM → SelSpillE → IEUAdrSpillE path feeds the next cycle's D$ index; one rv64gc TSMC28 synthesis comparison would confirm it doesn't lengthen the critical path.
  • spillfaultdefer.S fails on main at only one I$ alignment, so a future timing change could make it pass vacuously. A comment naming the failing trial would help.

🤖 Generated with Claude Code

@davidharrishmc

Copy link
Copy Markdown
Contributor Author

Merge order: this is the LSU counterpart of #1982 (IFU: no spill on a first-half fault). Merge the two together. They merge cleanly.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@davidharrishmc

Copy link
Copy Markdown
Contributor Author

Follow-up on the review notes:

  • Misaligned faults in DataFaultM: not needed. With Zicclsm, a misaligned fault requires ~Cacheable (mmu.sv:150), so the faulting half is an uncached bus access. Its BusRW (lsu.sv:358) is not gated by SelfFaultM, and busfsm.sv:78 asserts BusStall in ADR_PHASE whenever BusRW is set, even while Flush holds the FSM. CacheBusHPWTStall therefore stays high and ValidSpillM stays 0 until the trap is taken. The only path without that stall is DTIM (BusRW gated by ~SelDTIM), but the align unit needs a D$ (MISALIGN_SUPPORT), and no config or derivative has both a DTIM and a D$ with Zicclsm. A copy of spillfaultdefer.S whose first half is on a Svpbmt NC page and whose second half is on a cacheable page takes all 32 misaligned faults and writes nothing, on both main and this PR, with no lockstep mismatches. So no change.
  • Test comment. spillfaultdefer.S now names the trial that fails without the fix: trial 22 (the sd at byte 0x34 of its I$ line), which fails check 22 on main both alone and in the full sweep and passes with the fix.

🤖 Generated with Claude Code

Comment thread src/lsu/lsu.sv Outdated
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@rosethompson
rosethompson merged commit 8ac1fee into openhwfoundation:main Oct 16, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants