Part 2 · Phases & Lifecycle · Intermediate

Motivation Case Studies: When Phases Earn Their Keep

Real integration stories — multi-protocol env assembly, reset-before-stimulus ordering, and scoreboard wiring — showing where phases prevent production failures.

Case 1: AXI + APB + memory in one env

Three protocol VIPs, one scoreboard, two clock domains. Without phases, the integrator must manually sequence twelve construction steps and eight connects . With phases, each VIP owns its callbacks.

diagram
[UVM][PHASE] multi-protocol integration

manual approach pain:
  - reorder VIP init when passive APB added
  - scoreboard imp null when monitor created late
  - factory override for error injector missed

phased approach win:
  test.build sets cfg + overrides
  env.build creates all agents + scb
  env.connect wires mon.ap -> scb.imps
  run_phase sequences start after reset sub-phases
systemverilog
class soc_env extends uvm_env;
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    axi = axi_agent::type_id::create("axi", this);
    apb = apb_agent::type_id::create("apb", this);
    mem = mem_model ::type_id::create("mem", this);
    scb = soc_scb  ::type_id::create("scb", this);
  endfunction

  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    axi.mon.ap.connect(scb.axi_imp);
    apb.mon.ap.connect(scb.apb_imp);
    mem.ap.connect(scb.mem_imp);
  endfunction
endclass

Key takeaways

  • Adding a passive agent should not rewrite the integrator's initial block.

  • Scoreboard wiring belongs in env connect_phase after all monitors exist.

  • Factory overrides belong in test build before env build.

Common pitfalls

  • Hard-wiring scoreboard connects inside VIPs — breaks reuse.

  • Creating memory model in run_phase when scoreboard connects in connect.

  • Mixing protocol config and structural create across multiple phases.


Case 2: Reset before stimulus

Reset sequencing is a behavioral synchronization problem. Runtime sub-phases (covered later) and run_phase parallelism exist so reset completes before main stimulus without ad-hoc delays.

diagram
[PHASE][RUN] reset story

without schedule:
  fork driver + monitor at t=0
  reset deassert at t=100ns (maybe)
  first beat corrupted -> debug spiral

with schedule:
  pre_reset/reset/post_reset sub-phases
  main/test sequences start in main
  objections hold run until traffic drains
systemverilog
task run_phase(uvm_phase phase);
  super.run_phase(phase);
  wait_reset_deasserted(); // in agent run, not build
  phase.raise_objection(this, "stimulus");
  seq.start(sqr);
  phase.drop_objection(this, "stimulus done");
endtask

Case 3: Premature $finish vs objections

  • Burst test ends at 10us by timeout while AXI outstanding transactions remain.

  • Scoreboard reports pass because checks were skipped on truncated traffic.

  • Objection-balanced run_phase plus check_phase zero-txn guard catches the false pass.

diagram
[UVM] completion contrast

magic delay:
  #10us; $finish;
  -> false pass risk

objections:
  raise before seq.start
  drop after drain + idle
  -> end tracks real quiescence

Key takeaways

  • Case studies map directly to structural, behavioral, and completion sync axes.

  • Reset and main ordering is a phase-schedule problem, not a longer #delay.

  • Objections align simulation end with traffic reality.

Common pitfalls

  • Using start_of_simulation to drive reset — still zero-time function phase.

  • Assuming fork/join in test replaces agent-level reset discipline.

  • Declaring pass in run_phase before check_phase aggregation.