Part 11 · Senior Prep · Intermediate
run_phase & drain_time Interview Q&A
Model answers on when run_phase ends, parallel task execution, drain_time tuning, and run_phase debug patterns.
run_phase ending mechanics
run_phase is a parallel task phase — all components' run_phase tasks start together and end on shared objection quiescence.
Q: When does run_phase end?
[INT][SENIOR][UVM] MODEL ANSWER
Q: When does run_phase end?
A:
MECHANISM: run_phase ends when all objections dropped, drain_time elapsed, and
phase_ready_to_end callbacks complete without re-raise.
MOTIVATION: Parallel agents finish at different times — objection model waits for
last active worker, not a fixed delay or first-completed sequence.
WHEN: Sequences raise in run_phase, drop after body() and all forks join.
Test may extend drain_time for in-flight bus transactions.
PITFALL: Assuming run_phase ends when main sequence returns — forked threads
still running keep implicit activity even without objection.
EXAMPLE: vseq drops objection; driver still processing last item — drain_time
absorbs pipeline before extract_phase begins.Q: Is run_phase parallel across components?
[INT][SENIOR][UVM] MODEL ANSWER
Q: Is run_phase parallel?
A:
MECHANISM: run_phase is a task phase — scheduler forks all component run_phase
tasks; they execute concurrently subject to simulation time advancement.
MOTIVATION: TX agent, RX agent, scoreboard, and test all need simultaneous activity
during stimulus — sequential run_phase would deadlock the TB.
WHEN: Always — every component's run_phase runs in parallel with others in
the same phase domain.
PITFALL: Blocking call in env run_phase that waits for test — circular wait
because test run_phase also waits for env activity.
EXAMPLE: driver run_phase loops get_next_item while monitor run_phase samples
pins concurrently; test run_phase starts sequences in parallel.Q: How do you debug a hung run_phase?
[INT][SENIOR][UVM] MODEL ANSWER
Q: Hung run_phase — debug order?
A:
MECHANISM: Hang = run_phase task never returns — objection leak, driver handshake
stall, or infinite wait in component run_phase.
MOTIVATION: Systematic triage beats random waveform scrolling — localize which
component blocks phase completion.
WHEN: Step 1: display_objections(). Step 2: probe driver get_next_item /
item_done. Step 3: check reset and vif. Step 4: UVM_PHASE_TRACE.
PITFALL: Opening waves before objection trace — wastes 30 minutes on healthy
components while one sequencer stall holds the phase.
EXAMPLE: display_objections shows test holds objection; virtual sequence fork
never joined — add join before drop_objection.Q: What is the relationship between run_phase and runtime sub-phases?
[INT][SENIOR][UVM] MODEL ANSWER
Q: run_phase vs runtime sub-phases?
A:
MECHANISM: run_phase executes in parallel with 12 runtime sub-phases (pre_reset
through post_shutdown) — all are sibling task phases in the default domain.
MOTIVATION: Legacy UVM kept run_phase for backward compatibility while sub-phases
provide finer-grained reset/configure/main/shutdown orchestration.
WHEN: Modern TBs use sub-phases for structured bring-up; run_phase for general
stimulus. Many teams raise objections in main_phase instead of run_phase.
PITFALL: Raising objection only in run_phase while sequences run in main_phase —
phase ends before main_phase stimulus completes (or vice versa).
EXAMPLE: Test raises/drops in main_phase; run_phase task empty — objections must
match the sub-phase where sequences actually execute.Key takeaways
run_phase ends on objections + drain_time — not sequence return alone.
All component run_phase tasks execute in parallel.
Debug order: objections → driver handshake → vif/config → phase trace.
Common pitfalls
Empty run_phase in test but sequences run in main_phase without matching objections.
Circular wait between env and test run_phase tasks.
drain_time and run_phase policy
Q: How do you set drain_time correctly for a protocol?
[INT][SENIOR][UVM] MODEL ANSWER
Q: Setting drain_time for a protocol?
A:
MECHANISM: phase.phase_done.set_drain_time(component, duration) adds post-count-zero
wait before phase_done triggers for that component's subtree context.
MOTIVATION: Last transaction may have response beats after driver drops objection;
drain_time absorbs protocol pipeline without keeping objection raised.
WHEN: Set to max expected trailing latency: AXI R/B after last AW, PCIe CPL
after last TLP, interrupt pulse after last MMIO write.
PITFALL: Copy-pasting 1us drain_time from one protocol to another — either too
short (truncated checks) or too long (farm time waste).
EXAMPLE: PCIe env sets 2us drain_time on run_phase; scoreboard clears retry queue
during drain window before extract_phase.Q: Should the test or agent own run_phase objection policy?
[INT][SENIOR][UVM] MODEL ANSWER
Q: Who owns run_phase objections?
A:
MECHANISM: Test (or base_test) typically raises umbrella objection for scenario
duration; sequences may raise sub-window objections for fine control.
MOTIVATION: Centralized test policy ensures consistent end criteria across scenarios;
agent-level raises are for agent-internal background tasks (periodic monitor).
WHEN: base_test raises at run_phase entry, drops after wait_for_quiescence().
Sequences raise only if test delegates per-sequence control.
PITFALL: Both test and every sequence raise independently — hard to balance,
double-count confusion, premature or never-ending phase.
EXAMPLE: base_test owns objection; child sequences run without raising — test
drops after scoreboard pending count hits zero.// run_phase ending — interview pattern
task run_phase(uvm_phase phase);
phase.raise_objection(this, "test start");
phase.phase_done.set_drain_time(this, 500ns);
run_main_sequence();
wait_for_scoreboard_empty();
phase.drop_objection(this, "test done");
endtask
// debug
phase.phase_done.display_objections();Q: extract_phase vs run_phase end — what happens between them?
[INT][SENIOR][UVM] MODEL ANSWER
Q: What happens after run_phase ends?
A:
MECHANISM: run_phase completes → extract_phase (function) collects final state →
check_phase validates → report_phase summarizes → final_phase cleanup.
MOTIVATION: Separates timed activity from zero-time post-run bookkeeping — scoreboard
final compare, coverage report, objection audit happen in cleanup.
WHEN: extract for scoreboard drain summaries; check for fatal-on-error policy;
report for uvm_report_summary and test status.
PITFALL: Starting new stimulus in extract_phase — function phase, no time advance,
and stimulus should have completed in run/main phase.
EXAMPLE: extract_phase: scoreboard.report_unmatched(); check_phase: fatal if
pending count > 0; report_phase: print coverage merge directive.Key takeaways
drain_time should match protocol trailing latency — tune per project.
Centralize objection policy in base_test for regression consistency.
Cleanup phases (extract/check/report) are function phases — no new stimulus.
Common pitfalls
Multiple competing objection owners without documented policy.
Treating extract_phase as a second run_phase for late stimulus.