0% found this document useful (0 votes)
246 views

Merging SystemVerilog Covergroups by Example - Verification Horizons - Verification Academy

This document discusses different ways to implement SystemVerilog covergroups when there are multiple instances that need to be merged. It provides examples to illustrate how to correctly set up covergroups to perform a union merge or weighted average merge of the instances. Defining the covergroup in the module itself rather than a separate package prevents merging, as the simulator does not recognize that different instances are of the same covergroup type. The examples demonstrate how to avoid issues by making informed choices about covergroup implementation.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
246 views

Merging SystemVerilog Covergroups by Example - Verification Horizons - Verification Academy

This document discusses different ways to implement SystemVerilog covergroups when there are multiple instances that need to be merged. It provides examples to illustrate how to correctly set up covergroups to perform a union merge or weighted average merge of the instances. Defining the covergroup in the module itself rather than a separate package prevents merging, as the simulator does not recognize that different instances are of the same covergroup type. The examples demonstrate how to avoid issues by making informed choices about covergroup implementation.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

Merging SystemVerilog Covergroups by Example

by Eldon Nelson M.S. P.E., Verification Engineer, Micron Technology

SystemVerilog has the concept of covergroups that can


keep track of conditions observed during a simulation. If
c1_cg c1_cg_inst = new(x);
you have a single instance of a covergroup in your design,
you don’t need to deal with merging coverage across all of always @(posedge clk) begin
the instances of that covergroup. If you do have multiple c1_cg_inst.sample();
end
instances of a covergroup and want to merge coverage,
there are implementation details that can make a big endmodule
difference on what information you will be able to collect.
module tb ();
An incorrect application of a covergroup might collect
bit clk = 0;
extraneous information that slows down the simulation
and the merging process. Or, an incorrect application dut duta(1’h0, clk);
of a covergroup could result in covergroups that cannot dut dutb(1’h1, clk);
be merged with other instances because of where the
initial begin
covergroup was defined. You can avoid making these #10; clk = 1;
mistakes by making informed choices when implementing a #10; clk = 0;
covergroup. #10; clk = 1;
#10
$finish();
The choices for implementing a covergroup start with where
end
the covergroup is actually defined: in a separate coverage
object or in the module itself. The choices continue with endmodule
the options that define the behavior of the covergroup.
This article describes the effect of those choices on how
the resulting covergroup behaves when merged. The source Figure 1 Complete source of union_merge.sv
code of the examples, along with their structural diagrams,
as well as screen shots of the resulting covergroups, taken
from Mentor Questa, will help illustrate those choices in a The SystemVerilog above creates a covergroup type called
simple way. c1_cg (purple box in Figure 2) that has a single coverpoint
that will keep track of the one bit vector x that is passed into
The source code of the examples shown and how to it. The coverpoint creates two bins named _0 for the zero
execute them is available on GitHub (link available in value and _1 for the one value. The name of the single
References). coverpoint is: x.

THE BASE EXAMPLE UNION_MERGE.SV The example then instantiates the covergroup inside a
module named dut (green box). The testbench (blue box)
covergroup c1_cg (ref bit x); instantiates two copies of dut named: duta and dutb that has
their x input tied to either a constant one or constant zero.
option.per_instance = 1; The covergroup is sampled on the positive edge of clk.
type_option.merge_instances = 1;

x : coverpoint x { THE UNION MERGE


bins _0 = {1’h0}; The first example “union_merge.sv” merges the two
bins _1 = {1’h1}; instances of the covergroup c1_cg_inst in a way where if
}
either instance meets a specific condition, the condition
endgroup is marked as met. This could be thought of as the union
merge of both covergroup instances.
module dut (input bit x, input bit clk);

32
You might be a person who likes looking directly at the code The coverpoint c1_cg::x also shows the number of hits it
or if you are like me, you would get a lot more out of the had for each bin: 2 in this case. Which is the union of duta
structural block diagram below. and dutb. In this example, you can use the INST and the
c1_cg::x coverage as both measurements are available;
both measurements also include full bin information.

