Part 2 · Phases & Lifecycle · Intermediate

Phase Timeline Map: Build, Run, and Cleanup on One Axis

A single left-to-right map of simulation progress through build-time, run-time, and cleanup phases, including parallel runtime sub-phases.

The master timeline

diagram
[UVM][PHASE] simulation timeline (left = earlier)

|-- BUILD-TIME (function, Δt=0) ----------------|
| build -> connect -> end_of_elab -> start_sim  |
|                                               |
|-- RUN-TIME (task, Δt>0) ----------------------|
| run_phase =====================================|
|   || pre_reset -> reset -> post_reset         |
|   || pre_configure -> configure -> post_cfg   |
|   || pre_main -> main -> post_main            |
|   || pre_shutdown -> shutdown -> post_shutdown|
|                                               |
|-- CLEANUP (function, Δt=0) -----------------|
| extract -> check -> report -> final           |

The double line under run_phase indicates it runs

in parallel with the 12 runtime sub-phases. Objections determine when the entire run-time block ends.

Key takeaways

  • Keep this diagram accessible — every phase lesson expands one segment.

  • Build and cleanup are zero-time barriers between run-time and structural setup/teardown.

  • Runtime sub-phases provide reset/configure/main/shutdown schedule inside run.

Common pitfalls

  • Thinking run_phase finishes before reset sub-phase — they overlap by design.

  • Placing main stimulus in pre_reset because 'it is still run_phase'.

  • Skipping cleanup phases in bring-up — lose structured pass/fail reporting.


Mapping work to timeline segments

Build-time strip

  • Factory create and config_db distribution.

  • TLM topology wiring.

  • Structural validation before time advances.

systemverilog
function void start_of_simulation_phase(uvm_phase phase);
  super.start_of_simulation_phase(phase);
  `uvm_info("SIM", $sformatf("seed=%0d", $get_initial_random_seed()), UVM_LOW)
endfunction

Run-time strip

systemverilog
task run_phase(uvm_phase phase);
  super.run_phase(phase);
  phase.raise_objection(this, "main");
  // reset waits belong here or in reset sub-phase callbacks
  seq.start(sqr);
  phase.drop_objection(this, "main done");
endtask
diagram
[PHASE][RUN] parallel lanes

Lane A: component run_phase tasks
Lane B: runtime schedule (12 sub-phases)

scheduler waits until:
  all tasks done AND objections balanced AND drain_time elapsed

Cleanup strip

  • extract: pull coverage, counters, scoreboard stats.

  • check: uvm_error if predicates fail.

  • report: formatted summary for humans and CI.

  • final: close resources.

Key takeaways

  • If you know where you are on the timeline, phase placement errors become obvious.

  • Run-time has two parallel mechanisms — run_phase and sub-phases.

  • Cleanup is not optional decoration — it is the regression contract output.

Common pitfalls

  • Reporting pass/fail only via $display in run_phase.

  • Extracting coverage in report_phase when check needs it earlier.

  • Starting sequences in start_of_simulation — zero-time phase.