Part 10 · Advanced Topics · Intermediate
Objections Best Practices
Production conventions for objection ownership, phase-by-phase guidance, reusable helper patterns, and review checklists.
Phase types vs objection usage
Not every phase should use objections the same way. The table below gives a pragmatic rule set for production environments.
[UVM] phase-type matrix for objections
Phase Objections? Typical owner Notes
─────────────────────────────────────────────────────────────────────────────────────
build_phase (function) No N/A structural construction only
connect_phase (function) No N/A TLM wiring only
end_of_elaboration (function) No N/A configuration validation
start_of_simulation (function) No N/A final setup/logging
reset_phase (task) Yes (optional) reset sequencer/test while reset traffic or waits active
configure_phase (task) Yes (optional) test/env if configuration sequences run
main_phase / run_phase (task) Yes (primary) test/seq/components core stimulus/checking lifetime control
shutdown_phase (task) Yes (optional) env/test graceful stop / final flush
check_phase (function) No (usually) N/A assert leftovers; no long waits
report_phase (function) No N/A summarize results onlyTask phases can consume time and may need objections; function phases should not.
run_phase is the primary objection domain in most UVM environments.
check_phase should report integrity, not run long asynchronous cleanup.
Ownership conventions that scale
Large teams need consistency more than personal style. Pick one ownership model for each testbench layer and encode it in review guidelines.
[CHECK] recommended team convention
Test layer:
owns top-level scenario objections
Agent drivers/sequences:
avoid independent objections unless traffic is autonomous
Scoreboards/predictors:
no long-lived objections in run body
conditional temporary hold only in phase_ready_to_end when needed
Passive monitors/coverage:
typically no objections (observe-only components)Why this convention works
Reduces accidental mixed ownership across layers.
Keeps objection traces short and attributable.
Encourages passive components to remain passive.
Makes hung-phase triage a deterministic owner search.
Reusable helper patterns
Codify objection patterns in shared utilities to reduce copy/paste bugs.
class objection_utils;
static task with_objection(uvm_phase phase,
uvm_object source,
string reason,
task automatic body_t());
phase.raise_objection(source, reason);
body_t();
phase.drop_objection(source, {reason, " complete"});
endtask
endclasstask run_phase(uvm_phase phase);
objection_utils::with_objection(
phase, this, "run smoke scenario",
task automatic ();
smoke_vseq vseq = smoke_vseq::type_id::create("vseq");
vseq.start(env.v_sqr);
endtask
);
endtaskHelpers standardize reason strings and balanced accounting.
Keep helpers simple; avoid hiding control flow excessively.
Still review async branches inside helper body for hidden leaks.
Code review checklist and governance
Is objection ownership location explicit (test/sequence/component)?
Does each raise have a guaranteed drop on every control path?
Are drain_time values justified with measured trailing-latency data?
If phase_ready_to_end is used, is condition complete and race-safe?
Do logs include enough context for +UVM_OBJECTION_TRACE interpretation?
Are check/report phases validating leftovers and summary counts?
[UVM] maturity progression
Level 1: objections used ad hoc, frequent hangs
Level 2: standardized ownership, basic trace triage
Level 3: measured drain tuning, conditional holds, stable CI
Level 4: reusable utilities + review automation + low hang incidenceIntegration with scoreboard closure policy
Best-practice objections and best-practice scoreboards are coupled. A clean objection policy ends run only when expected data is drained; a clean scoreboard policy asserts leftovers in check_phase. Together they prevent both hangs and false passes.
[CHECK] end-of-test integrity contract
objection policy:
do not end run while meaningful work remains
scoreboard policy:
fail if expected remains unmatched at check_phase
combined effect:
fewer premature ends, fewer silent passes, easier debugKey takeaways
Use objections primarily in task phases, especially run/main/reset-like flows.
Adopt one team ownership convention and enforce it in reviews.
Prefer measured drain + conditional holds over blanket delays.
Pair objection discipline with scoreboard drain checks for robust sign-off.
Common pitfalls
Applying objections uniformly across all phases without phase-type intent.
Over-abstracting objection helpers so ownership becomes opaque.
Reviewing objection code without checking async and timeout paths.