Part 5 · Functional Coverage · Intermediate
Managing Cross Explosion
Bin-count multiplication math, coarser source bins, targeted named cross bins, splitting covergroups, and with-filtered crosses.
The multiplication problem
Cross bin counts multiply, and the numbers get away from you fast. Three coverpoints that each look reasonable in isolation can produce a cross no regression will ever close — and every empty cell costs triage time at sign-off.
EXPLOSION MATH
cp_addr_region : 16 bins (address map regions)
cp_burst_len : 16 bins (1..16, one bin each)
cp_qos : 8 bins (QoS levels)
cross cp_addr_region, cp_burst_len, cp_qos
= 16 × 16 × 8 = 2048 cross bins
Regression reality check:
~50k transactions/seed × 100 seeds = 5M samples
5M samples / 2048 cells ≈ 2441 avg hits/cell — looks fine, BUT
samples are NOT uniform: random stimulus clusters, corner cells
may see one sample per million. Last 5% of cells dominate the
entire closure schedule.
Same intent, restructured:
region(4 coarse) × len(3) × qos(2 groups) = 24 cells
+ 6 named precision bins for plan-critical exact combos
= 30 bins. Closeable in days, reviewable in minutes.The fix is never 'run more seeds'. It is restructuring the cross so the goal contains only cells the plan actually demands.
Strategy 1 & 2 — coarsen sources, name only targets
// STRATEGY 1: coarser source bins — shrink the factors
cp_len : coverpoint burst_len {
bins single = {1};
bins short_b = {[2:4]};
bins long_b = {[5:15]};
bins max_b = {16}; // 16 bins -> 4 bins
}
// STRATEGY 2: keep sources fine, but replace the auto product
// with only the named bins the plan demands.
x_len_qos : cross cp_len, cp_qos {
bins max_hiqos = binsof(cp_len.max_b) && binsof(cp_qos) intersect {[6:7]};
bins single_any = binsof(cp_len.single);
// everything else: explicitly not a goal
ignore_bins rest = !binsof(cp_len.max_b) && !binsof(cp_len.single);
}Strategy 3 — split covergroups by concern
One covergroup crossing everything against everything is a smell. Split by verification concern: a performance covergroup crosses QoS with length; an address-map covergroup crosses region with direction. Each cross stays two-dimensional and reviewable, and option.weight on each group keeps the rollup percentage meaningful.
covergroup perf_cg @(posedge clk iff txn_done);
cp_qos : coverpoint qos { bins lo = {[0:3]}; bins hi = {[4:7]}; }
cp_len : coverpoint burst_len{ bins s = {1}; bins m = {[2:8]}; bins l = {[9:16]}; }
x_perf : cross cp_qos, cp_len; // 6 cells
endgroup
covergroup addrmap_cg @(posedge clk iff txn_done);
cp_reg : coverpoint region { bins r[4] = {[0:15]}; } // 4 coarse bins
cp_dir : coverpoint is_write { bins rd = {0}; bins wr = {1}; }
x_map : cross cp_reg, cp_dir; // 8 cells
endgroup
// 6 + 8 = 14 goal cells instead of one 2048-cell monster.What reviewers flag
Cross-review checklist
Any cross over ~50 cells without a written justification line in the plan.
Crosses of 3+ coverpoints where no design logic examines all three fields together.
Auto product accepted wholesale — no named bins, no pruning — on any non-trivial cross.
A coverpoint with per-value bins (bins b[] = ...) feeding a cross — the factor explodes silently.
Goal cells that have been at zero hits across three consecutive regressions — either unreachable (prune) or unplanned-for (write the test).
Interview angle: "You inherit a covergroup with a 16×16×8 cross at 61% after a 500-seed regression. What now?" The expected shape: quantify (2048 cells, ~800 empty), classify empties by reachability, coarsen or split so the goal matches intent, keep a handful of named precision bins for the spec-critical exact combinations, re-baseline, and present the before/after goal math to the review. Mentioning that you would NOT just 'add seeds' is most of the answer.
Key takeaways
Cross size is the product of source bin counts — control the factors before the product.
Replace the auto product with named target bins plus an ignore_bins catch-all when only specific combos matter.
Split monolithic covergroups by verification concern — several small crosses beat one giant one.
Closure effort lives in the emptiest cells — a goal of 30 intentional cells beats 2048 accidental ones.
Common pitfalls
bins x[] per-value array bins feeding a cross — the multiplication happens out of sight.
Answering explosion with more regression seeds — random stimulus clusters; rare cells stay rare.
Coarsening bins so far the cross stops distinguishing the corner the plan cares about — keep named precision bins.
Splitting covergroups but leaving all weights at default — the rollup percentage no longer reflects priorities.