UNCTIONAL
OVERAGE
Functional Coverage
Introduction to Coverage
Coverage provides a set of metrics used to measure verification progress.
Need for Coverage
• Verification is a prolonged process with unpredictable input stimuli that can
uncover bugs.
• Essential metrics are needed to decide the endpoint of verification once all
metrics are satisfied.
• Ensures all features supported by the design are verified and every line of
design code is covered.
Types of Coverage
1. Code Coverage
2. Functional Coverage
Code Coverage
Code coverage deals with covering design code metrics. It measures how many lines
of code have been exercised with respect to blocks, expressions, FSMs, and signal
toggling.
Types of Code Coverage
• Block Coverage: Checks how many lines of code have been covered.
• Expression Coverage: Ensures all combinations of inputs have been driven to
cover expressions completely.
• FSM Coverage: Verifies all state transitions are covered.
• Toggle Coverage: Ensures all bits in variables have changed their states.
Note:
• Code coverage does not indicate whether the code behavior is correct; it only
identifies uncovered lines, expressions, state transitions, dead code, etc.
• Verification engineers aim to achieve 100% code coverage.
• Industry tools are available to show covered and missing code in code
coverage.
Functional Coverage
Functional coverage deals with covering design functionality or feature metrics. It is
a user-defined metric that indicates how much design specification or functionality
has been exercised.
Types of Functional Coverage
• Data Intended Coverage: Checks the occurrence of data value combinations.
o Example: Writing different data patterns in a register.
• Control Intended Coverage: Checks the occurrence of sequences in the
intended fashion.
o Example: Reading a register to retrieve reset values after releasing a
system reset.
Note:
• Functional coverage metrics are user-defined. It is crucial to consider all
features; missing some features in the functional coverage can lead to
inaccurate coverage results, even if functional coverage shows 100%.
Coverage Model: Covergroup
The covergroup is a user-defined construct that encapsulates coverage model
specifications. The covergroup construct can be instantiated multiple times in
various contexts using the new() operator. A covergroup can be defined in a program,
class, module, or interface.
Components of Covergroup
• A set of coverage points
• Cross coverage between coverage points
• A clocking event that synchronizes coverage points sampling
• Coverage options
• Optional formal arguments
Basic Covergroup Syntax
covergroup <coverage_model_name>;
...
endgroup
<coverage_model_name> <covergroup_inst> = new();
Covergroup Syntax with Clocking Event
covergroup <coverage_model_name> @(clocking_event);
...
endgroup
<coverage_model_name> <covergroup_inst> = new();
List of Arguments in a Covergroup
A covergroup can have an optional list of arguments, which must also be specified in
the new operator.
covergroup cg (list_of_arguments);
...
endcovergroup
Coverpoint in Functional Coverage
A coverpoint is an integral expression or variable that must be covered when
sampling the covergroup. A covergroup can have one or more coverpoints, which
can be labeled. Each coverpoint is associated with single or multiple bins that can be
explicitly defined.
Syntax
covergroup <covergroup_name>;
<coverpoint_label>: coverpoint <coverpoint_name>;
<coverpoint_label>: coverpoint <coverpoint_name>;
...
endgroup
Example
covergroup cg @(posedge clk);
cp1: coverpoint addr;
cp2: coverpoint data;
endgroup : cg
Bins in Functional Coverage
Bins create a set of values for a particular range or all possible values for the specified
coverpoint variable.
• Bins can be generated automatically or explicitly defined by an engineer.
• Bins can be excluded or ignored from the coverage.
• Bins can also be marked as illegal.
Syntax
covergroup <covergroup_name>;
<coverpoint_label>: coverpoint <coverpoint_name> {bins <bin_name> =
{<values>} };
...
endgroup
Without Explicit Bins Declaration
module func_coverage;
logic [3:0] addr;
logic [2:0] data;
logic en;
covergroup c_group;
cp1: coverpoint addr;
cp2: coverpoint data;
cp3: coverpoint en;
endgroup
c_group cg = new();
...
endmodule
Since bins are explicitly specified. They are auto-generated as follows.
variables bins
addr cp1.auto[0], cp1.auto[1], … cp1.auto[15]
data cp2.auto[0], cp2.auto[1], … cp2.auto[7]
en cp3.auto[0], cp1.auto[1]
With explicit bins declaration
module func_coverage;
logic [3:0] addr;
logic [2:0] data;
logic en;
covergroup c_group;
cp1: coverpoint addr {bins b1 = {1, 10, 12};
bins b2[] = {[2:9], 11};
bins b3[4] = {0:8};
}
cp2: coverpoint data {bins b1 = {4,$};
bins b2[] = {2, 3, 6};
}
cp3: coverpoint en {bins b1 = {1}; }
endgroup
c_group cg = new();
...
...
endmodule
variables bins Description
addr bins b1 = {1, 10, 12}; Constructs single bin for 1, 10, 12 value.
bins b2[] = {[2:9], 11}; Constructs 2 bins ie.
b2[0] = 2 ~9,
b2[1] = 11.
bins b3[4] = {0:7}; Constructs 4 bins with possible values as
b3[0] = 0 ~1,
b3[1] = 1~2,
b3[2] = 3~4,
b3[3] = 5~7,
data bins b1 = {4,$}; Constructs single bin for 4~7
bins b2[] = {2, 3, 6}; Constructs 3 bins as
b2[0] = 2,
b2[1] = 3,
b2[2] = 6,
en bins b1 = {1}; Constructs single bin for value = 1
Transition bins
The transition of coverpoint variables for a specified sequence of values can also be
covered.
Transitions can be covered for the below legal coverpoint transitions.
1. Single value transitions
2. Sequence of transitions
3. Set of transitions
4. Consecutive repetition
5. Range of repetition
6. Goto repetition
7. Non-consecutive repetition
Single value transitions
The single value transition can be specified as <value1> => <value2>
Example:
module func_coverage;
logic [3:0] data;
covergroup c_group;
cp1: coverpoint data {bins b1 = (2 => 5);
bins b2 = (2 => 10);
bins b3 = (3 => 8);
}
endgroup
c_group cg = new();
...
...
endmodule
Sequence of transitions
The sequence of transitions can be specified as <value1> => <value2> => <value3>
=> <value4>
Example:
module func_coverage;
logic [3:0] data;
covergroup c_group;
cp1: coverpoint data {bins b1 = (2 => 5 => 6);
bins b2 = (2 => 10 => 12);
bins b3 = (3 => 8 => 9 => 10);
}
endgroup
c_group cg = new();
...
...
endmodule
Set of transitions
The set of transitions can be specified as <transition_set1> => <transition_set2>
Example:
module func_coverage;
logic [3:0] data;
covergroup c_group;
cp1: coverpoint data {bins b1[] = (2,3 => 4,5);
}
endgroup
c_group cg = new();
...
...
endmodule
It creates 4 bins: 2 => 4, 2 => 5, 3 => 4, 3 => 5.
Consecutive repetition
The range of repetition can be specified as <transition_value> [*<repeat_value>]
Example:
module func_coverage;
logic [3:0] data;
covergroup c_group;
cp1: coverpoint data {bins b1[] = (4[*3]);
}
endgroup
c_group cg = new();
...
...
endmodule
4[*3] is equivalent to 4=>4=>4
Range of repetition
The range of repetition can be specified as <transition_value> [*<repeat_range>]
Example:
module func_coverage;
logic [3:0] data;
covergroup c_group;
cp1: coverpoint data {bins b1[] = (4[*2:4]);
}
endgroup
c_group cg = new();
...
...
endmodule
4[*2:4] is equivalent to 4=>4, 4=>4=>4, 4=>4=>4=>4
Goto repetition
Example:
module func_coverage;
logic [3:0] data;
covergroup c_group;
cp1: coverpoint data {bins b1 = (2=>5[->3]=>7);
}
endgroup
c_group cg = new();
...
...
endmodule
2=>5[->3]=>7 is equivalent to 2…=>5…=>5…=>5=>7
Multiple transitions (represented as …) can happen before interested value
transitions.
Non-consecutive repetition
The non-consecutive repetition can be specified as <transition_value> [=
<repeat_range>]
Example:
module func_coverage;
logic [3:0] data;
covergroup c_group;
cp1: coverpoint data {bins b1 = (2=>5[=3]=>7);
}
endgroup
c_group cg = new();
...
...
endmodule
2=>5[=3]=>7 is equivalent to 2…=>5…=>5…=>5=>7
Multiple transitions (represented as …) can happen before interested value
transitions.
Note: It is similar to goto repetition except that non-consecutive repetition may
happen after any number of sample points without the occurrence of repetition
value. Whereas in the case of goto repetition transition must follow the last repetition
occurrence immediately.
Ignore bins
The ignore bins are used to specify a set of values or transitions that can be excluded
from coverage.
Example:
module func_coverage;
logic [3:0] addr;
covergroup c_group;
cp1: coverpoint addr {ignore_bins b1 = {1, 10, 12};
ignore_bins b2 = {2=>3=>9};
}
endgroup
c_group cg = new();
...
...
endmodule
illegal_bins
The illegal bins are used to specify a set of values or transitions that can be marked
as illegal.
For the occurrence of illegal values or transactions, a run-time error is reported.
Example:
module func_coverage;
logic [3:0] addr;
covergroup c_group;
cp1: coverpoint addr {illegal_bins b1 = {1, 10, 12};
illegal_bins b2 = {2=>3=>9};
}
endgroup
c_group cg = new();
...
...
endmodule
Cross Coverage
Cross coverage allows creating a cross product (i.e., Cartesian product) between two
or more variables or coverage points within the same covergroup. In simple terms,
cross coverage is a set of cross-products of variables or coverage points.
Syntax
<cross_coverage_label> : cross <coverpoint_1>, <coverpoint_2>, ...,
<coverpoint_n>
Example
bit [7:0] addr, data;
bit [3:0] valid;
bit en;
covergroup c_group @(posedge clk);
cp1: coverpoint addr && en; // labeled as cp1
cp2: coverpoint data; // labeled as cp2
cp1_X_cp2: cross cp1, cp2; // cross coverage between two expressions
valid_X_cp2: cross valid, cp2; // cross coverage between variable and
expression
endgroup : c_group
Coverage Constructs
iff Construct
The iff construct allows excluding the coverpoint from coverage if an expression
evaluates to false.
Example
module func_coverage;
logic [3:0] addr;
covergroup c_group;
cp1: coverpoint addr iff (!reset_n); // coverpoint addr is covered when
reset_n is low.
endgroup
c_group cg = new();
...
endmodule
binsof and intersect Constructs in Functional Coverage
binsof Construct
The binsof construct yields bins of its expression, which can be a single variable or an
explicitly defined coverage point.
Syntax
binsof (<expression>)
Example
bit [7:0] var1, var2;
covergroup c_group @(posedge clk);
cp1: coverpoint var1 {
bins x1 = { [0:99] };
bins x2 = { [100:199] };
bins x3 = { [200:255] };
}
cp2: coverpoint var2 {
bins y1 = { [0:74] };
bins y2 = { [75:149] };
bins y3 = { [150:255] };
}
cp1_X_cp2: cross cp1, cp2 {
bins xy1 = binsof(cp1.x1);
bins xy2 = binsof(cp2.y2);
bins xy3 = binsof(cp1.x1) && binsof(cp2.y2);
bins xy4 = binsof(cp1.x1) || binsof(cp2.y2);
}
endgroup
Description of Cross Bins
• Cross Bin xy1: Results in 3 cross-products:
<x1, y1>, <x1, y2>, <x1, y3>
• Cross Bin xy2: Results in 3 cross-products:
<x1, y2>, <x2, y2>, <x3, y2>
• Cross Bin xy3: Results in 1 cross-product:
<x1, y2>
• Cross Bin xy4: Results in 5 cross-products:
<x1, y1>, <x1, y2>, <x1, y3>, <x2, y2>, <x3, y2>
intersect Construct
The intersect construct is used with the binsof construct to include or exclude a set of
values of bins that intersect a desired set of values.
Syntax
binsof(<coverpoint>) intersect {<range of values>}
Syntax Description
binsof(cp) intersect {r} The bins of coverpoint cp whose values intersect the range r.
!binsof(cp) intersect {r} The bins of coverpoint cp whose values do not intersect the range r.
Example
bit [7:0] var1, var2;
covergroup c_group @(posedge clk);
cp1: coverpoint var1 {
bins x1 = { [0:99] };
bins x2 = { [100:199] };
bins x3 = { [200:255] };
}
cp2: coverpoint var2 {
bins y1 = { [0:74] };
bins y2 = { [75:149] };
bins y3 = { [150:255] };
}
cp1_X_cp2: cross cp1, cp2 {
bins xy1 = binsof(cp1) intersect {[100:200]};
bins xy2 = !binsof(cp1) intersect {[100:200]};
bins xy3 = !binsof(cp1) intersect {99, 125, 150,
175};
}
endgroup
Description of Cross Bins with intersect
• Cross Bin xy1: Results in 6 cross-products:
<x2, y1>, <x2, y2>, <x2, y3>, <x3, y1>, <x3, y2>, <x3, y3>
• Cross Bin xy2: Results in 3 cross-products:
<x1, y1>, <x1, y2>, <x1, y3>
• Cross Bin xy3: Results in 3 cross-products:
<x3, y1>, <x3, y2>, <x3, y3>
Excluding Cross Products using ignore_bins and illegal_bins Constructs
Excluding Cross Products with ignore_bins
cp1_X_cp2: cross cp1, cp2 {
ignore_bins xy1 = binsof(cp1) intersect {[100:200]};
ignore_bins xy2 = !binsof(cp1) intersect {[100:200]};
ignore_bins xy3 = !binsof(cp1) intersect {99, 125, 150, 175};
}
• Cross Bin xy1: Excludes 6 cross-products:
<x2, y1>, <x2, y2>, <x2, y3>, <x3, y1>, <x3, y2>, <x3, y3>
• Cross Bin xy2: Excludes 3 cross-products:
<x1, y1>, <x1, y2>, <x1, y3>
• Cross Bin xy3: Excludes 3 cross-products:
<x3, y1>, <x3, y2>, <x3, y3>
Specifying Illegal Bins with illegal_bins
cp1_X_cp2: cross cp1, cp2 {
illegal_bins xy1 = binsof(cp1) intersect {[100:150]};
illegal_bins xy2 = !binsof(cp1) intersect {[100:150]};
illegal_bins xy3 = !binsof(cp1) intersect {99, 125, 150, 175};
}
Coverage Methods
The covergroup provides a set of coverage methods as follows.
Methos Description Can be called
(functions) on
void sample Triggers covergroup sampling covergroup
void start Starts collecting coverage information covergroup,
coverpoint, cross
void stop Stops collecting coverage information covergroup,
coverpoint, cross
void Sets instance name to the given string covergroup
set_inst_name
real get_coverage Returns cumulative or type coverage of all covergroup,
instances of coverage item. coverpoint, cross
real Returns specific instance coverage on covergroup,
get_inst_coverage which it is called. coverpoint, cross
Coverage Methods Example
module func_coverage;
bit [7:0] addr, data;
covergroup c_group;
cp1: coverpoint addr;
cp2: coverpoint data;
cp1_X_cp2: cross cp1, cp2;
endgroup : c_group
c_group cg = new();
initial begin
cg.start();
cg.set_inst_name("my_cg");
forever begin
cg.sample();
#5;
end
end
initial begin
$monitor("At time = %0t: addr = %0d, data = %0d", $time, addr, data);
repeat(5) begin
addr = $random;
data = $random;
#5;
end
cg.stop();
$display("Coverage = %f", cg.get_coverage());
$finish;
end
endmodule
Output:
At time = 0: addr = 36, data = 129
At time = 5: addr = 9, data = 99
At time = 10: addr = 13, data = 141
At time = 15: addr = 101, data = 18
At time = 20: addr = 1, data = 13
Coverage = 5.777995
System tasks and functions in coverage
The covergroup provides a set of system tasks and functions in coverage as follows.
System Descriptions
tasks/functions
$set_coverage_db_name Sets coverage information throughout the simulation
in a specified file name.
$get_coverage Returns 0 to 100 range real numbers as an overall
coverage of all coverage groups.
$load_coverage_db Loads cumulative coverage information of all coverage
groups from the given file name.
System tasks and functions coverage example
module func_coverage;
bit [7:0] addr, data;
covergroup c_group;
cp1: coverpoint addr;
cp2: coverpoint data;
cp1_X_cp2: cross cp1, cp2;
endgroup : c_group
c_group cg = new();
initial begin
$set_coverage_db_name("my_cg");
forever begin
cg.sample();
#5;
end
end
initial begin
$monitor("At time = %0t: addr = %0d, data = %0d", $time, addr, data);
repeat(5) begin
addr = $random;
data = $random;
#5;
end
$display("Coverage = %f", $get_coverage());
$finish;
end
endmodule
Output:
At time = 0: addr = 36, data = 129
At time = 5: addr = 9, data = 99
At time = 10: addr = 13, data = 141
At time = 15: addr = 101, data = 18
At time = 20: addr = 1, data = 13
Coverage = 5.777995
Coverage options in Functional Coverage
The coverage options control the behavior of covergroup, coverpoint, and cross.
There are two types of options which are
1. Specific to an instance of a covergroup
2. Specific to the covergroup type as a whole.
Type A: Specific to an instance of a covergroup
Each instance of the covergroup can have an instance-specific option.
Syntax:
option.<option_name> = <expression>;
Where,
option – a built-in member of any coverage group.
<option_name> – supported options are specified in the below table.
Option name Description Allowed in
Syntactic
level
Weight = number 1. If it is set at the covergroup syntactic covergroup,
level, then it specifies the weight of this coverpoint,
[Default value = 1]
covergroup instance for computing the cross
overall instance coverage of the
simulation.
2. If it is set at coverpoint or cross
syntactic level, then it specifies the
weight of a coverpoint or a cross for
computing the instance coverage of the
enclosing covergroup.
name = string Specifies a name for the covergroup covergroup
instance. If it is not specified, the tool will
generate a unique name for each
instance.
per_instance = boolean Each covergroup instance contributes to covergroup
the overall coverage information for the
[Default value = False/0]
coverage type. If it is true, coverage
information for this covergroup instance
is also tracked.
goal = number Specifies target goal for coverpoint or covergroup,
cross or covergroup instance. coverpoint,
[Default value = 90]
cross
comment = string Saves comment in coverage database covergroup,
and includes in the coverage report for coverpoint,
an instance of covergroup, coverpoint, cross
and cross.
at_least = number Specifies the minimum number of hits covergroup,
for each bin. If the bin is hit less than the coverpoint,
[Default value = 1]
specified number, then it is not cross
considered.
detect_overlap=boolean When it is true, it reports a warning for an covergroup,
overlap between the range list of the two coverpoint
[Default value = False/0]
bins of a coverpoint.
auto_bin_max = number When no bins are explicitly specified for covergroup,
a coverpoint, it denotes the maximum coverpoint
[Default value = 64]
number of automatically created bins.
cross_auto_bin_max = Denotes the maximum number of covergroup
number automatically created cross-product bins cross
for a cross.
cross_num_print_missing Saves uncovered cross-product bins in covergroup,
= number the coverage database and includes cross
them in the coverage report.
[Default value = 0]
Example for specific to an instance of a covergroup
module func_coverage;
bit [7:0] addr, data;
covergroup c_group;
option.per_instance = 1;
option.comment = "This is the comment";
cp1: coverpoint addr {
option.weight = 2;
option.auto_bin_max = 32;
}
cp2: coverpoint data;
cp1_X_cp2: cross cp1, cp2 {
option.cross_auto_bin_max = 32;
}
endgroup : c_group
c_group cg = new();
initial begin
forever begin
cg.sample();
#5;
end
end
initial begin
$monitor("At time = %0t: addr = %0d, data = %0d", $time, addr, data);
repeat(5) begin
addr = $random;
data = $random;
#5;
end
$display("Coverage = %f", cg.get_coverage());
$finish;
end
endmodule
Output:
At time = 0: addr = 36, data = 129
At time = 5: addr = 9, data = 99
At time = 10: addr = 13, data = 141
At time = 15: addr = 101, data = 18
At time = 20: addr = 1, data = 13
Coverage = 7.389323
Type B: Specific to the covergroup type as a whole
It specified a particular feature or property of the covergroup type as a whole. They
are analogous to static data members of classes.
Syntax:
type_option.<option_name> = <expression>;
Where,
type_option – a built-in member of any coverage group.
<option_name> – supported options are specified in the below table.
Option name Description Allowed in
Syntactic
level
Weight = 1. If it is set at the covergroup syntactic level, covergroup,
constant_number then it specifies the weight of this covergroup coverpoint,
[Default value = instance for computing the overall instance cross
coverage of the simulation.
1]
2. If it is set at coverpoint or cross syntactic level,
then it specifies the weight of a coverpoint or a
cross for computing the instance coverage of the
enclosing covergroup.
goal = number Specifies target goal for coverpoint or cross or covergroup,
[Default value = covergroup instance. coverpoint,
cross
90]
comment = string Saves comment in coverage database and covergroup,
includes in the coverage report for an instance of coverpoint,
covergroup, coverpoint, and cross. cross
strobe = Similar to the $strobe system task, if it sets to 1, covergroup
constant_number sampling is done at the end of the time slot.
[Default value =
0]
Example for specific to the covergroup type as a whole
module func_coverage;
bit [7:0] addr, data;
covergroup c_group;
option.per_instance = 1;
type_option.comment = "This is the comment";
type_option.strobe = 1;
cp1: coverpoint addr {
type_option.weight = 2;
}
cp2: coverpoint data;
cp1_X_cp2: cross cp1, cp2;
endgroup : c_group
c_group cg = new();
initial begin
forever begin
cg.sample();
#5;
end
end
initial begin
$monitor("At time = %0t: addr = %0d, data = %0d", $time, addr, data);
repeat(5) begin
addr = $random;
data = $random;
#5;
end
$display("Coverage = %f", cg.get_coverage());
$finish;
end
endmodule
Output:
At time = 0: addr = 36, data = 129
At time = 5: addr = 9, data = 99
At time = 10: addr = 13, data = 141
At time = 15: addr = 101, data = 18
At time = 20: addr = 1, data = 13
Coverage = 6.286621