Covergroup - nayanarudramurthy/functional-coverage GitHub Wiki
In system verilog covergroup is a user-defined type that encapsulates the specifications of coverage model. It must be instantiated for it to collect data. This is similar to a class, they can be defined once and instantiated multiple times at different places using new
function.
The coverage model is defined using the covergroup construct and it contains cover points, options, formal arguments, and an optional trigger.
-
Syntax:-
covergroup covergroup_name; label 1: coverpoint var1; .... label n: coverpoint var n; endgroup
Each covergroup specification can include,
- A clocking event that synchronizes the sampling of coverage points.
- A set of coverage points.
- Cross coverage between coverage points.
- Optional formal arguments.
- Coverage option.
The functional coverage has two major parts they are data values that are sampled and the time at which they are sampled. When new values are generated, testbench triggers the cover group. This triggering can be done directly by using the pre-defined sample
function.
We generally use the sample function to trigger the coverage group explicitly. If we don't sample this cover group then functional coverage will term it as zero functions covered.
Covergroup can be defined in either a package, module, program, interface, or class. It can sample any visible variables or signals in the design.
Covergroup defined inside a module:-
When we define a cover group inside a module it is easy to access data values and we need to create an object using new
function.
Usual way for creating an object is instantiating cover group with instance_name generally called as handle. For a particular handle an object is created using new function and this cover group can be called as many times by using the handle.
When we define the cover group inside module there is no need to instantiate, instead we can use the covergroup_name to execute the respective cover groups.
Example:
module tb;
datatype var;
covergroup covergroup_name;
label : coverpoint var;
endgroup
initial begin
covergroup_name = new();
endclass
Covergroup defined inside a class:-
A cover group inside a class can sample variables in that class as well as data values from embedded objects. If the covergroup is defined in a class, it is known as the embedded cover group. In this case, we do not make a separate name when we construct it; instead, we just use the original cover group name
Example :
class pack;
data_type var;
covergroup covergroup_instantiate;
label: coverpoint var;
endgroup
endclass
Here var refers to the name of the variable and it can be of any datatype. Inside a class we areCoverpoint must be always declared inside the covergroup block.
Covergroup defined outside class and module :-
Cover group can be defined anywhere within the program, if we are defining covergroup outside module or class we need to instantiate it with a handle names and can be used anywhere inside program by creating an object to the specified handle using new
function.
Example:
covergroup covergroup_name;
label l: coverpoint var 1;
...
label N: coverpoint var N;
endgroup
covergroup_name cg_inst = new();
Here, var 1,....var N refers to the declared variables.
label 1,.....,label N are the names given to the respective coverpoints.
cg_inst is the name instantiated for the covergroup and new
function is used for creating object to the handle cg_inst.
Triggering a cover group
Cover groups are generally triggered by the test bench. It is mandatory to trigger cover group for calculating the percentage of the functions covered. Incase if we don't trigger the cover group the measure of functionality covered will be not not calculated and hence by default it will display as (0.00%) zero percent covered.
General way to trigger the cover group explicitly inside the procedural code is by using sample
function.
There are two ways to trigger coverage collection in a cover group:
-
Triggering cover group at respective clock edge.
covergroup covergroup_name @(posedge clk) ; // samples coverpoint at posedge clk coverpoint var; endgroup
When defining a covergroup, you need to give it a name and optionally provide a sampling event, which in this case is the positive edge of “clk” for var signal. In other words, when a valid instruction occurs,then sample the values on the var signals.
- Mention the
event
at which the covergroup should be sampled.
The coverage event can use a @ to block on signals or events. coverage group can be triggered using "-> event_name" in the procedural code.
covergroup covergroup_name @ e; // e is an event name and can be triggered using ->e
label: coverpoint var;
endgroup
The advantage of using an event over calling the sample method directly is that you may be able to use an existing event such as one triggered by an assertion.
Conditional Coverage
-
Use
iff
keyword to add condition to the coverpoint.
The most common reason for doing so is to turn off coverage till the specified condition is satisfied so that stray triggers are ignored.
Example:covergroup covergroup_name; coverpoint var iff (conditon) { //bins for var} endgroup
iff
is similar to if condition. Whenever the condition inside iff
is true then only it enters into the bins and checks for the coverage. If the condition is not satisfied or false the bins are ignored and the entire cover point will have (0.00%)zero coverage.
-
Use the
start
andstop
functions to control individual instances of cover groupsCovergroup_name cg_inst = new; initial begin if(condtion) cg_inst.stop(); else cg_inst.start(); end
In the above example if and else statements are used to explain start
and stop
functions. This functions can be called anywhere within the procedural code. In general stop and start functions are defined in handle.start() or handle.stop() manner.