Part 2 · Phases & Lifecycle · Intermediate

The 12-Phase Schedule: Complete Ordered List

Every runtime sub-phase in order, scheduler traversal rules, parallel-within-group semantics, and how the schedule relates to run_phase.

The complete list

  1. pre_reset_phase — wait for power-good, clocks stable before reset.

  2. reset_phase — assert/deassert reset; drive interfaces to safe idle.

  3. post_reset_phase — settle period after reset deassertion.

  4. pre_configure_phase — prepare for DUT/register configuration.

  5. configure_phase — program registers, set up DUT (often via RAL).

  6. post_configure_phase — let configuration propagate through DUT.

  7. pre_main_phase — final readiness checks before main traffic.

  8. main_phase — primary stimulus and checking.

  9. post_main_phase — wind down main traffic gracefully.

  10. pre_shutdown_phase — prepare components for stop.

  11. shutdown_phase — drain in-flight transactions.

  12. post_shutdown_phase — final settle before cleanup function phases.

diagram
[PHASE][RUN] full runtime timeline

  │ pre_reset │ reset │ post_reset │
  │ pre_cfg   │ cfg   │ post_cfg   │
  │ pre_main  │ main  │ post_main  │
  │ pre_shut  │ shut  │ post_shut  │
  └───────────┴───────┴────────────┘
       sequential groups left  right
       within each cell: all components run in parallel
  • 12 phases = 4 groups × 3 phases (pre, core, post) per group.

  • Groups execute sequentially; phases within a group execute in order.

  • All are task phases — they consume simulation time.


Scheduler behavior

The UVM phase scheduler processes runtime sub-phases sequentially across groups , but within each phase all components that override that phase run in parallel — identical to run_phase parallelism.

diagram
[UVM][PHASE] scheduler traversal

  for each runtime phase P in [pre_reset ... post_shutdown]:
    invoke P on all components (parallel)
    wait until P objections drain to 0
    advance to next phase

  after post_shutdown completes  extract_phase begins
systemverilog
// Component overrides only the phases it needs
class my_agent extends uvm_agent;
  task reset_phase(uvm_phase phase);
    // runs during reset_phase only
  endtask
  task configure_phase(uvm_phase phase);
    // runs after ALL components finish reset group
  endtask
  task main_phase(uvm_phase phase);
    // runs after ALL components finish configure group
  endtask
  // unoverridden phases: default empty task from uvm_component base
endclass
  • Unoverridden runtime phases are no-ops — zero cost if you don't use them.

  • A component can override any subset — not required to implement all 12.

  • The scheduler waits for ALL components to finish phase P before starting P+1.


Relationship to run_phase

run_phase and the 12 runtime sub-phases occupy the same simulation time window. They are scheduled independently but concurrently:

diagram
[PHASE][RUN] parallel schedules

  run_phase:           ═══════════════════════════════════════►
  pre_reset:           ───►
  reset:                   ───►
  post_reset:                  ───►
  pre_configure:                     ───►
  configure:                             ───►
  ...
  post_shutdown:                                              ───►

  run_phase spans the entire window
  sub-phases occupy sequential slices within it
systemverilog
// CORRECT: agent uses sub-phases, run_phase is super-only
class subphase_agent extends uvm_agent;
  task run_phase(uvm_phase phase);
    super.run_phase(phase);  // no direct activity
  endtask
  task main_phase(uvm_phase phase);
    phase.raise_objection(this);
    run_traffic();
    phase.drop_objection(this);
  endtask
endclass

// WRONG: same component does work in both
class mixed_agent extends uvm_agent;
  task run_phase(uvm_phase phase);
    run_traffic();  // ← conflicts with main_phase below
  endtask
  task main_phase(uvm_phase phase);
    run_traffic();  // ← double execution
  endtask
endclass
  • run_phase continues across the entire runtime window even while sub-phases advance.

  • If using sub-phases, leave run_phase as super-only in that component.

  • Tests can use run_phase for top-level coordination while agents use sub-phases.


Enabling runtime sub-phases

Runtime sub-phases are part of the default UVM phase schedule — no special enable needed. However, your testbench must actually override the relevant phase methods for them to do anything useful.

diagram
[UVM][PHASE] adoption checklist

  □ Identify which groups each agent needs (usually reset + main minimum)
  □ Move reset-wait logic from run_phase  reset_phase
  □ Move register programming  configure_phase
  □ Move stimulus loop  main_phase
  □ Move drain logic  shutdown_phase
  □ Set run_phase to super-only in converted components
  □ Verify group transitions with phase trace

Key takeaways

  • 12 phases in 4 groups: reset, configure, main, shutdown — each with pre/core/post.

  • Scheduler runs phases sequentially; components within a phase run in parallel.

  • run_phase and sub-phases share the time window — pick one model per component.

  • Override only the sub-phases you need; unoverridden ones are no-ops.

Common pitfalls

  • Assuming sub-phases replace run_phase globally — they run concurrently, not instead.

  • Implementing all 12 when only reset_phase and main_phase are needed — unnecessary.

  • Expecting configure_phase at time 0 — reset group must complete first.

  • Activity in run_phase AND main_phase in same component — double execution.