|
<< Click to Display Table of Contents >> Navigation: ASA-EMulatR Reference Guide > Introduction > Architecture Overview > Chapter 13 – AlphaPipeline Implementation > 13.10 Exception Precision |
Exceptions are detected early (in EX) but delivered late (in WB). When a fault is detected in stage_EX(), slot.faultPending is set to true with the trapCode and faultVA. The instruction continues flowing through MEM (where its pending commit is preserved but may be discarded). When the faulting instruction reaches stage_WB(), the fault check fires first — before any store commit or retirement.
Why not deliver immediately in EX? Because older instructions in MEM and WB must complete first. Delivering in WB guarantees that the faulting instruction is the oldest incomplete instruction — all prior instructions have already retired.
On fault in stage_WB: the m_pending (from a younger instruction in MEM) is discarded (PendingCommit{}), PipelineAction::FAULT is set with trapCode/faultVA/faultPC, and the slot is invalidated. The fault propagates to AlphaCPU via BoxResult::faultDispatched(), which triggers enterPal() with EXC_ADDR set to the faulting instruction's PC.
flushYoungerSlots() clears all instructions younger than the faulting instruction — preserving older instructions that have already committed. This guarantees precise exceptions: all prior instructions completed, no later instruction modified architectural state.
Fault precedence: If multiple slots have faultPending set simultaneously, slotSequence (the monotonic age counter) determines which fault is architecturally first. Only the oldest faulting instruction's exception is delivered; younger faulting instructions are discarded by flushYoungerSlots().
The following invariants hold for every exception delivery and are verified by the testing framework (Chapter 22):
No younger instruction commits. flushYoungerSlots() is called before the fault propagates. Any younger instruction that reached MEM has its PendingCommit discarded — its register write never takes effect.
All prior instructions completed. Because WB processes in age order (oldest first, guaranteed by in-order retirement), every instruction older than the faulting instruction has already retired before the fault check executes.
Faulting stores never reach SafeMemory. Stores commit in stage_WB() after the fault check. Since the fault check fires first and returns immediately, the store commit path is never reached for a faulting instruction.
Faulting loads never write the result register. Load results sit in slot.payLoad and m_pending until commitPending() in stage_MEM(). If the load faulted, the pending commit is discarded in stage_WB() before the next MEM cycle could commit a younger instruction's result.
LL/SC reservations cleared on delivery. Exception delivery clears all LL/SC reservations for the faulting CPU, ensuring no stale reservation survives across a fault boundary.
See Also: 11.2 Execution and Pipeline Invariants ; Chapter 18 – Fault Dispatcher & Precise Exceptions ; Chapter 22 – Testing, Validation, and Architectural Compliance (exception precision verification).