2.4 Execution Phases per Cycle

<< Click to Display Table of Contents >>

Navigation:  ASA-EMulatR Reference Guide > Introduction > Architecture Overview > Chapter 2 - Execution Model >

2.4 Execution Phases per Cycle

Each cycle consists of the following conceptual phases. These phases are descriptive of the architectural contract; their implementation may overlap within the tick() method.

 

2.4.1 Pre-Cycle Checks

 

Before advancing the pipeline, the run loop evaluates conditions that may prevent or alter execution:

Halt or shutdown requests

Pending interrupts — checked via m_pending->hasDeliverable(currentIPL)

Pending exceptions

Debugger intervention (breakpoints, single-step)

 

If a halt condition is detected, the run loop exits cleanly. Interrupts and exceptions are only taken when architecturally enabled, safe to deliver (no higher-priority condition active), and the pipeline state allows precise delivery.

 

In the implementation, interrupt checking is the first action in runOneInstruction(). If a deliverable interrupt exists at the current IPL, handleInterrupt() is called and the method returns immediately — no pipeline advancement occurs that cycle.

 

// 1. Check for external events (interrupts)

if (m_pending->hasDeliverable(m_iprGlobalMaster->h->getIPL())) {

 handleInterrupt();

 return;

}

 


 

2.4.2 Pipeline Advancement

 

The pipeline advances one stage per cycle, subject to stalls. Pipeline advancement is the primary source of forward progress.

 

Key properties:

Stages execute from oldest to youngest (WB → MEM → EX → IS → DE → IF)

Slots may advance, stall, or be flushed

No architectural state is committed outside WB

The ring buffer is rotated (advanceRing) after all stages have executed

 

In the implementation, AlphaCPU calls m_iBox->fetchNext() to obtain a FetchResult, then passes it to m_alphaPipeline->tick(). The tick() method calls execute() which runs all six stages in reverse order, then advances the ring buffer and increments the cycle counter.

 

// 2. Fetch and decode

FetchResult fetchResult = m_iBox->fetchNext();

 

// 3. Supply to pipeline

BoxResult boxResult = m_alphaPipeline->tick(fetchResult);

 


 

2.4.3 Barrier and Serialization Evaluation

 

After advancement, the run loop evaluates whether any stalled serialization conditions may be released:

Memory barriers (MB, WMB) — release when write buffers are drained

Exception barriers (EXCB) — release when all prior exceptions are resolved

Trap barriers (TRAPB) — release when all prior traps are resolved

PAL entry/exit serialization — release after HW_REI completes

 

Barriers block frontend fetch and speculative execution until their release conditions are satisfied. The CBox manages barrier state and coordinates with the WriteBufferManager for drain conditions.

 


 

2.4.4 Branch Resolution

 

Branch outcomes are resolved once their execution reaches the appropriate pipeline stage. Branches are predicted in stage_IF(), resolved in stage_EX(), and the branch predictor is updated in stage_WB().

 

If a misprediction is detected:

Younger pipeline slots are flushed

The program counter is redirected to the correct target

Execution resumes from the corrected address

 

The BranchPredictor (owned by CBox) provides prediction services and is updated on branch retirement at the WB stage.

 


 

2.4.5 Exception and Interrupt Delivery

 

If exceptions or interrupts are pending and deliverable:

The pipeline is flushed

Architectural state is preserved precisely

The faulting PC is saved to the EXC_ADDR IPR

The fault vector is computed from PAL_BASE + offset

The PC is redirected to the PAL handler entry point

LL/SC reservations are broken via m_reservationManager->breakReservation(m_cpuId)

Write buffers may be drained if required by the exception class

 

Exception delivery always preserves precise exception semantics. The next iteration of runOneInstruction() fetches from the PAL handler address and executes PAL code naturally through the normal pipeline — there is no special PAL execution path.

 


 

2.4.6 State Updates and Housekeeping

 

At the end of the cycle:

The pipeline cycle counter (m_cycleCount) is incremented

Performance counters may be updated

Pipeline debug summaries are logged periodically (every 500 cycles)

SMP coordination events may be processed

Debugger hooks and trace macros (EXECTRACE) are evaluated

 

See Also: Chapter 3 - Pipeline Architecture (stage detail); Chapter 7 - Exceptions, Faults, and Interrupts; Chapter 6 - Serialization and Stall Model.