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

  1. extract-phase-role — gather counters and coverage into parent-visible state.

  2. check-phase-drain — evaluate end-of-test invariants and raise uvm_error.

  3. report-phase-summary — human-readable summary and PASS/FAIL from report server.

  4. final-phase-cleanup — last teardown: close files, flush databases.

  5. end-of-test-signoff-chain — coordinated env/test signoff across the hierarchy.

  6. check-report-debug — triage false passes, missing checks, and teardown gaps.

Cleanup phase timeline

diagram
[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
systemverilog
// 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
endclass

Key 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.

diagram
[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 logs
  • Add 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.