Part 7 · Environment & Tests · Intermediate

run_test Factory Startup: Select Tests Without Surprises

How +UVM_TESTNAME resolution, class registration, and override ordering shape startup behavior.

Core Contract

Keep this startup boundary deterministic, observable, and fail-fast.

Treat startup as reusable infrastructure: ownership, ordering, and liveness checks must be explicit.

diagram
[UVM][ENV] launch flow

top.run_test()
  -> parse +UVM_TESTNAME
  -> factory lookup
  -> create uvm_test_top.<test>
  -> phase schedule
diagram
[UVM][ENV] boundary model

boundary A: ownership and lifecycle
boundary B: publication and path scope
boundary C: first-activity liveness proof

fix the first broken boundary first
  • Document ownership and ordering assumptions in code, not only slides.

  • Make startup diagnostics actionable and low-noise.

  • Prefer deterministic startup defaults over convenience shortcuts.


Reference Implementation

systemverilog
class base_test extends uvm_test;
  `uvm_component_utils(base_test)
endclass

class smoke_test extends base_test;
  `uvm_component_utils(smoke_test)
endclass

class stress_test extends base_test;
  `uvm_component_utils(stress_test)
endclass

function void build_phase(uvm_phase phase);
  my_driver::type_id::set_type_override(err_driver::get_type());
  super.build_phase(phase);
endfunction
diagram
[ENV] implementation audit

- critical startup assumptions validated?
- missing-state paths fail immediately?
- diagnostics include component path and context?
- minimal smoke seed can exercise this boundary?
diagram
[UVM][ENV] startup observability

track timestamps/counters for:
  reset release
  first sequence launch
  first monitor publish
  first checker compare

these markers reduce triage latency dramatically
  • Keep startup code simple enough to audit in code review.

  • Use fatal failures for non-recoverable startup contract violations.

  • Expose startup metrics in report_phase for CI artifacts.


Debug Workflow

Triage order

  1. Reproduce with one seed and startup tracing enabled.

  2. Verify startup boundary counters and first-activity markers.

  3. Classify failure by boundary before deep waveform analysis.

  4. Fix root boundary and rerun identical seed to confirm.

bash
simv +UVM_TESTNAME=smoke_test        +UVM_VERBOSITY=UVM_LOW        +UVM_CONFIG_DB_TRACE        +UVM_OBJECTION_TRACE
diagram
[UVM][ENV] quick diagnosis

fails before build:
  run_test/factory/config publish issue

build passes, no traffic:
  reset/sequence launch gating issue

monitor active, checker idle:
  connect/subscriber pipeline issue

Key takeaways

  • Factory registration is mandatory for startup reliability.

  • Override ordering must precede creation of target types.

  • Script-level test-name validation prevents avoidable CI failures.

  • A deterministic startup workflow improves regression trust and team velocity.

Common pitfalls

  • Hardcoding run_test("one_test") in production top.sv.

  • Missing factory macros on new test classes.

  • Late overrides that silently do nothing.

  • Skipping startup smoke and finding setup regressions only in long runs.


Applied Patterns

Use this reusable grid before landing startup-related changes.

diagram
[UVM][ENV] startup pattern grid

contract:
  ownership + ordering + liveness documented

implementation:
  fail-fast checks and deterministic defaults

observability:
  milestone counters and concise logs

verification:
  smoke seed + boundary-first triage + closure checklist
systemverilog
function void startup_health_report();
  `uvm_info("STARTUP_SUMMARY",
    $sformatf("rst=%0t seq=%0t mon=%0t cmp=%0t",
      first_reset_release_time,
      first_sequence_start_time,
      first_monitor_publish_time,
      first_scoreboard_compare_time),
    UVM_LOW)
endfunction
  • Treat startup updates as infrastructure API changes.

  • Keep code and checklist language aligned.

  • Require stable startup summaries in regression logs.