Part 7 · Environment & Tests · Intermediate

End-of-Test Checklist: Repeatable Pass/Fail Closure Gates

Apply a deterministic closure checklist so every test ends with validated activity, checker completeness, and clear pass/fail semantics.

Checklist philosophy

A test should pass because it met explicit closure gates, not because simulation stopped. A reusable checklist creates consistency across all test classes and prevents accidental silent passes.

diagram
[UVM][ENV] closure checklist categories

A) Activity gates
   - required sequences issued
   - required monitor observations seen

B) Checker gates
   - scoreboard mismatches == 0
   - no pending expected/actual queues

C) Control gates
   - objections balanced
   - timeout not hit
   - no fatal infrastructure errors
diagram
[TEST] pass means

traffic happened
checks completed
no unresolved errors
controlled shutdown path executed
  • Codify checklist in base_test or shared utility package.

  • Keep gates objective with counters and queue depth checks.

  • Fail loudly on missing activity to avoid false green runs.


Reference closure validator

systemverilog
class eot_validator extends uvm_object;
  `uvm_object_utils(eot_validator)

  static function void validate(my_env env);
    if (env.mon.publish_cnt == 0)
      `uvm_error("EOT", "no monitor traffic observed")

    if (env.sb.compare_cnt == 0)
      `uvm_error("EOT", "no scoreboard comparisons executed")

    if (env.sb.mismatch_cnt != 0)
      `uvm_error("EOT",
        $sformatf("scoreboard mismatches=%0d", env.sb.mismatch_cnt))

    if (env.sb.pending_expected() != 0 || env.sb.pending_actual() != 0)
      `uvm_error("EOT", "scoreboard queues not empty at end")
  endfunction
endclass
systemverilog
function void check_phase(uvm_phase phase);
  super.check_phase(phase);
  eot_validator::validate(env);
endfunction

function void report_phase(uvm_phase phase);
  super.report_phase(phase);
  `uvm_info("EOT_REPORT",
    $sformatf("issued=%0d done=%0d mon=%0d cmp=%0d mm=%0d",
      env.drv.issued_cnt,
      env.drv.done_cnt,
      env.mon.publish_cnt,
      env.sb.compare_cnt,
      env.sb.mismatch_cnt),
    UVM_LOW)
endfunction
diagram
[UVM][ENV] minimum required metrics

driver:
  issued_cnt, done_cnt

monitor:
  publish_cnt, drop_cnt

scoreboard:
  compare_cnt, mismatch_cnt, pending depths

coverage:
  sample_cnt (or key bin hits)
  • Gather closure metrics from each boundary in the data path.

  • Validate in check_phase; summarize in report_phase.

  • Treat zero-activity tests as failures unless explicitly intended.


Project-level rollout and review

Checklist adoption steps

  1. Define mandatory gates in one shared validator.

  2. Call validator from base_test so all child tests inherit it.

  3. Allow optional gate extensions per sub-environment.

  4. Require checklist pass in CI before approving new tests.

diagram
[ENV] review template

- objection ownership documented?
- drain_time rationale documented?
- readiness checks bounded?
- timeout configured and justified?
- closure validator metrics complete?
diagram
[UVM][ENV] escalation policy

if gate fails:
  classify as infrastructure vs stimulus vs DUT
  block regression signoff until infrastructure failures are fixed

Key takeaways

  • A formal closure checklist prevents false positives and hidden regressions.

  • Centralized validation in base_test drives consistency across suites.

  • Metrics-based gates are easier to debug than narrative pass criteria.

  • Checklist discipline scales verification quality across teams.

Common pitfalls

  • Optionalizing core closure gates so failures become advisory.

  • Checking only mismatches while ignoring no-activity scenarios.

  • Keeping closure criteria in wiki docs but not enforced in code.

  • Duplicating checklist logic per test and drifting behavior over time.