Part 2 · Phases & Lifecycle · Intermediate

End-of-Test Signoff Chain: Coordinated Hierarchy Closure

Wiring extract → check → report → final across test, env, and agents for a single authoritative regression signoff.

The full signoff pipeline

A production testbench coordinates signoff across three layers: agents extract local counters, the env aggregates and checks global invariants, the test adds feature-specific checks and prints the final RESULT. Each layer calls super so child work completes before parent logic runs (except final, which is top-down).

diagram
[PHASE][UVM] hierarchy signoff chain

                    TEST
           check: feature goals
           report: *** RESULT ***
                      │
                    ENV
           extract: merge all agent totals
           check: zero-txn, mismatch, cov goal
           report: env summary line
                      │
              ┌───────┴───────┐
           AGENT A         AGENT B
           extract: local   extract: local
           scb counters     scb counters

Layered implementation

systemverilog
// Agent: owns local counters
class axi_agent extends uvm_agent;
  scoreboard scb;
  function void extract_phase(uvm_phase phase);
    super.extract_phase(phase);
    uvm_config_db#(int)::set(this, "", "axi_mismatches", scb.mismatch_count);
    uvm_config_db#(int)::set(this, "", "axi_txns", scb.txn_count);
  endfunction
endclass
systemverilog
// Env: aggregate + global check
class tb_env extends uvm_env;
  int total_mismatches, total_txns;
  function void extract_phase(uvm_phase phase);
    super.extract_phase(phase);
    int m, t;
    void'(uvm_config_db#(int)::get(axi, "", "axi_mismatches", m));
    void'(uvm_config_db#(int)::get(axi, "", "axi_txns", t));
    total_mismatches += m; total_txns += t;
  endfunction
  function void check_phase(uvm_phase phase);
    super.check_phase(phase);
    if (total_txns == 0) `uvm_error("CHECK", "no traffic")
    if (total_mismatches > 0) `uvm_error("CHECK", "mismatches detected")
  endfunction
endfunction
systemverilog
// Test: feature check + final banner
class base_test extends uvm_test;
  function void report_phase(uvm_phase phase);
    super.report_phase(phase);
    uvm_report_server svr = uvm_report_server::get_server();
    int errs = svr.get_severity_count(UVM_ERROR)
             + svr.get_severity_count(UVM_FATAL);
    if (errs == 0) `uvm_info("RESULT", "*** TEST PASSED ***", UVM_NONE)
    else           `uvm_info("RESULT", "*** TEST FAILED ***", UVM_NONE)
  endfunction
endclass

Key takeaways

  • Each hierarchy level has a clear signoff responsibility.

  • Agents extract local data; env checks global invariants; test owns RESULT.

  • config_db handoff is a simple pattern for cross-subtree totals.

Common pitfalls

  • Duplicate check_phase errors at every hierarchy level for the same condition.

  • Test printing PASS while env check_phase already failed.

  • Agents raising uvm_error for global conditions — belongs at env/test level.


CI integration

Regression farms grep for RESULT banners and uvm_error counts. Keep format stable and ensure non-zero exit codes map to FAIL when errors are present.

bash
# Typical CI pass criteria
grep -q "TEST PASSED" sim.log &&   [ $(grep -c "UVM_ERROR" sim.log) -eq 0 ]