Skip to content

Optimize sampling of array bins over consecutive values - #8467

Open
davidharrishmc wants to merge 3 commits into
verilator:masterfrom
davidharrishmc:cg-array-bins
Open

davidharrishmc wants to merge 3 commits into
verilator:masterfrom
davidharrishmc:cg-array-bins

Conversation

@davidharrishmc

@davidharrishmc davidharrishmc commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

An array bin such as bins b[] = {[lo:hi]} was sampled with one equality test per value, so a bin over thousands of values generated a sample() function with thousands of if statements. That function dominated C++ compile time: in the RISC-V architectural tests (riscv-arch-test), one covergroup with array bins over about 3000 CSR addresses took 442 s to compile at the default -Os. Its sample() was 10,530 lines.

Each run of consecutive values is now tested as one range, and the bin index is computed from the sampled value's offset into the run: if (lo <= v && v <= hi) cp.incrementBin(base + (v - lo)). Bin names, cross selections, and exclusion metadata are unchanged. Values that are not consecutive, contain X/Z, or belong to a signed or wide coverpoint keep one test per value.

On that suite, total Verilator build time falls from 497 s to 35 s, with identical coverage.dat.

SECOND COMMIT REVERTED. Old notes about its effects for future reference

The second commit applies the same range test to adjacent single-value bins whose values are consecutive, such as the automatic bins of an enum coverpoint over register names (#8462). In the RISC-V architectural tests' Vx16 suite, 55% of all bin tests are such runs; the generated C++ shrinks from 38.9 MB to 33.2 MB and the C++ build from 196 s to 180 s, with identical coverage.dat. A single-value bin joins a run only if it is a normal bin with one integral constant in the coverpoint's range (non-negative for a signed coverpoint) and no iff or wildcard.

New test t_covergroup_array_bins_range covers ranges, mixed lists of runs and single values, ignore and illegal array bins, an iff guard, a cross, runs of single-value bins (unsigned, signed, and wide coverpoints), and the non-range cases. Its bin counts match Questa.

This change was developed with AI assistance (Claude Code). I reviewed and tested it.

An array bin such as 'bins b[] = {[lo:hi]}' was sampled with one
equality test per value, so a bin over thousands of values produced a
sample() function with thousands of tests. That function dominated C++
compile time: one RISC-V architectural test covergroup took 442 s to
compile. Test each run of consecutive values as one range and compute
the bin index from the sampled value's offset.

Signed-off-by: David Harris <David_Harris@hmc.edu>
@verilator-bot verilator-bot Bot added pr: regression Run Regression workflow on PR pr: dev-coverage Run Code coverage workflow on PR labels Sep 23, 2026
Extend the range test for array bins to adjacent single-value bins whose
values are consecutive, such as the automatic bins of an enum coverpoint
over register names. The first bin of a run tests the whole run; the
others need no test of their own.

Signed-off-by: David Harris <David_Harris@hmc.edu>
@davidharrishmc

Copy link
Copy Markdown
Contributor Author

The second commit adds significant new code for only a 10% speed up. It is beyond my skill set to fully understand its interactions with the rest of the system. I would not object to dropping the second commit if that boosts confidence in the correctness.

@davidharrishmc
davidharrishmc marked this pull request as ready for review September 23, 2026 19:05
@wsnyder wsnyder added the pr: uvm-pass PR was run against UVM test suite and passed (Currently running and labelling is a manual process) label Sep 23, 2026
@wsnyder

wsnyder commented Sep 24, 2026

Copy link
Copy Markdown
Member

Do you mind dropping the second commit then, for now?

…ive values"

This reverts commit 1c7c5b3.

Signed-off-by: David Harris <David_Harris@hmc.edu>

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@davidharrishmc

Copy link
Copy Markdown
Contributor Author

Dropped

@verilator-bot

verilator-bot Bot commented Sep 24, 2026

Copy link
Copy Markdown

Patch coverage from PR workflow #5337 (code coverage of lines changed relative to 39e2d8e):

  lines: 100.00% (39 of 39 lines)
  branches: 100.00% (26 of 26 branches)

Report: 35942100500

Please get to 100% line coverage, and understand all branches; see the developer docs

PR history

Workflow #5259 report: 35887451987
Workflow #5198 report: 35834136416

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr: dev-coverage Run Code coverage workflow on PR pr: regression Run Regression workflow on PR pr: uvm-pass PR was run against UVM test suite and passed (Currently running and labelling is a manual process)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants