A verification engineer is asked for a coverage model for DCRouter and writes one coverpoint per input signal, with automatic bins for every value. The model has thousands of bins, most of them meaningless (every value of the CRC byte), and it says nothing about what matters: a packet of length 15 arriving when the FIFO is nearly full, or an error on a high-priority packet. Coverage written from the signals measures the signals; coverage written from the plan measures the plan.
How do you write a functional coverage model that measures what matters?
The obvious model covers everything the tool can see, automatically. It produces huge numbers of bins, closes slowly on irrelevant ones (all 256 CRC values), and misses situations that are not a single signal's value: sequences, combinations, configurations, events across ports. A model is a statement of which situations must occur before the team believes the design works; only people who know the risks can write it.
Element | Is | DCRouter example |
|---|---|---|
Coverpoint | A quantity that matters, sampled at a meaningful moment | A header's length, sampled when the header is accepted |
Bins | Groups of values that should behave alike, plus the boundaries | len 0, len 1, len 2–14, len 15 |
Cross | A combination of coverpoints that matters together | Destination × priority × length class |
Event bin | A situation that is not one value | "Woken by input 3 alone", "two tails in one cycle" |
Illegal or ignored bins | Values that must not occur, or that do not matter | A bad CRC on a length-0 packet (one fault per packet) |
Each element should trace to a rule (R1 to R13) or a risk from the plan (lesson 2.6), so an empty bin always means "this rule or risk was never exercised".
// snippet: DCRouter header coverage as a SystemVerilog covergroup
covergroup hdr_cg with function sample(bit [1:0] dst, bit prio, bit [3:0] len);
cp_dst : coverpoint dst; // 4 automatic bins
cp_prio : coverpoint prio; // 2 automatic bins
cp_len : coverpoint len { bins len0 = {0}; bins len1 = {1}; // boundaries apart,
bins mid = {[2:14]}; bins len15 = {15}; } // the middle grouped
x_hdr : cross cp_dst, cp_prio, cp_len; // 32 combinations (R3, R4, R5, R6)
endgroup
// sampled when a header is accepted: hdr_cg.sample(d[15:14], d[13], d[12:9]);The course's runnable model (lesson 6.9) expresses the same bins as named counters, so it runs on every simulator the course uses; the design of the model, which matters more than its syntax, is identical.
For each rule: what values, combinations and events must occur for its check to be meaningful?
For each risk: which situation would expose it (lesson 1.9's places bugs hide)?
For each boundary: is it a bin of its own (0, 1, max, full, empty)?
For each mode: is every configuration value, and every change of it, covered?
For each event across ports or time: simultaneous, back to back, during sleep, right after reset?
For each bin: what is the sampling moment, and could the bin be hit without the situation really happening?
Practice | Purpose |
|---|---|
Coverage model reviewed with designers and architects | Situations that matter, not signals that exist |
Every coverpoint traced to a plan item | Holes map directly to untested requirements |
Illegal bins for impossible values | The model doubles as a check that they never occur |
A coverage model (illustrative) sampled the FIFO's occupancy every cycle and had a bin for "full". It closed quickly. But the bug lived in a push arriving while full with a simultaneous pop, an event across two signals in one cycle that the model never named. The bin "full" was hit thousands of times by tests that never pushed while full. Naming the event ("push and pop together at full") would have shown the hole.
0, 1 and 15 are boundaries where bugs concentrate (BUG_4, BUG_12, BUG_3); 2 to 14 should behave alike, and one bin for them keeps the model small.
The test environment injects at most one fault per packet, so the combination never occurs by design; counting it as a hole would be noise.
Functional coverage is written by people, from the plan: coverpoints, bins, crosses and events.
Boundaries get their own bins; values that behave alike are grouped; impossible values are illegal or ignored.
Every bin should trace to a rule or risk, so each hole means something untested.