13.6 Stage Implementations

<< Click to Display Table of Contents >>

Navigation:  ASA-EMulatR Reference Guide > Introduction > Architecture Overview > Chapter 13 – AlphaPipeline Implementation >

13.6 Stage Implementations

13.6.1 stage_IF() — Instruction Fetch

 

Consumes the FetchResult from m_pendingFetch (supplied by IBox via supplyFetchResult()). Transfers the decoded instruction (DecodedInstruction + grain pointer) into the IF-stage slot. Assigns monotonic sequence number (m_nextSequence++). Sets slot.valid = true, slot.cycle = m_cycleCount. No execution occurs here.

 

13.6.2 stage_DE() — Decode

 

Mostly a pass-through — the grain was pre-decoded in IBox during fetch. Future: could detect early hazards here.

 

13.6.3 stage_IS() — Issue

 

Mostly a pass-through — hazard checks are now performed in boxes during EX. Future: could handle dual-issue logic here.

 


 

13.6.4 stage_EX() — Execute (Critical Stage)

 

All instruction semantics occur here. The implementation:

 

Early exits: if (!slot.valid || slot.stalled || slot.faultPending) return.

 

Illegal instruction check: if (!slot.grain) → set faultPending, trapCode = ILLEGAL_INSTRUCTION, return.

 

Grain execution: slot.grain→execute(slot) — the grain calls EBox, FBox, MBox, CBox, or PalBox as needed, performs arithmetic/logical work, executes memory accesses, detects exceptions, sets stall or serialization flags, and produces result payload in slot.payLoad.

 

Branch/jump misprediction detection: after execution, if isBranchOrJump and branchTaken, compare actualTarget vs predictedTarget. If mispredicted, set slot.flushPipeline = true.

 

Multi-cycle operations block EX until complete.

 


 

13.6.5 stage_MEM() — Register Writeback + Stall Check

 

Despite the name, no memory access occurs here (memory was accessed in EX via MBox). stage_MEM() has two responsibilities:

 

Register writeback: commitPending(slot) writes deferred register results from the PendingCommit structure. For integer results: slot.writeIntReg(destReg, value), then m_eBox→clearDirty(reg). For FP results: slot.writeFpReg(destReg, value), then m_fBox→clearDirty(reg).

 

Stall check: if needsMemoryBarrier and !memoryBarrierCompleted → stall. If needsWriteBufferDrain and !writeBufferDrained → stall. This is where barrier instructions block the pipeline until CBox confirms completion.

 


 

13.6.6 stage_WB() — Store Commit and Retirement

 

WB is the architectural commit point. Execution order within stage_WB:

 

1. Fault check — if slot.faultPending: discard m_pending (younger instruction squashed), set PipelineAction::FAULT with trapCode/faultVA/faultPC, return immediately. The fault propagates to AlphaCPU via BoxResult::faultDispatched().

 

2. CALL_PAL check — if isCallPal(slot.di): discard m_pending (pipeline serializes), compute PAL entry vector via computeCallPalEntry(), set PipelineAction::PAL_CALL, return.

 

3. Store commit — if slot has store semantics (S_Store): m_guestMemory→write64(slot.pa, slot.payLoad), then m_reservationManager→breakReservationsOnCacheLine(slot.pa).

 

4. Branch predictor update — if branchTaken: m_cBox→updatePrediction(pc, taken, target).

 

5. Retirement — commitInstruction(slot): increment m_instructionsRetired, update m_totalCycles, emit EXECTRACE_WB_RETIRE.

 

6. Cleanup — slot.valid = false, slot.clear().

 

Note: registers were already written in stage_MEM — WB only commits stores and retires.

 

See Also: cpuCoreLib/AlphaPipeline.h (stage implementations lines 860–1430).