WEIGHTED AVERAGE MERGE


Let’s do a small change where we set the values of:
option.per_instance and type_option.merge_instances
to zero - this is handled in “weighted_merge.sv”. Now,
when we look at the overall coverpoint c1_cg::x, we see
that the simulator now shows the coverpoint c1_cg::x as a
greyed-out un-expandable entry (in the previous example
it was expandable). The coverpoint c1_cg::x now has 50%
coverage opposed to 100% previously. That is because it is
not doing a union merge.

Figure 2 Structural Diagram of union_merge.sv

The implementation detail that is important is that you are


setting the values of: option.per_instance and type_option.
merge_instances both equal to one; which will properly
setup a union merge.

WHAT DOES COVERAGE LOOK LIKE


IN MENTOR QUESTA?
Seeing how the covergroups are interpreted in a simulator Figure 3 Mentor Questa View of Covergroups
will help make this clearer. Below, is a screen capture of in union_merge.sv
how Mentor Questa interprets the covergroups in “union_
merge.sv”. You can see that there are two INST lines in
the Covergroups window. This is showing the c1_cg_inst
covergroup that is in both duta and dutb.

We can see that the duta instance only had hits for the
bin _0 while dutb only had hits for the bin _1 – exactly as
we expected, we tied them to constants of course. So
each INST is 50% covered because each is hitting half of
their described bins. But, because we set the covergroup
options to do a union merge of all possible covergroups of
this type, we get the “overall coverpoint” called c1_cg::x Figure 4 Mentor Questa View of Covergroups
being marked as 100%. in weighted_merge.sv

33
The merge used in this example, is taking all of the What you see below is that Mentor Questa did not pull
instances of the covergroup and giving you the average out what I called the “overall coverpoint” that was named
across every coverpoint – the weighted average merge. It c1_cg::x as it did before. It doesn’t know that the duta and
doesn’t have visibility into what bins are covered anymore; dutb covergroups are the same; therefore, it can’t pull out
that is why you can’t expand it and see the _0 and _1 bins. the covergroup c1_cg as a shared coverage component.
In this example, you can use either the INST or the c1_cg::x
as both measurements are available; but, bin coverage is
only available for INST instance coverage.

Figure 7 Mentor Questa View of Covergroups


in module_merge.sv

You cannot do a union merge or a weighted average merge


