Part 2 · Phases & Lifecycle · Intermediate
Objections Deep Dive: Drain Time & Propagation
Hub — hierarchical propagation, set_drain_time mechanics, phase_ready_to_end callback, counting rules, multi-component coordination, and debugging objection hangs.
Overview
The basic raise/drop API is simple, but the internal objection mechanism has depth: hierarchical propagation up the component tree, drain time for trailing activity, the phase_ready_to_end callback for last-chance extensions, and precise counting rules that govern when a phase actually ends.
Understanding these internals separates engineers who guess at hang causes from those who diagnose them in minutes.
Sub-lessons in this topic
objection-hierarchy-propagation — how raises propagate up the component tree.
set-drain-time-deep — drain time mechanics, configuration, and tuning.
phase-ready-to-end — the callback fired before phase actually ends.
objection-counting-rules — source vs total count, set/get semantics.
multi-component-objections — coordinating many raisers across a testbench.
objections-debug-hangs — advanced hang triage, trace interpretation, and fixes.
Architecture map
Legend: [PHASE] [RUN] [UVM]
driver.raise_objection(this)
│
▼ propagates up parent chain
agent (total count includes driver)
│
▼
env
│
▼
phase root objection (count must reach 0)
count hits 0 → drain_time wait → phase_ready_to_end → phase END[PHASE][UVM] objection lifecycle (full)
RAISE → count++ → propagate to root
DROP → count-- → propagate to root
count=0 at root → start drain_time timer
drain_time expires → phase_ready_to_end callback (can re-raise!)
no re-raise → phase_done.trigger() → phase ENDKey takeaways
Objections propagate up the component hierarchy to a per-phase root.
Drain time adds a settle window after count=0 before the phase ends.
phase_ready_to_end allows last-chance re-raise to extend the phase.
Source count vs total count matter for set/get and debugging.
Common pitfalls
Assuming child drop immediately ends phase — parent or sibling may still object.
Excessive drain time silently inflating every test's runtime.
Ignoring phase_ready_to_end — missed opportunity for trailing checks.
Debugging without understanding propagation — misleading count readings.