Part 2 · Phases & Lifecycle · Intermediate
extract, check, report & final Phases Hub
Hub — post-run cleanup chain: extract aggregates, check enforces invariants, report summarizes, final tears down. End-of-test signoff and debug playbooks.
Overview
After run_phase and the 12 runtime sub-phases end, four function phases close the simulation in a fixed order: extract → check → report → final. This hub teaches each role, the bottom-up vs top-down traversal rules, and how to build a trustworthy end-of-test signoff chain.
These phases are where aggregate pass/fail is decided, coverage and scoreboard totals are surfaced, and files are flushed. Getting them right prevents silent false passes and resource leaks.
Sub-lessons in this topic
extract-phase-role — gather counters and coverage into parent-visible state.
check-phase-drain — evaluate end-of-test invariants and raise uvm_error.
report-phase-summary — human-readable summary and PASS/FAIL from report server.
final-phase-cleanup — last teardown: close files, flush databases.
end-of-test-signoff-chain — coordinated env/test signoff across the hierarchy.
check-report-debug — triage false passes, missing checks, and teardown gaps.
Cleanup phase timeline
[PHASE][UVM] post-run cleanup chain
run_phase + runtime sub-phases end (objections == 0)
│
▼
[PHASE] extract_phase (bottom-up) children → parent aggregates
│
▼
[PHASE] check_phase (bottom-up) invariant evaluation, uvm_error
│
▼
[PHASE] report_phase (bottom-up) summary banners, PASS/FAIL
│
▼
[PHASE] final_phase (top-down) parents finalize after children
invariants:
extract before check — check reads extracted totals
check before report — report reflects check outcomes
final last — no phase runs after final_phase// Minimal env skeleton for the cleanup chain
class tb_env extends uvm_env;
scoreboard scb;
int mismatches, total_txns;
function void extract_phase(uvm_phase phase);
super.extract_phase(phase);
mismatches = scb.mismatch_count;
total_txns = scb.txn_count;
endfunction
function void check_phase(uvm_phase phase);
super.check_phase(phase);
if (total_txns == 0) `uvm_error("CHECK", "no transactions observed")
if (mismatches > 0) `uvm_error("CHECK", $sformatf("%0d mismatches", mismatches))
endfunction
endclassKey takeaways
extract gathers, check decides, report summarizes, final cleans up.
extract/check/report are bottom-up; final_phase is top-down.
Per-transaction compare belongs in the scoreboard during run_phase, not check_phase.
Derive PASS/FAIL from uvm_report_server error+fatal counts, not ad-hoc prints.
Common pitfalls
Heavy per-item comparison in check_phase instead of streaming scoreboard checks.
Printing PASS while UVM_ERROR count is non-zero.
Skipping final_phase teardown and leaving files or coverage DB handles open.
Omitting super.extract_phase / super.check_phase and breaking child propagation.
Signoff discipline
Treat the cleanup chain as a formal signoff pipeline. Every env and test should participate: children extract first, parents aggregate, check raises on violations, report prints a single authoritative result.
[PHASE][UVM] signoff ownership
env layer:
extract scoreboard + coverage totals
check aggregate invariants (zero-txn guard, mismatch ceiling)
test layer:
check test-specific goals (feature exercised, seed replay markers)
report final banner from report server
final layer:
flush coverage DB, close transaction logsAdd a zero-transaction guard in check_phase to catch premature objection drops.
Keep check_phase fast — it runs on every regression.
Use consistent severity tags (CHECK, RESULT) for grep-friendly logs.