Part 2 · Phases & Lifecycle · Intermediate

The Shared Timeline Contract: What Every Component Agrees To

The implicit agreement all uvm_component derivatives sign — phase callback names, ordering, zero-time vs time-consuming rules, and completion via objections.

The contract in one view

Every uvm_component implicitly agrees to a fixed phase schedule and method signatures. The library calls them; user code fills them in.

diagram
[UVM][PHASE] shared timeline contract

BUILD-TIME (function, 0 time):
  build -> connect -> end_of_elaboration -> start_of_simulation

RUN-TIME (task, may consume time):
  run_phase || 12 runtime sub-phases

CLEANUP (function, 0 time):
  extract -> check -> report -> final

completion rule:
  run ends when objection count hits zero (+ drain_time)
  • Function phases: structure, config, checks, reporting — no time control.

  • Task phases: stimulus, sampling, parallel runtime schedule.

  • Objections: distributed vote on 'may we leave run-time yet?'

Key takeaways

  • The contract is the API that makes VIPs composable across projects.

  • Violating phase placement breaks guarantees for every neighbor in the tree.

  • Objections replace integrator-written completion delays.

Common pitfalls

  • Treating run_phase as optional — it is where time-consuming work lives.

  • Skipping super calls — silently breaks base-class bookkeeping.

  • Ending run without objections — simulation may exit at time 0.


Contract obligations by role

Test / env authors

  1. Push config and virtual interfaces before children build.

  2. Register factory overrides before the create they affect.

  3. Raise/drop objections around scenario stimulus in run_phase.

  4. Aggregate pass/fail in check/report phases.

Agent / VIP authors

  1. Create children only in build_phase via factory.

  2. Connect only in connect_phase with null-safe config gating.

  3. Never consume time in function phases.

  4. Document which objections the VIP expects from the integrator.

systemverilog
task run_phase(uvm_phase phase);
  super.run_phase(phase);
  if (cfg.is_active) begin
    phase.raise_objection(this, "agent active");
    fork
      driver_forever();
      monitor_forever();
    join
    phase.drop_objection(this, "agent done");
  end
endtask
diagram
[PHASE] contract compliance signals

good:
  print_topology shows expected hierarchy after build
  connect logs show bottom-up order
  +UVM_OBJECTION_TRACE shows balanced raise/drop

bad:
  components appear only in run_phase logs
  instant test finish at 0ns
  hang with objections never reaching zero

Key takeaways

  • Roles differ in what they create, but all share the same phase schedule.

  • VIP documentation should state objection expectations explicitly.

  • Phase trace plus objection trace validates contract compliance quickly.

Common pitfalls

  • Env authors driving pins directly instead of delegating to agents.

  • VIPs that start threads in start_of_simulation instead of run_phase.

  • Tests that drop objections before sequences complete.