Part 7 · Environment & Tests · Intermediate
Shared run_phase: Common Flow With Safe Extension Hooks
Designing one shared run_phase in base_test so all scenarios inherit consistent objections, timeout guards, and execution sequencing.
Single run-phase policy
Keep objection control and timeout ownership in one place: base_test::run_phase. Child tests should customize through hooks only.
[TEST][UVM][ENV] shared run flow
raise objection
-> pre_main()
-> run_main_sequence()
-> wait_for_quiescence()
-> post_main()
drop objection
timeout guard wraps full flowvirtual task run_phase(uvm_phase phase);
time start_t;
start_t = $time;
phase.raise_objection(this);
fork
begin
pre_main();
run_main_sequence();
wait_for_quiescence();
post_main();
end
begin
#(cfg.default_timeout_ns * 1ns);
`uvm_fatal("TEST_TIMEOUT", "Shared run_phase timed out")
end
join_any
disable fork;
phase.drop_objection(this);
`uvm_info("TEST_DONE", $sformatf("elapsed=%0t", $time - start_t), UVM_LOW)
endtaskKey takeaways
Shared lifecycle makes regressions comparable across scenarios.
Timeout policy should fail loudly and consistently.
Child tests gain flexibility through narrow virtual hooks.
Common pitfalls
Child tests opening/dropping objections independently.
Multiple timeout mechanisms fighting each other.
No quiescence criteria, causing flaky test completion.
Extension hook design
Design hooks by responsibility: setup, stimulus, convergence, teardown.
Hook catalog
virtual task pre_main();
// program scoreboard modes, reset counters
endtask
virtual task run_main_sequence();
default_vseq seq = default_vseq::type_id::create("seq");
seq.start(env.v_sqr);
endtask
virtual task wait_for_quiescence();
wait (env.sb.outstanding_count() == 0);
endtask
virtual task post_main();
env.sb.dump_summary();
endtaskEvery hook should be optional and safe to call by default.
Avoid hooks that expose internal component handles.
Prefer declarative cfg changes over imperative side effects.
Determinism checks
[TEST] determinism smoke
seed N:
run base_test hook order logging enabled
seed N again:
verify identical hook timeline + pass/fail
if mismatch:
inspect hook side effects and async waits[ENV] quiescence signals
- scoreboard pending txn count
- monitor publish counter stopped
- coverage collector flush complete
- no pending RAL accessesCommon pitfalls
Waiting on unstable conditions in wait_for_quiescence().
Post-main cleanup mutating checker state before report.
Hidden forked threads not joined before dropping objection.