Part 2 · Phases & Lifecycle · Intermediate

Task Phase Rules: Time, Events, and Objections

Rules for task phases — consuming simulation time, objection protocol, fork/join patterns, and safe shutdown in run_phase.

What tasks may do

Task phases exist because verification must wait for real hardware time — clocks, resets, bus transactions, and protocol handshakes. run_phase and runtime sub-phases are tasks.

  • #delay, @event, wait() are legal.

  • fork/join patterns for parallel stimulus and monitors.

  • raise_objection/drop_objection control simulation lifetime.

  • Blocking TLM and sequence start are task-phase activities.

diagram
[UVM][PHASE] task phase anatomy

task run_phase(uvm_phase phase);
  super.run_phase(phase);       // library bookkeeping
  phase.raise_objection(...);   // hold run-time
  // time-consuming work
  phase.drop_objection(...);    // release run-time (all paths!)
endtask

Key takeaways

  • Objections are the task-phase mechanism that ends simulation cleanly.

  • super.run_phase is not optional boilerplate — call it.

  • Every raise needs a matching drop on every exit path.

Common pitfalls

  • raise without drop on error paths — hang forever.

  • drop before sequences complete — premature end.

  • Multiple uncoordinated raises without documented ownership.


Objection discipline and fork patterns

systemverilog
task run_phase(uvm_phase phase);
  super.run_phase(phase);
  phase.raise_objection(this, "agent run");

  fork
    begin
      reset_wait();
      forever drive_items();
    end
    begin
      monitor_forever();
    end
  join_any

  disable fork;
  phase.drop_objection(this, "agent run");
endtask

Sequence start pattern

systemverilog
task run_phase(uvm_phase phase);
  super.run_phase(phase);
  phase.raise_objection(this, "seq");
  my_seq seq = my_seq::type_id::create("seq");
  seq.start(env.agt.sqr);
  phase.drop_objection(this, "seq");
endtask
diagram
[PHASE][RUN] objection ownership

good patterns:
  test raises for scenario duration
  agent raises for perpetual monitor (if needed)
  sequence may auto-raise via starting_phase (know your policy)

bad patterns:
  raise in build_phase
  drop in report_phase
  forget drop on return/ break paths

Runtime sub-phase tasks

The 12 runtime sub-phases (reset_phase, main_phase, etc.) are also tasks. They run in parallel with run_phase — covered in detail in later topics.

  • reset_phase for reset application/wait.

  • configure_phase for programming registers.

  • main_phase for primary stimulus window.

  • shutdown phases for drain and disable.

Key takeaways

  • Task phases coordinate real time; objections coordinate simulation end.

  • fork patterns need explicit shutdown before drop_objection.

  • Runtime sub-phases partition run-time without abandoning run_phase.

Common pitfalls

  • join_none without later quiescence wait.

  • Assuming run_phase ends when main_phase ends — they are parallel.

  • Infinite forever loops without disable fork on shutdown.