Part 1 · Foundations · Intermediate

The Stimulus, Check, and Coverage Triangle

Balancing constrained-random stimulus, self-checking scoreboards, and functional coverage — the three legs every effective UVM environment must stand on.

Three legs of modern verification

Every credible verification effort rests on three interdependent legs:

  • Stimulus — explores the input space (constrained-random sequences and items).

  • Checking — proves correctness against a model or spec (scoreboards, SVA, RAL).

  • Coverage — measures which scenarios were actually exercised (functional coverage).

Remove any one leg and the stool falls over: stimulus without checking finds nothing; checking without coverage cannot prove completeness; coverage without checking measures activity that was never verified to be correct.


How the three legs connect in UVM

In a UVM environment the three legs are wired through the analysis path:

diagram
sequence ──► sequencer ──► driver ──► DUT ──► monitor ──► analysis_port
                                                              │
                              (CHECK)  scoreboard  ◄──────────┤
                              (COVER)  subscriber  ◄──────────┘
   STIMULUS                                         CHECK + COVERAGE

Stimulus: drive the space

systemverilog
class rw_item extends uvm_sequence_item;
  rand bit        write;
  rand bit [31:0] addr;
  rand bit [31:0] data;
  // constraints keep stimulus in the legal space while staying random
  constraint c_aligned { addr[1:0] == 2'b00; }
  `uvm_object_utils(rw_item)
endclass

Check: prove correctness

systemverilog
// scoreboard receives observed transactions and compares to a model
function void write_actual(rw_item t);
  rw_item exp = ref_model.predict(t);
  if (t.data !== exp.data)
    `uvm_error("SCB", $sformatf("addr %0h exp %0h got %0h", t.addr, exp.data, t.data))
endfunction

Coverage: measure what was hit

systemverilog
covergroup cg;
  cp_dir : coverpoint tr.write { bins rd = {0}; bins wr = {1}; }
  cp_addr: coverpoint tr.addr[15:0] { option.auto_bin_max = 8; }
  x_dir_addr: cross cp_dir, cp_addr;   // were both directions tried across the map?
endgroup

Balancing the three in practice

The legs are designed together, per verification-plan feature. A common failure is to over-invest in one leg: heaps of random stimulus with weak checking, or rich coverage with a scoreboard that only checks trivial cases.

  1. Start from a plan feature; decide its stimulus, its check, and its coverage together.

  2. Use coverage to find unexercised scenarios, then add directed/constrained stimulus to close them.

  3. Use checking strength proportional to risk — data-path blocks need real reference models, not just count checks.

Key takeaways

  • Stimulus, checking, and coverage are co-designed, not bolted on separately.

  • The analysis port feeds both the scoreboard (check) and the subscriber (coverage) from the same observed stream.

  • Coverage tells you where to aim more stimulus; checking tells you whether it was correct.

Common pitfalls

  • Random stimulus with no coverage bins — you cannot prove a feature was hit.

  • High coverage with a weak scoreboard — you measured activity you never actually checked.

  • Sampling coverage on driver items instead of monitored DUT output, missing real behavior.