Part 11 · Senior Prep · Intermediate

Directed Closure Tests: Surgical Stimulus for Stubborn Bins

Writing constrained-random and directed sequences that target specific uncovered bins — closure test templates, plusargs, and regression integration.

Aim at the cell, not the universe

Closure sequences constrain the exact scenario the hole needs. For cross write × large burst, randomize with inline constraints or extend a base sequence with defaults that hit the cell:

systemverilog
class wr_large_closure_seq extends axi_base_seq;
  `uvm_object_utils(wr_large_closure_seq)
  int n_txns = 32;

  task body();
    repeat (n_txns) begin
      axi_item req = axi_item::type_id::create("req");
      start_item(req);
      assert(req.randomize() with {
        write == 1;
        burst_len inside {[8:16]};
      });
      finish_item(req);
    end
  endtask
endclass
diagram
[CLOSE][SENIOR][UVM] closure test template

  class axi_wr_large_closure_test extends axi_base_test;
    task run_phase(uvm_phase phase);
      wr_large_closure_seq seq;
      phase.raise_objection(this);
      seq = wr_large_closure_seq::type_id::create("seq");
      seq.start(env.axi_agt.sqr);
      phase.drop_objection(this);
    endtask
  endclass

  regression manifest entry:
    test=axi_wr_large_closure_test  seed=fixed  goal=FEAT-AXI-030
  • One closure test per stubborn cross — easier to attribute and maintain.

  • Use fixed seed for reproducibility; vary only when exploring constraint space.

  • Re-merge after closure run; confirm the specific bin flipped, not just overall %.

Key takeaways

  • Closure sequences are surgical — constrain the hole, not the whole protocol.

  • Dedicated closure tests map 1:1 to plan feature IDs in the manifest.

  • Confirm the targeted bin closed in merged DB — not single-run luck.

Common pitfalls

  • Over-constraining so the test passes but samples the wrong monitor event.

  • Packing ten unrelated holes into one closure test — attribution breaks.

  • Forgetting run_phase objections — closure test exits at time zero.


Virtual sequences for multi-agent holes

Chip-level holes often need coordinated stimulus across agents. Use a virtual sequence on the env virtual sequencer to orchestrate without breaking agent encapsulation:

systemverilog
class ddr_pcie_closure_vseq extends uvm_sequence;
  `uvm_object_utils(ddr_pcie_closure_vseq)
  task body();
    fork
      pcie_wr_seq.start(p_sequencer.pcie_sqr);
      ddr_poll_seq.start(p_sequencer.ddr_sqr);
    join
  endtask
endclass
diagram
[CLOSE][SENIOR][UVM] multi-agent closure pattern

  virtual seq on env.vsqr
       ├─► agent A: setup config (RAL frontdoor)
       ├─► agent B: stress traffic (constrained)
       └─► agent C: error injection (single cycle)

  coverage samples when DUT-visible handshake completes — not when seq starts

Closure test acceptance criteria

  1. Merged DB shows target bin/cross covered.

  2. No new UVM_ERROR beyond known waivers.

  3. Re-run with same seed reproduces the hit.

  4. Hole ticket updated to closed with test+seed reference.

Key takeaways

  • Multi-agent holes need virtual sequences — not env hacks.

  • Acceptance = merged bin hit + repro seed + clean error log.

Common pitfalls

  • Virtual sequence starts traffic before reset deasserts — bin never samples.

  • Closure test passes but monitor never sees the scenario (driver-only path).