|
<< Click to Display Table of Contents >> Navigation: ASA-EMulatR Reference Guide > Introduction > Architecture Overview > Chapter 18 – Fault Dispatcher & Precise Exceptions > 18.6 Pipeline Fault Detection and Delivery Flow |
EMulatR implements the Alpha precise exception model through a detect-early/deliver-late pattern. Faults are detected in the Execute (EX) stage but not delivered until the faulting instruction reaches the Writeback (WB) stage. This ensures that all prior instructions have committed and no younger instruction has modified architectural state.
Detection (EX stage):
grain->execute(slot)
│
├── MBox detects: DTB miss, alignment, ACV, FOE/FOW/FOR
├── EBox detects: integer overflow, divide by zero
├── FBox detects: FP overflow/underflow/inexact/invalid/DBZ
└── Pipeline: illegal instruction, privilege violation
│
▼
slot.faultPending = true
slot.trapCode = ExceptionClass_EV6::...
slot.faultVA = faulting_address
Transit (MEM stage):
Faulting instruction flows through MEM
Pending commit preserved but may be discarded
No side effects committed for faulting instruction
Delivery (WB stage):
stage_WB() checks slot.faultPending BEFORE any commit
│
├── Discard pending commit (PendingCommit{})
├── Set PipelineAction::FAULT with trapCode/faultVA/faultPC
├── Invalidate slot
├── flushYoungerSlots() — clear all younger instructions
└── BoxResult::faultDispatched() → enterPalMode()
The key guarantee: the fault check in WB fires before any store commit or register writeback for the faulting instruction. Older instructions have already committed in prior WB cycles. Younger instructions are flushed and never commit.
Interrupts follow a different path than synchronous faults. They are sampled during the pre-cycle phase of the CPU run loop, before pipeline advancement:
AlphaCPU::runOneInstruction()
│
├── 1. Check FaultDispatcher::eventPending()
│ (delivers queued faults/traps from prior cycle)
│
├── 2. Poll IRQPendingState (if !inPalMode)
│ hasDeliverable(currentIPL) → true?
│ claimNext() → ClaimedInterrupt{source, IPL, vector}
│ break reservation
│ PalService::deliverInterrupt(claimed)
│ flush pipeline
│ return (skip instruction execution this cycle)
│
├── 3. Poll for IPIs (if !inPalMode)
│ TLB shootdown, barrier synchronization
│
└── 4. Execute pipeline stages (IF → DE → IS → EX → MEM → WB)
Interrupts are never taken mid-instruction. The interrupt check occurs at instruction boundaries, after the previous instruction has fully retired. PAL mode blocks non-critical interrupt delivery — only machine checks override PAL mode.
See Also: 13.10 Exception Precision; 7.8 Precise Exception Model; cpuCoreLib/AlphaCPU.h – runOneInstruction(), checkInterrupts().