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
pre_reset_phase — wait for power-good, clocks stable before reset.
reset_phase — assert/deassert reset; drive interfaces to safe idle.
post_reset_phase — settle period after reset deassertion.
pre_configure_phase — prepare for DUT/register configuration.
configure_phase — program registers, set up DUT (often via RAL).
post_configure_phase — let configuration propagate through DUT.
pre_main_phase — final readiness checks before main traffic.
main_phase — primary stimulus and checking.
post_main_phase — wind down main traffic gracefully.
pre_shutdown_phase — prepare components for stop.
shutdown_phase — drain in-flight transactions.
post_shutdown_phase — final settle before cleanup function phases.
[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 parallel12 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.
[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// 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
endclassUnoverridden 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:
[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// 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
endclassrun_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.
[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 traceKey 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.