Merging SystemVerilog Covergroups for Efficiency

In the previous blog post, we were merging covergroups and, in all cases, keeping track of the covergroup instances "INST" (the Mentor Questa notation) data as well.  This is perfectly fine if you have only a few repeated instances. But, what if you have thousands of instances in your design - the covergroup data can get bloated.

Bloated, being that you have lots of almost redundant data if all you want to know is a single coverage number in the end.

The source for my examples that I go through below, and the one liners to launch them for Mentor Questa, are published on my github account here.


Note: June 15, 2014 -
This article and and its predecessor were revised and published in the June 2014 issue of Mentor's "Verification Horizons" quarterly publication under the title "Merging SystemVerilog Covergroups by Example".  I recommend the published version which has a lot more editing and simplifications.

If you just want to have a single number to represent your coverage, you can turn off a few of the options for the covergroup:

  • option.per_instance = 0
  • option.get_inst_coverage = 0
  • type_option.merge_instances = 1

Below is the example of efficient_merge.sv.

Block Diagram of efficient_merge.sv

Block Diagram of efficient_merge.sv

Mentor Questa View of efficient_merge.sv

Mentor Questa View of efficient_merge.sv

What we can see is that there is no longer any "INST" data being kept as in the previous post.  You just get a single number.

Why Do It

The reason to do this is to reduce the amount of data that the coverage database has to hold.  Imagine having 1024 cores in your design that each have an instance of your covergroup in them.  You would have 1024 "INST" values plus the aggregate covergroup.

There are also problems when merging across runs.  If you have to merge those 1024 cores covergroups, it is going to update each of the 1024 covergroups "INST" coverage data as well as the aggregate.  That takes a lot more time than just updating the bins of one coverpoint.

If you have multiple layers of environments and test benches you have to drag along all of the covergroup "INST" data with you too; you would likely also have to do tricks in your simulator to normalize the path to the "INST" coverage as well for the coverage to merge properly.

There are times when it makes sense to keep that "INST" data; such as, if you need to answer the question: "did you send command x to every core in the design?"  That question could not be answered without the "INST" data.  Right now, with this implementation, you could only answer with: "we sent the command x to at least one core in the design; and we sent that command N times."

It is a balancing act of keeping the tools and database reasonable and meeting the completeness requirements.

Reference

IEEE STD 1800-2012 System Verilog LRM Excerpt on Covergroup Options

option.per_instance=boolean Each instance contributes to the overall coverage information for the covergroup type. When true, coverage information for this covergroup instance shall be saved in the coverage database and included in the coverage report. When false, implementations are not required to save instance-specific information.

option.get_inst_coverage=boolean Only applies when the merge_instances type option is set. Enables the tracking of per instance coverage with the get_inst_coverage built-in method. When false, the value returned by get_inst_coverage shall equal the value returned by get_coverage.

type_option.merge_instances=boolean When true, cumulative (or type) coverage is computed by merging instances together as the union of coverage of all instances. When false, type coverage is computed as the weighted average of instances.