Figure 5 Structural Diagram of weighted_merge.sv
if you define your covergroup this way. The reasoning why
the covergroups cannot be merged is best described in
COVERGROUPS DEFINED IN A MODULE Dave Rich’s blog post “SystemVerilog Coding Guidelines:
– WATCH OUT! Package import versus `include.” The problem with merging
The next example, and the one that confused me the most these has to do with the type equivalence of a covergroup.
when I first started implementing coverage, is the diagram The covergroup type gets a unique class name prefixed by
below “module_merge.sv”. This example defines the cover- the module instance name, which names the covergroups
group within the dut module. This is a perfectly legal thing to differently and won’t allow merging to occur. The more
do, but you will see that even if you setup the union merge robust way of doing this example is to define a covergroup
you will not get the result you may think you are getting. within a package and then import the covergroup into the
module; which will allow merging of coverage across the
instances of the covergroup.

MERGING SYSTEMVERILOG COVERGROUPS


FOR EFFICIENCY
So far, we are 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 coverage
database can get bloated. Bloated, being that you have
redundant data if all you want to know is the union of the
total coverage.

Figure 6 Structural Diagram of module_merge.sv

34
If you just want to have a single number, the union, If you have multiple layers of environments and test
to represent your coverage, you can turn off an option benches you have to drag along all of the covergroup INST
for the covergroup: data with you too; you would likely also have to do tricks in
your simulator to normalize the path to the INST coverage
option.per_instance = 0 to merge the coverage databases properly.
type_option.merge_instances = 1
There are times when it makes sense to keep 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 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.”

There is a balancing act of keeping the tools and coverage


database reasonable and meeting the completeness
requirements.

THE TABLE OF COVERGROUP POSSIBILITIES


The table below describes the four types of coverage
Figure 8 Structural Diagram for efficient_merge.sv explored in this article: Union Merge with INST, Weighted
Average Merge, Only Instance Coverage, and Union Merge
without INST with the required values of the covergroup
options and where the covergroup is defined. (A grey “-“
means the value could be any value including not defined
at all.)
per_instance
option.
merge_instances
type_option.
inside a module
covergroup defined
Figure 9 Mentor Questa View of Covergroups
in efficient_merge.sv

In Figure 9 we can see there is no longer any INST data


being kept. You just get a single number.

WHY DO IT
Union Merge with INST
The reason to do this is to reduce the amount of data that 1 1 0
union_merge.sv
the coverage database has to hold. Imagine having 1024
cores in your design that each has an instance of your Weighted Average Merge
covergroup in them. You would have 1024 INST values
0 0 0
weighted_merge.sv
plus the “overall covergroup”.
Only Instance Coverage
— — 1
There are also problems when merging across simulations. module_merge.sv
If you have to merge those 1024 cores’ covergroups, the
Union Merge w/o INST
simulator is going to update each of the 1024 covergroups 0 1 0
efficient_merge.sv
INST coverage data as well as calculating the “overall
covergroup” for every simulation. That takes a lot more time
Figure 10 Table of Covergroup Possibilities
than just updating the bins of the “overall covergroup”.

35
SUMMARY
This article through: source code, diagrams, and screen
captures from Mentor Questa showed how the choices
in implementing a covergroup effect what data will be
available in the coverage database. The covergroup
choices that can be made are summarized in a provided
table that allows for quick reference of the common ways of
configuring covergroups that will meet the required need.
Covergroups are a powerful verification tool to see what
conditions the design has encountered. Informed with a
few examples of how the simulator uses the configuration
options of covergroups, your next covergroup will be even
more effective at capturing exactly what you need to verify.

REFERENCES
• Source Code for All Examples is Available on GitHub
at the link below under the “covmerge” folder:
https://github.com/tenthousandfailures/blog.git
• IEEE STD 1800-2012 SystemVerilog LRM
• This paper is based off of posts that first appeared
on my blog Ten Thousand Failures:
http://tenthousandfailures.com
• Dave Rich blog post “SystemVerilog Coding Guidelines:
Package import versus `include”:
http://blogs.mentor.com/verificationhorizons/
blog/2010/07/13/package-import-versus-include/

36
VERIFICATION
ACADEMY
The Most Comprehensive Resource for Verification Training

20
20 Video
Video Courses
Courrses Available
Available Covering
Covering
• Intelligent
Intelligent Testbench
Testbench Automation
Automation
• Metrics
Metrics inin SoC
SoC Verification
Verification
• Verification
Verification Planning
Planning
• Basic
Basic and
and Advanced
Advanced UVM
UVM
• Assertion-Based
Assertion-Based Verification
Verification
• FPGA
FPGA Verification
Verification
• Testbench
Testbench Acceleration
Acceleration
• Power
Power Aware
Aware Verification
Verificatio
on
• Analog
Anallog Mixed-Signal
Mixed-SSignal Verification
Verification
n
UVM
UVM and
and Coverage
Coverage Online
Online Methodology
Methodology Cookbooks
Cookbo
ooks
Discussion
Discus n Forum
ssion Forum with
with more
more than
than 4400
4400 topics
topic
cs
UVM
M Connect
UVM ct and
Connec d UVM
and UVM Express
s Kits
Express Kits

www.
w ww. verificationacademy.com
verrific
cationacademy.com
Editor: Tom Fitzpatrick
Program Manager: Rebecca Granquist

Wilsonville Worldwide Headquarters


8005 SW Boeckman Rd.
Wilsonville, OR 97070-7777
Phone: 503-685-7000

To subscribe visit:
www.mentor.com/horizons

To view our blog visit:


VERIFICATIONHORIZONSBLOG.COM

You might also like