Coverage#
Coverage is a generic term for measuring progress to complete design verification. Coverage reports are read in percentage(%).
Need for coverage
To help us to understand whether all features of the design are measured and to know whether every line in the code is executed or not.
Types of coverage
- Code Coverage
- Functional Coverage
Code Coverage#
Code coverage deals with the implementation part that is, it checks whether your tests exercised the “implementation” of the design specification, but it won’t check the verification plan. It will measure the quality of the test case
- Line Coverage: Checks how many lines have been executed.
- Path Coverage: Checks in which path the code has been executed.
- Toggle Coverage: Checks which single-bit variable has/had the values 0 or 1.
- FSM Coverage: Checks which state and transitions in a state machine have been visited.
Limitation of Code coverage
It depends on the design code so it can measure coverage for the code which has been written but cannot say anything about the software that has not been written.
Functional Coverage#
Functional coverage defines how much of the design specification has been exercised in verification or Functional coverage measures the progress of all tests in fulfilling the verification plan requirements. It measures the quality of DV.
Limitation of Functional Coverage
If there are 15 features in the design and we mentioned only 10 features of them, it will conclude that all the features are covered. So make sure to include all design features is included in the functional coverage block.
Need
Functional coverage is needed to track whether all the DUT features have been verified and measure the quality of verification. Functional coverage helps us to target the DUT features that are unverified.
Difference between Functional Coverage and Code Coverage
Sl.No. | Functional Coverage | Code Coverage |
---|---|---|
1. | Checks how well the stimulus is covering various functionality | Checks how well code is tested by stimulus |
2. | If any block of code is missing in the design, functional coverage can identify that mistake | If any block of code is missing in the design, code coverage cannot identify that mistake |
3. | Depends on design specification | Depends on design code |
Coverage comparison#
When functional coverage and code coverage are low
- It is the start of the project
When functional coverage is high and code coverage is low
- Code needs more cover points/cases
- Dead code
- It is possible that the test plan is missing some features to cover
When functional coverage is low and code coverage is high
- Poor quality of stimulus(try different seeds)
When functional coverage and code coverage are high
- End of the design and check for the bug rate
Covergroup and coverpoints#
In the System Verilog, the cover group is a user-defined type, that encapsulates the specifications of the 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 the new
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.
Each cover group 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.
Syntax:-
covergroup covergroup_name ;
.....
endgroup
- Example:
The below example shows the declaration and execution of the cover group.
covergroup cgrp;
c1: coverpoint a;
c2: coverpoint b;
endgroup
cgrp cg =new();
initial begin
repeat (5)begin
a=$random();
b=$random();
cg.sample();
$display("a=%d ; b=%d ; coverage = %.2f",a,b,cg.get_inst_coverage());
A cover group is defined with name cgrp and it is instansiated with name ‘cg’. c1 and c2 are the labels given to the cover points, and a and b are the variables declared. Using its handle_name(cg) an object is created using the new
function. a and b variables are randomized to have different values for 5 iterations and during this randomization, the cover group is triggered using the sample
function, and functional coverage is displayed using the handle.get_inst_coverage()
function.
- Output Snap
The below figure shows the output of a simple coverage group.
During the first iteration a=0 and b=1, at this iteration cover points c1 and c2 coverages are calculated separately. The average of c1 and c2 is the instance coverage percentage. Here a and b can have four values that are from 0-3, out of 4 values only value 0 is assigned for ‘a’ variable , therefore the percentage is (1/4)*100 = 25%. Similarly, for b variable value 1 is assigned, so the coverage percentage is (1/4)*100 = 25%. Now, the average of c1 and c2 is (25+25)/2 = 25%.
During the second iteration: a=1 and b=3 ; at this point two values out of four are assigned to variable ‘a’ hence the coverage percentage is (2/4)*100 = 50%. Similarly for ‘b’ variable coverage percentage is 50%. Now the average of cover points c1 and c2 are (50+50)/2 = 50%.
During the third iteration: a=1 and b=1, at this point ‘a’ value is repeating with value 1. But this value 1 is already covered in the execution during the 2nd iteration hence ‘a’ has covered only 2 values out of 4, hence its coverage is (2/4)*100 = 50%. Similarly for variable ‘b’, value 1 is covered during 1st iteration, so 2 values are assigned out of 4, hence coverage is (2/4)*100 = 50%. Now average of c1 and c2 is (50+50)/2 = 50%.
During the fourth iteration a=1 and b=2; at this point variable ‘a’ has covered 2 values but variable ‘b’ has covered 3 values out of 4. Hence, coverage for c1 = 50% and c2 = 75%. Now average of c1 and c2 is (50+75)/2 = 62.50% .
During the fifth iteration a=1 and b=1; ‘a’ has covered 2 values and ‘b’ has covered 3 values out of 4. Hence, coverage for c1 = 50% and c2 = 75%. Now average of c1 and c2 is (50+75)/2 = 62.50% .
Coverage report
NOTE: To have a higher coverage percentage, increase the number of iterations, so the probability of covering all the functions is more.
Coverpoints#
A covergroup can contain one or more coverpoints. Coverpoints specify only integral value or integral expression. The coverpoint can be evaluated when the covergroup is sampled. It can be optionally labeled with a semicolon ‘:’. If the coverpoint is labeled then the system Verilog gives the name of the coverpoint. Each coverpoint will have bins. Bins are automatically created by the simulator or explicitly defined.
syntax:
// without label name //
covergroup covergroup_name;
coverpoint variable_name;
endgroup
// with label name//
covergroup covergroup_name;
label_name: coverpoint variable _name;
endgroup
1. Covergroup defined inside a module#
When we define a cover group inside a module it is easy to access data values and there is no mandatory for instantiation and handle creation. Instead, we can directly use the covergroup_name to execute the respective coverpoints. In order to use cover group we need to create an object using the new
function.
- Syntax:
module tb;
datatype var;
covergroup covergroup_name;
label : coverpoint var;
endgroup
initial begin
covergroup_name = new();
endclass
- Example:
module cvgrp_inside_mod;
covergroup cvgrp ;
c1: coverpoint p.a;
c2: coverpoint p.b ;
endgroup
cvgrp cg;
initial begin
cg=new;
repeat (5) begin
void'(p.randomize);
cg.sample();
$display ("a=%d ; b=%d ; coverage =%.2f",p.a,p.b,cg.get_inst_coverage());
Here a cover group is defined inside the module whereas the variable is declared inside the class. c1 and c2 are the labels given to the cover points, p.a and p.b are the variables declared in class. A handle is created for covergroup with a user-defined name ‘cg’. Using handle name an object is created using the new
function. ‘a’ and ‘b’ variables are randomized using class_handle.randomize
function during this randomization, the cover group is triggered using the sample
function, and functional coverage is displayed using the group_handle.get_inst_coverage()
function.
- Output Snap
Here variable a can have 4 values that are [0-3] and variable ‘b’ can have 8 values that are [0-7].
During 1st iteration a=0 and b=0; coverage of c1 is (1/4)*100 = 25% and coverage of c2 is (1/8)*100 = 12.5% ; therefore average of c1 and c2 is (25+ 12.5)/2 = 18.75%.
During 2nd iteration a=0 and b=2; coverage of c1 is (1/4)*100 = 25% and coverage of c2 is (2/8)*100 = 25% ; therefore average of c1 and c2 is (25+ 25)/2 = 25%.
During 3rd iteration a=1 and b=1; coverage of c1 is (2/4)*100 = 50% and coverage of c2 is (3/8)*100 = 37.5% ; therefore average of c1 and c2 is (50+ 37.5)/2 = 43.75%.
During 4th iteration a=0 and b=2; coverage of c1 is (2/4)*100 = 50% and coverage of c2 is (3/8)*100 = 37.5% ; therefore average of c1 and c2 is (50+ 37.5)/2 = 43.75%.
During 5th iteration a=2 and b=7; coverage of c1 is (3/4)*100 = 75% and coverage of c2 is (4/8)*100 = 50% ; therefore average of c1 and c2 is (75+ 50)/2 = 62.50%.
Coverage report
2. 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. Embedded covergroup can be called outside the class with class_handle.covergroup_name .
- Syntax:
class class_name;
data_type var;
covergroup covergroup_instantiate;
label: coverpoint var;
endgroup
endclass
- Example:
class pack;
rand bit [1:0] a;
rand bit [1:0] b;
covergroup cg;
c1: coverpoint a;
c2: coverpoint b;
endgroup
cg =new();
endclass
pack p = new();
Here the cover group is defined inside the class. . A handle is created for covergroup with a user-defined name ‘cg’. Instancing covergroup with a handle name is not required inside the class and module, instead, you can directly use the cover group name. An object is created using the new
function. During randomization, ‘a’ and ‘b’ variables are randomized using the class_handle.randomize
function and the cover group is triggered using the sample
function.
- Output snap
Here variables a and b can have 4 values that are [0-3].
During 1st iteration a=0 and b=2; coverage of c1 is (1/4)*100 = 25% and coverage of c2 is (1/4)*100 = 25% ; therefore average of c1 and c2 is (25+ 25)/2 = 25%.
During 2nd iteration a=0 and b=1; coverage of c1 is (1/4)*100 = 25% and coverage of c2 is (2/4)*100 = 50% ; therefore average of c1 and c2 is (25+ 50)/2 = 37.50%.
During 3rd iteration a=1 and b=0; coverage of c1 is (2/4)*100 = 50% and coverage of c2 is (3/4)*100 = 75% ; therefore average of c1 and c2 is (50+ 75)/2 = 62.50%.
During 4th iteration a=0 and b=2; coverage of c1 is (2/4)*100 = 50% and coverage of c2 is (3/4)*100 = 75% ; therefore average of c1 and c2 is (50+ 75)/2 = 62.50%.
During 5th iteration a=2 and b=0; coverage of c1 is (3/4)*100 = 75% and coverage of c2 is (3/4)*100 = 75% ; therefore average of c1 and c2 is (75+ 75)/2 = 75%.
Coverage report
3. Covergroup defined outside class and module#
The cover group can be defined anywhere within the program, if we are defining covergroup outside a module or class we need to instantiate it with a handle name, and can be used anywhere inside a program by creating an object to the handle using the new
function.
In general, the Syntax of covergroup
- Syntax:
covergroup covergroup_name;
label l: coverpoint var 1;
...
label N: coverpoint var N;
endgroup
covergroup_name cg_inst = new();
- Example:
class cover_group;
rand bit [2:0]a;
rand bit [1:0]b;
endclass
cover_group c=new();
covergroup cgrp;
c1: coverpoint c.a;
c2: coverpoint c.b;
endgroup
module outside;
cgrp cg=new();
initial begin
repeat (5)begin
void'(c.randomize());
cg.sample();
$display("a =%d b=%d; coverage %%= %0.2f",c.a,c.b,cg.get_inst_coverage());
end
Here the cover group is defined outside the class and module whereas the variable is declared inside the class. A handle is created for a class with a user-defined name ‘c’, Using this handle name(‘c’) an object is created using the new
function. Similarly a handle is created for covergroup with a user-defined name ‘cg’. Using this handle name an object is created using the new
function. Cover group is then triggered using sample
function and the variable a and b are randomized using randomize
function.
- output snap
Here variable a can have 8 values that is [0-7] and variable ‘b’ can have 4 values that is [0-3].
During 1st iteration a=0 and b=2; coverage of c1 is (1/8)*100 = 12.5% and coverage of c2 is (1/4)*100 = 25% ; therefore average of c1 and c2 is (12.5+ 25)/2 = 18.75%.
During 2nd iteration a=3 and b=1; coverage of c1 is (2/8)*100 = 25% and coverage of c2 is (2/4)*100 = 50% ; therefore average of c1 and c2 is (25+ 50)/2 = 37.5%.
During 3rd iteration a=0 and b=0; coverage of c1 is (2/8)*100 = 25% and coverage of c2 is (3/4)*100 = 75% ; therefore average of c1 and c2 is (25+ 75)/2 = 50%.
During 4th iteration a=6 and b=2; coverage of c1 is (3/8)*100 = 37.5% and coverage of c2 is (3/4)*100 = 75% ; therefore average of c1 and c2 is (37.5+ 75)/2 = 56.25%.
During 5th iteration a=3 and b=0; coverage of c1 is (3/8)*100 = 37.5% and coverage of c2 is (3/4)*100 = 75% ; therefore average of c1 and c2 is (37.5+ 75)/2 = 56.25%.
Coverage report
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. In case we don’t trigger the cover group the measure of functionality covered will be not calculated and hence by default it will display as (0.00%) zero percent covered.
The general way to trigger the cover group explicitly inside the procedural code is by using sample
function.
SL.NO | Triggering a cover group |
---|---|
1. | Triggering cover group at respective clock edge |
2. | Mention the event at which the covergroup should be sampled. |
There are two different methods to trigger coverage collection in a cover group:
1. Triggering cover group at respective clock edge.#
- Syntax:
covergroup covergroup_name @(clkedge clk) ; // samples coverpoint at respective clk edge
coverpoint var;
endgroup
The cover group is triggered during the respective edge of the clock and the cover points are taken into consideration.
Example:
bit clk;
always #5 clk=~clk;
covergroup cvgp @ (posedge clk);
c1: coverpoint a;
c2: coverpoint b;
endgroup
To trigger the cover group we are using clock edges. In this example at every 5ns clock edge varies and during the positive edge of clock the cover group gets triggered and the values of cover points are sampled and randomized.
- Output snap
Here variable a can have 8 values that is [0-7] and variable ‘b’ can have 2 values that is 0 and 1.
During 1st iteration a=4 and b=1; coverage of c1 is (1/8)*100 = 12.5% and coverage of c2 is (1/2)*100 = 50% ; therefore average of c1 and c2 is (12.5+ 50)/2 = 31.25%.
During 2nd iteration a=1 and b=0; coverage of c1 is (2/8)*100 = 25% and coverage of c2 is (2/2)*100 = 100% ; therefore average of c1 and c2 is (25+ 100)/2 = 62.50%.
During 3rd iteration a=1 and b=0; coverage of c1 is (2/8)*100 = 25% and coverage of c2 is (2/2)*100 = 100% ; therefore average of c1 and c2 is (25+ 100)/2 = 62.50%.
During 4th iteration a=3 and b=0; coverage of c1 is (3/8)*100 = 37.5% and coverage of c2 is (2/2)*100 = 100% ; therefore average of c1 and c2 is (37.5+100)/2 = 68.75%.
During 5th iteration a=5 and b=0; coverage of c1 is (4/8)*100 = 50% and coverage of c2 is (2/2)*100 = 100% ; therefore average of c1 and c2 is (50+ 100)/2 = 75%.
Coverage report
2. Mention the event
at which the covergroup should be sampled.#
The coverage event can use a @ to block signals or events. coverage group can be triggered using “-> event_name” in the procedural code.
- Syntax:
covergroup covergroup_name @ e; // e is an event name and can be triggered using ->e
label: coverpoint var;
endgroup
- Example:
event e;
covergroup cgrp @ e;
c1 : coverpoint a;
endgroup
cgrp cg;
initial begin
cg = new();
repeat (5)begin
a=$random;
#1 -> e;
$display("a = %0d ; coverage = %0.2f",a,cg.get_inst_coverage());
end
Another method used to trigger the cover group is by using events. In this example, an event ’e’ is defined and triggered using ->e(event_name) this in turn triggers the covergroup and samples the values of every cover point. The advantage of using an event over calling the sampling method directly is that you may be able to use an existing event.
- output snap
Here variable a can have 4 values that is [0-3].
During 1st iteration a=0 ; coverage of c1 is (1/4)*100 = 25% .
During 2nd iteration a=1 ; coverage of c1 is (2/4)*100 = 50% .
During 3rd iteration a=1 ; coverage of c1 is (2/4)*100 = 50% .
During 4th iteration a=3 ; coverage of c1 is (3/4)*100 = 75% .
During 5th iteration a=1 ; coverage of c1 is (3/4)*100 = 75% .
coverage report
Conditional Coverage#
1. Use iff
keyword to add a 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.
- Syntax:
covergroup covergroup_name;
coverpoint var iff (condition) { //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.
- Example:
covergroup cvgrp @ (posedge clk);
c1: coverpoint a iff(b==2) {bins b1 = {4};
bins b2 = {5};}
endgroup
In this example, the coverpoint is defined for variable ‘a’ and only if the condition (b==2) is satisfied the coverpoint bins are executed. Here If the b value is 2 then cover point bins are checked for their conditions b1 and b2. Bin b1 is said to be hit/covered only if the variable ‘a’ is assigned with 4 and similarly bin b2 is said to be hit/covered only if the variable ‘a’ is assigned with 5. Finally, it averages the coverage percentage of the bins and that is termed as the overall coverage of that particular coverpoint.
- output snap
Here variable a can have 8 values that is [0-7] and variable ‘b’ can have 4 values that is [0-3].Coverage depends on explicitly defined bins. bins b1
During 1st iteration a=4 and b=1; checks for ‘b’ value; iff condition (b==2) is False, hence coverage of b1=0% and coverage of bin b2 =0% ; Average coverage of coverpoint is (0+0)/2 = 0.00%.
During 2nd iteration a=1 and b=3; checks for ‘b’ value; iff condition (b==2) is False, hence coverage of b1=0% and coverage of bin b2 =0% ; Average coverage of coverpoint is (0+0)/2 = 0.00%.
During 3rd iteration a=5 and b=1; checks for ‘b’ value; iff condition (b==2) is False, hence coverage of b1=0% and coverage of bin b2 =0% ; Average coverage of coverpoint is (0+0)/2 = 0.00%.
During 4th iteration a=5 and b=2; checks for ‘b’ value; iff condition (b==2) is True, hence coverage of b1=0% and coverage of bin b2 =100% ; Average coverage of coverpoint is (0+100)/2 = 50%.
During 5th iteration a=1 and b=1; checks for ‘b’ value; iff condition (b==2) is False, hence coverage of b1=0% and coverage of bin b2 =100% ; Average coverage of coverpoint is (0+100)/2 = 50%.
During 6th iteration a=6 and b=1; checks for ‘b’ value; iff condition (b==2) is False, hence coverage of b1=0% and coverage of bin b2 =100% ; Average coverage of coverpoint is (0+100)/2 = 50%.
During 7th iteration a=5 and b=0; checks for ‘b’ value; iff condition (b==2) is False, hence coverage of b1=0% and coverage of bin b2 =100% ; Average coverage of coverpoint is (0+100)/2 = 50%.
During 8th iteration a=1 and b=2; checks for ‘b’ value; iff condition (b==2) is True, hence coverage of b1=0% and coverage of bin b2 =100% ; Average coverage of coverpoint is (0+100)/2 = 50%.
coverage report
2. Use the start
and stop
functions to control individual instances of cover groups.#
Covergroup_name cg_inst = new;
initial begin
if(condition)
cg_inst.stop();
else
cg_inst.start();
end
In the above example if and else statements are used to explain the start
and stop
functions. These functions can be called anywhere within the procedural code. In general stop and start functions are defined in handle. start() or handle.stop() manner.
- Example:
covergroup cgrp;
c1: coverpoint s.a;
c2: coverpoint s.b;
endgroup
module cvgrp_start_stop;
cgrp cg;
initial begin
cg = new();
for(int i=0;i<6;i++) begin
void'(s.randomize());
cg.sample();
$display("a=%d ; b=%d ; coverage = %0.2f",s.a,s.b,cg.get_inst_coverage());
if (cg.get_inst_coverage()>65)begin
cg.stop;
$display("if coverage%% is greater than 65%%,stop executing covergroup");
end
end
In this example, the variables a and b are declared inside the class. To access those variables from the class we created an object with the handle (here handle for the class is ’s’). After triggering the covergroup the coverage percentage is getting displayed. If the coverage is beyond 65% the execution of coverage crop is stopped using cg.stop
(group_handle_name.stop) function. Hence the coverage percentage will remain constant, even if new values are assigned to variables the coverpoint ignores those values and shows the previous percentage. Execution can be triggered and continued by using cg.start
(group_handle.start) function.
- output snap
Here variable a can have 8 values that is [0-7] and variable ‘b’ can have 2 values that is 0 and 1.
During 1st iteration a=0 and b=0; coverage of c1 is (1/8)*100 = 12.5% and coverage of c2 is (1/2)*100 = 50% ; therefore average of c1 and c2 is (12.5+ 50)/2 = 31.25%.
During 2nd iteration a=1 and b=1; coverage of c1 is (2/8)*100 = 25% and coverage of c2 is (2/2)*100 = 100% ; therefore average of c1 and c2 is (25+ 100)/2 = 62.50%.
During 3rd iteration a=6 and b=0; coverage of c1 is (3/8)*100 = 37.5% and coverage of c2 is (2/2)*100 = 100% ; therefore average of c1 and c2 is (25+ 100)/2 = 68.75%.
Execution of cover points is stopped and hence the coverage percentage remains unchanged. Even though new values of a and b are assigned they are ignored and coverage will not be calculated.
coverage report
Git lab code link: https://github.com/muneeb-mbytes/SystemVerilog_Course/blob/production/functional_coverages/covergroup/conditional_coverage/cvgrp_start_stop/cvgrp_start_stop.sv
Git lab output link: https://github.com/muneeb-mbytes/SystemVerilog_Course/blob/production/functional_coverages/covergroup/conditional_coverage/cvgrp_start_stop/cvgrp_start_stop.log
Cross Coverage :#
Cross Coverage is specified between the cover points or variables. Cross coverage is specified using the cross construct.
Expressions cannot be used directly in a cross. cross coverage can be measured for two or more cover points at the same time. If we are measuring cross coverage of a variable with N values, and of another with M values, internally there will be N * M bins to store all the combinations of ‘NM’.
Syntax:
covergroup covergroup_name;
label1: coverpoint var1;
label2: coverpoint var2;
label3:cross label1,label2;
endgroup
Example - 1:
covergroup cg;
c1: coverpoint a;
c2: coverpoint b;
c3: cross c1,c2;
endgroup
cg = new();
In this example the cross coverage is carried out between coverpoint c1 and c2. variable a and b are of single bit and hence it can have values either 0 or 1. After execution of c1 and c2, cross of those cover points are calculated by using cross keyword. Since variable ‘a’ and ‘b’ each can have 2 values, the cross of this can have combination of a and b i,e { {0,1} , {0,1} , {1,0}, {1,1} }.
Example 2:
covergroup cvgrp;
c1:cross a,b;
endgroup
cvgrp cg = new();
Instead of writing 3 lines of code for cross coverage on cover points(cross c1,c2), we can directly write that in one code using cross of variable names(cross a,b). Using cross construct for variables will implicitly creates an individual cover points on variable ‘a’, on variable ‘b’ and a cross of variable a and b. This is just similar to the previous example 1. Hence the output of example 1 and example 2 remains same.
Here variable a and b can have 2 values that is either 0 or 1 and the cross values are the combination of two coverpoint values, they are {0,0}, {0,1}, {1,0} and {1,1}.
During 1st iteration a=1 and b=0; coverage of c1 is (1/2)*100 = 50% ; coverage of c2 is (1/2)*100 = 50% ; coverage of c3 is (1/4)*100 = 25% ; therefore average of c1, c2 and cross c3 is (50+50+25)/3 = 41.67%.
During 2nd iteration a=1 and b=0; coverage of c1 is (1/2)*100 = 50% ; coverage of c2 is (1/2)*100 = 50% ; coverage of c3 is (1/4)*100 = 25% ; therefore average of c1, c2 and cross c3 is (50+50+25)/3 = 41.67%.
During 3rd iteration a=0 and b=1; coverage of c1 is (2/2)*100 = 100% ; coverage of c2 is (2/2)*100 = 100% ; coverage of c3 is (2/4)*100 = 50% ; therefore average of c1, c2 and cross c3 is (100+100+50)/3 = 83.33%.
During 4th iteration a=1 and b=0; coverage of c1 is (2/2)*100 = 100% ; coverage of c2 is (2/2)*100 = 100% ; coverage of c3 is (2/4)*100 = 50% ; therefore average of c1, c2 and cross c3 is (100+100+50)/3 = 83.33%.
During 5th iteration a=1 and b=1; coverage of c1 is (2/2)*100 = 100% ; coverage of c2 is (2/2)*100 = 100% ; coverage of c3 is (3/4)*100 = 75% ; therefore average of c1, c2 and cross c3 is (100+100+75)/3 = 91.67%.
NOTE : If we define cover points on some variables, and a cross on that variables, then there arises a warning.
Warning Example:
covergroup cvgrp;
c1: coverpoint a;
c2: coverpoint b;
c3: cross a,b;
endgroup
In this example both coverpoint and cross are carried out on same variables. Earlier we have seen cross between cover points and cross between the variables but here we are performing cross on variables whose cover points are already defined explicitly.
Now here a conflict arises in the simulator. The conflict is variable ‘a’ and ‘b’ are already defined in cover points, hence we can directly write cross on those cover points c1 and c2. Other wise if we don’t need to use that c1 and c2 then, the simulator will implicitly create another cover points on a and b along with cross of those variables. Therefore in total we will have 5 cover points.
Here variable a and b can have 2 values that is either 0 or 1. Inside covergroup c1,c2 and c3 are cover points. c3 will generate 3 coverpoint c3[0] , c3[1] and c3[2] implicitly.
- During 1st iteration a=0 and b=1; coverage of c1 is (1/2)*100 = 50% ; coverage of c2 is (1/2)*100 = 50% ;In coverage of c3 implicitly coverpoints for a and b are generated. Hence, cover point c3 will split into 3 seperate parts, c3[0] is for a variable ‘a’ , c3[1] is for a variable ‘b’ and c3[2] is for cross of a and b.
coverage of c3: c3[0] is (1/2)*100 = 50% ; c3[1] is (1/2)*100 = 50% ; c3[2] is (1/4)*100 = 25% ;
The overall average for first iteration is (c1+c2+c3[0]+c3[1]+c3[2])/5; that is (50+50+50+50+25)/5 = 45%.
- During 2nd iteration a=1 and b=1; coverage of c1 is (2/2)*100 = 100% ; coverage of c2 is (1/2)*100 = 50% ;
coverage of c3: c3[0] is (2/2)*100 = 100% ; c3[1] is (1/2)*100 = 50% ; c3[2] is (2/4)*100 = 50% ;
The overall average for first iteration is (c1+c2+c3[0]+c3[1]+c3[2])/5; that is (100+50+100+50+50)/5 = 70%.
- During 3rd iteration a=1 and b=1; coverage of c1 is (2/2)*100 = 100% ; coverage of c2 is (1/2)*100 = 50% ;
coverage of c3: c3[0] is (2/2)*100 = 100% ; c3[1] is (1/2)*100 = 50% ; c3[2] is (2/4)*100 = 50% ;
The overall average for first iteration is (c1+c2+c3[0]+c3[1]+c3[2])/5; that is (100+50+100+50+50)/5 = 70%.
- During 4th iteration a=1 and b=0; coverage of c1 is (2/2)*100 = 100% ; coverage of c2 is (2/2)*100 = 100% ;
- coverage of c3: c3[0] is (2/2)*100 = 100% ; c3[1] is (2/2)*100 = 100% ; c3[2] is (3/4)*100 = 75% ;
The overall average for first iteration is (c1+c2+c3[0]+c3[1]+c3[2])/5; that is (100+100+100+100+75)/5 = 95%.
- During 5th iteration a=1 and b=0; coverage of c1 is (2/2)*100 = 100% ; coverage of c2 is (2/2)*100 = 100% ;
coverage of c3: c3[0] is (2/2)*100 = 100% ; c3[1] is (2/2)*100 = 100% ; c3[2] is (3/4)*100 = 75% ;
The overall average for first iteration is (c1+c2+c3[0]+c3[1]+c3[2])/5; that is (100+100+100+100+75)/5 = 95%.
Coverpoints can be specified in various ways:
- coverpoints using value
- coverpoints using expression
- coverpoints using function return value
- coverpoints using part select
coverpoints using value#
syntax:
cover_value: coverpoint value_name;
code snippet:
bit [3:0] a;
bit [3:0] arr[4]='{2,5,0,12};
covergroup cg; //creating covergroup cg
a1:coverpoint a; //declaring coverpoint a1
endgroup
cg cg_inst; //instantiating covergroup cg
initial begin
cg_inst = new();
foreach(arr[i]) begin
a=arr[i]; //assigning array values to a
cg_inst.sample(); //sampling the covergroup cg
$display("a=%d coverage %%=%0.2f",a,cg_inst.get_inst_coverage());
end
end
Here in the covergroup ‘cg’ coverpoint a1 is specified with the value ‘a’.The value of ‘a’ is assigned each time by the array ‘arr’. ‘a’ is the 4 bit number, so there are 16 possible values for ‘a’.
Output snap:
- coverage report
Git lab code link: https://github.com/muneeb-mbytes/SystemVerilog_Course/blob/production/functional_coverages/coverpoints/simple_coverpoint/cover_point.sv
Git lab output link: https://github.com/muneeb-mbytes/SystemVerilog_Course/blob/production/functional_coverages/coverpoints/simple_coverpoint/cover_point.log
In the above example, for 1st iteration, one value is covered so the coverage percentage is equal to (1/16)*100=6.25%. In 2nd iteration, the value of ‘a’ is covered with two values so the coverage percentage will be (2/16)*100=12.5%. In 3rd iteration, the value of ‘a’ is covered with three values so the coverage percentage will be (3/16)*100=18.75%. In the 4th iteration, the value of ‘a’ is covered with four values so the coverage percentage will be (4/16)*100=25%. Here bins are not specified so the system Verilog automatically created bins ‘auto bins’ for the coverpoint. If the same value occurs more than once then the system Verilog is considered it was covered and doesn’t count on the next time, it is just ignored.
coverpoints using expression#
syntax:
cover_exp: coverpoint expression;
In coverpoints, the coverpoint can be specified with the integral arithmetic expression.
Code snippet:
bit [1:0] a;
bit [2:0] b;
covergroup cg; //created covergroup cg
a1:coverpoint a; //declaring coverpoint a1
b1:coverpoint b; //declaring coverpoint b1
axb:coverpoint a*b; //declaring coverpoint axb
endgroup:cg
cg cg_inst; //covergroup instantiating
initial begin
cg_inst = new();
repeat(10) begin
a=$random; //assigning random values to a
b=$random; //assigning random values to b
cg_inst.sample(); //sampling the covergroup cg
$display("a=%d b=%d axb=%d coverage %%=%0.2f",a,b,a*b,cg_inst.get_inst_coverage());
end
end
Here the coverpoint a x d is specified using the arithmetic expression. The coverpoint a x b is calculated and the number of bits for a x b is equal to the maximum of the number of bits of a & b.
Output snap:
- coverage report
Git lab code link: https://github.com/muneeb-mbytes/SystemVerilog_Course/blob/production/functional_coverages/coverpoints/coverpoint_expression/expression.sv
Git lab output link: https://github.com/muneeb-mbytes/SystemVerilog_Course/blob/production/functional_coverages/coverpoints/coverpoint_expression/expression.log
Here ‘a’ has 2 bits and ‘b’ has 3 bits, therefore a x b is a 3-bit number. So, for a x b there will be 2^3=8 automatic bins created. If a x b has more than 3 bits it is considered only 3 bits from LSB. Therefore in the coverage report, the automatic bins for a x b are 8 and one is uncovered. The coverage percentage of a,b, and a x b are 75, 87.5, and 87.5 respectively, so the total coverage percentage will be the average of individual coverages i.e., 83.3%.
coverpoints using the function return value#
Coverpoints can be specified using a function call and the return type must be an integral value.
syntax:
cover_func:coverpoint func_call();
code snippet:
function bit[3:0] sum(int a, int b); //declaring function
int c;
c=a+b;
return c; //returning the sum value
endfunction
module func_return_value();
class val; //declaring class val
randc bit [1:0]a;
randc bit [1:0]b;
endclass
int addition;
covergroup cg; //created covergroup cg
a: coverpoint v.a;
b: coverpoint v.b;
func: coverpoint sum(v.a,v.b); //called the function in covergroup
endgroup
val v;
cg cg_inst; //instantiated covergroup cg
initial begin
v=new();
cg_inst=new();
repeat(5) begin
void'(v.randomize()); //randomizing the class variables
addition=sum(v.a,v.b); //storing function return value in addition variable
cg_inst.sample(); //sampling the covergreoup cg
$display("a = %d, b = %d; add = %d",v.a,v.b,addition);
$display("\tcoverage %%=%0.2f",cg_inst.get_inst_coverage());
end
end
Here the function func is calling inside the covergroup whenever the covergroup is sampled and then calculates the coverage percentage of the coverpoint func.
output snap:
- coverage report
In this example the coverpoint is specified using the function call sum(). The return value of the function has 4 bits, therefore the maximum number of possible values will be 2^4=16.The coverpoint func will calculate the coverage percentage of the function call whenever covergroup is sampled.
coverpoints using part select#
coverpoints can be specified by selecting part of the variable like addr[31:4].
- syntax:
cover_part: coverpoint addr[31:4];
- code snippet:
bit [2:0] a;
covergroup cg; //created covergroup cg
a1:coverpoint a[1:0]; //declaring coverpoint a1 with 'a' has 2 bits from LSB
a2:coverpoint a[0]; //declaring coverpoint a2 only with LSB
a3:coverpoint a[2:1]; //declaring coverpoint a3 with 'a' has 2 bits from MSB
endgroup
cg cg_inst; //covergroup cg instance
initial begin
cg_inst=new();
for(int i=0;i<5;i++) begin
a=$random; //assigining random values to a
cg_inst.sample(); //sampling the covergroup
$display("a=%d a1=%b a2=%b a3=%b",a,a[1:0],a[0],a[2:1]);
$display("\tcoverage %%=%0.2f",cg_inst.get_coverage());
end
end
In part select we can check the coverage of the selected part of the variable. Based on the number of bits selected there are 2^n auto bins are created and checks the coverage of the 2^n possible values.
- output snap:
- coverage report
In coverpoint a1, the bits are selected from the last 2 bits of ‘a’ from LSB. So for coverpoint a1 has 2^2=4 possible values. For coverpoint a2, the [0] bit is selected, therefore a2 has 2^1=2 possible values. For coverpoint a3, the 2 bits are selected from the MSB, therefore it has 4 possible values. Based on the values covered by each covergroup the coverage percentage will be calculated.
Coverage Bins#
Coverpoint must be declared inside the cover group, it can contain one or more coverage points. A coverage point can be an integral variable or an expression. Each coverage point is associated with “bins”.
Coverage-point bin associates a name and a count with a sequence of values or a set of values transitions. If the bin selects a set of values, the count is incremented every time the coverage point matches one of the values in the set. If the bin selects a sequence of value transitions, the count is incremented every time the coverage point matches the entire sequence of value transitions.
- Syntax:
Coverpoint_name: coverpoint variable{bins bin 1 = {values};
....
{bins bin N = {values};}
- Types of Bins
- Automatic or Implicit bins
- Explicit bins
- Transition bins
- Wildcard bins
- Ignore bins
- Illegal bins
Bins can be created implicitly(automatic) or explicitly.
1. Automatic or Implicit bins#
While defining cover points, if you are not specifying any bins, then it creates automatic bins for cover points. The number of bins created can be controlled by auto_bin_max
parameter.
- Syntax:
Coverpoint_name: coverpoint variable;
- Example:
Let’s take an example of an implicit bin for better understanding.
module implicit_bin;
bit [2:0] a;
covergroup cov_grp;
c1 : coverpoint a;
endgroup
cov_grp cg = new();
initial
begin
for(int i=1;i<=5;i++)
begin
a=$random;
cg.sample();
$display("a=%d, coverage = %0.2f %%",a,cg.get_inst_coverage());
end
end
endmodule
Here variable ‘a’ can have 8 values that are [0-7]. Here automatic bins are created.
- Output snap:
The below figure shows the output of the implicit bin.
- coverage report
Fig 14: Coverage Report Of Automatic or Implicit bins
Here bins will be automatically created, since it has 8 values 8 bins will be created.
- During 1st iteration a=4, coverage of c1 is (1/8)*100 = 12.50%.
- During 2nd iteration a=1, coverage of c1 is (2/8)*100 = 25%. (because in the previous iteration one value has been covered so in this iteration we will consider as 2)
- During 3rd iteration a=1, coverage of c1 is (2/8)*100 = 25% (because a=1 is already covered).
- During 4th iteration a=3, coverage of c1 is (3/8)*100 = 37.50%.
- During 5th iteration a=5, coverage of c1 is (4/8)*100 = 50%.
2. Explicit bins#
The bins
keyword is used to declare the bins explicitly to a variable.
Explicit bin creation is recommended method. Not all values are interesting or relevant in a cover point, so when a user knows the exact values going to cover, then a user can use explicit bins. Explicit bins are declared within curly braces { } along with the bins keyword followed by bin name and variable value/range, immediately after the coverpoint identifier.
- Syntax:
Coverpoint_name: coverpoint variable{bins bin_name = {values};}
- Example:
Let’s take an example of an explicit bin for better understanding.
module explicit_bin;
bit [2:0] a;
covergroup cov_grp;
c1 : coverpoint a{
bins b1={2};
bins b2={3};
}
endgroup
cov_grp cg = new();
initial
begin
for(int i=1;i<=5;i++)
begin
a=$random;
cg.sample();
$display("a=%d, coverage = %0.2f %%",a,cg.get_inst_coverage());
end
end
endmodule
Here variable ‘a’ can have 8 values that are [0-7], for ‘a’ variable c1 is the cover-point which has two bins- b1=2 and b2=3.
When ‘a’ gets any of this bin value that particular bin is considered a hit.
- Output Snap:
The below figure shows the output of the explicit bin.
- Coverage report
The denominator depends on the number of bins, since only 2 bins are given here so the denominator is considered as 2.
- During 1st iteration a=4, coverage of b1 is (0/1)*100=0% and b2 is (0/1)=0%, so the average of b1 and b2 is the coverage of c1 that is (0/1+0/1)*100=0%.
- During 2nd iteration a=1, coverage of b1 is (0/1)*100=0% and b2 is (0/1)=0%, so the average of b1 and b2 is the coverage of c1 that is (0/1+0/1)*100=0%.
- During 3rd iteration a=1, coverage of b1 is (0/1)*100=0% and b2 is (0/1)=0%, so the average of b1 and b2 is the coverage of c1 that is (0/1+0/1)*100=0%.
- During 4th iteration a=3, coverage of b1 is (0/1)*100=0% and b2 is (1/1)*100=100%, so the average of b1 and b2 is the coverage of c1 that is (0/1+1/1)*100=50%.
- During 5th iteration a=5, coverage of b1 is (0/1)*100=0% and b2 is (0/1)=0%, so the average of b1 and b2 is the coverage of c1 that is (0/1+0/1)*100=50%.
3. Transition bins#
A transitional functional point bin is used to examine the legal transitions of a value. SystemVerilog allows specifies one or more sets of ordered value transitions of the coverage point.
- Syntax:
covergroup cg;
c1: coverpoint a;
{
bins u[] = (value1=>value2);
}
- Type of Transitions:
- Single Value Transition
- Sequence Of Transitions
- Set Of Transitions
- Consecutive Repetitions
- Range Of Repetition
- Goto Repetition
Single value transition:
Single value transition is specified as < value1 > => < value2 >,value 1 is followed bt value 2.Syntax:
coverpoint_name: coverpoint variable {bins bin 1 = (value1 => value2);
...
bins bin N = (value1 => value2); }
- Example:
Let’s take an example of a single value transition bin for better understanding.
module single_val_tran_bin;
bit [0:3] a;
bit [0:2] values[$]= '{1,2,3,4};
covergroup cov_grp;
c1 : coverpoint a{
bins tran_1 = (1=>2);
bins tran_2 = (3=>4);
}
endgroup
cov_grp cg = new();
initial
begin
foreach(values[i])
begin
a=values[i];
cg.sample();
$display("val=%d, cov = %0.2f %%",a,cg.get_inst_coverage());
end
end
endmodule
In the above example for the ‘a’ variable, there are two bins trans_1 and trans_2. 2 bins were created for covering the transition of ‘a’, from 1 to 2 and 3 to 4.
- Output snap:
The below figure shows the output of the single-value transition bin.
- coverage report
When val=1 then the coverage will be 0% (because still there is no transition completed)
When val=2 then the coverage will be 50% (because the transition from 1 to 2 of trans_1 has been completed that is 100, so the average of val 1 and val 2 is 50%)
When val=3 then the coverage will be 50% (because still there is no transition, so it takes the coverage of the previous one)
When val=4 then the coverage will be 100% (because the transition from 3 to 4 of trans_2 has been completed)
Sequence of transition:
Sequence of transitions is specified as < value1 > => < value2 > => < value3 > => < value4 >, value 1 is followed by value 2, followed by value 3 and followed by value 4.Syntax:
coverpoint_name: coverpoint variable {bins bin 1 = (value 1 => value 2 => value 3);
...
bins bin N = (value 1 => value 2 => value 3 => value 4); }
- Example:
Let’s take an example of a sequence of transition bins for better understanding.
module sequence_of_trans_bin;
bit [0:2] a;
bit [0:2] values[$] = '{1,2,3,4};
covergroup cov_grp;
c1 : coverpoint a {
bins tran_1 = (1=>2=>3);
//bins tran_2 = (1=>2=>4);
}
endgroup
cov_grp cg = new();
initial
begin
foreach(values[i])
begin
a = values[i];
cg.sample();
$display("val=%d,cov = %.2f %%",a,cg.get_inst_coverage());
end
end
endmodule
In the above example, 2 bins are created for covering the transition of point ‘a’ from 1 to 2 to 3 and another for 1 to 2 to 4.
- Output snap:
The below figure shows the output of the sequence of the transition bin.
- coverage report
Set of transition:
The set of transitions is specified as <transition_set1> => <transition_set2>Syntax:
coverpoint_name: coverpoint variable {bins bin 1[] = (transition_set 1 => transition_set 2); }
- Example:
Let’s take an example of a set of transition bins for better understanding.
module set_of_trans_bin;
bit [0:3] a;
bit [0:2] values[$]= '{1,2,3,4,5};
covergroup cov_grp;
c1 : coverpoint a {
bins tran_1 = (1,2=>3,4);
bins tran_2 = (3,4=>5);
bins tran_3 = (1,3=>4);
}
endgroup
cov_grp cg = new();
initial
begin
foreach(values[i])
begin
a = values[i];
cg.sample();
$display("val=%d,cov = %.2f %%",a,cg.get_inst_coverage());
end
end
endmodule
In the above example, bin trans creates 3 bin for covering 1=>3, 2=>3, 1=>4, 2=>4, 3=>5, 4=>5 and 3=>4. .
- Output Snap:
The below figure shows the output of the set of transition bins.
- Coverage report
When val=1, the coverage will be 0% (because still the bin transition is not completed)
When val=2, the coverage will be 0% (because still the bin transition is not completed)
When val=3, the coverage will be 33.33% (because the bin transition is completed)
When val=4, the coverage will be 66.67% (because the bin transition is completed)
When val=5, the coverage will be 100% (because the bin transition is completed)
Consecutive Repetitions:
The range of repetition is specified as <transition_value> [*< repeat_value >]Syntax:
coverpoint_name: coverpoint variable {bins bin 1[] = (transition_value[*< return_value >]); }
- Example:
Let’s take an example of consecutive repetitions bin for better understanding.
module consec_repeat_bin;
bit [0:3] a;
bit [0:2] values[$]= '{2,2,4,4,4};
covergroup cov_grp;
c1 : coverpoint a {
bins tran_1 = (2[*2]);
bins tran_2 = (4[*3]);
}
endgroup
cov_grp cg = new();
initial
begin
foreach(values[i])
begin
a = values[i];
cg.sample();
$display("val=%d,cov = %.2f %%",a,cg.get_inst_coverage());
end
end
endmodule
Here, trans_item is repeated for repeat_range times, that is 2[*2] is the same as 2=>2 and 4[*3] is the same as 4=>4=>4.
- Output snap:
The below figure shows the output of the consecutive repetitions bin.
- Coverage Report
Fig 20:Coverage Report Output Of Consecutive Repetitions
Range of repetition:
The range of repetition can be specified as <transition_value> [*<repeat_range>]Syntax:
coverpoint_name: coverpoint variable {bins bin 1[] = (transition_value[*< return_value >]); }
- Example:
Let’s take an example of a range of repetitions bin for better understanding.
module range_of_repeat_bin;
bit [0:3] a;
bit [0:2] values[$]= '{2,3,2,2,2,2,4,4};
covergroup cov_grp;
c1 : coverpoint a {
bins tran_1 = (2[*3:5]);
bins tran_2 = (4[*3]);
}
endgroup
cov_grp cg = new();
initial
begin
foreach(values[i])
begin
a = values[i];
cg.sample();
$display("val=%d,cov = %.2f %%",a,cg.get_inst_coverage());
end
end
endmodule
An example of a range of repetition is 2 [* 3:5] is the same as 2=>2=>2, 2=>2=>2=>2, 2=>2=>2=>2=>2
- Output Snap:
The below figure shows the output of the range of repetitions bin.
- Coverage Report
Goto repetition:
The goto repetition is specified using trans_item [-> repeat_range].
Repeat_range is specified for the required number of occurrences of a particular value. Any number of sample points can occur before the first occurrence of the specified value and any number of sample points can occur between each occurrence of the specified value. The transition following the goto repetition must immediately follow the last occurrence of the repetition.Syntax:
coverpoint_name: cover-point variable {bins bin 1[] = (transition_item[->repeat_range]); }
- Example:
Let’s take an example of the goto repetitions bin for better understanding.
module goto_repeat_bin;
bit [0:3] a;
bit [0:2] values[$]= '{1,2,3,4,3,4,2,3,4,5};
covergroup cov_grp;
c1 : coverpoint a {
bins tran_1 = (1=>4[->3]=>5);
//bins tran_2 = (1=>3[=3]=>4);
}
endgroup
cov_grp cg = new();
initial
begin
foreach(values[i])
begin
a = values[i];
cg.sample();
$display("val=%d,cov = %.2f %%",a,cg.get_inst_coverage());
end
end
endmodule
- Output snap:
The below figure shows the output of the goto repetitions bin.
- Coverage report
Non-consecutive repetition:
The non-consecutive repetition can be specified as <transition_value> [= <repeat_range>]Syntax:
coverpoint_name: coverpoint variable {bins bin 1 = (transition_value[= < repeat_range >]=> value); }
4. Wildcard bins#
The wildcard
keyword is used for creating multiple states and transitions. In the expression, X, Z, or ? are considered wildcards for 0 or 1. Wildcard bins can also be defined as transition bins.
- Syntax:
wildcard bins p = {4’b11??};
- Example:
Let’s take an example of a wildcard bin for better understanding.
module wildcard_bin;
bit [0:3] a;
bit [0:3] values[$]= '{4'b1000,4'b1001,4'b1010,4'b1011};
covergroup cov_grp;
c1 : coverpoint a {
wildcard bins b1 ={4'b100x};
wildcard bins b2 ={4'b101x};
}
endgroup
cov_grp cg = new();
initial
begin
foreach(values[i])
begin
a = values[i];
cg.sample();
$display("val=%d,cov = %.2f %%",a,cg.get_inst_coverage());
end
end
endmodule
- Output snap:
The below figure shows the output of the wildcard bin.
coverage report
5. Ignore bins#
A set of values or transitions related to a coverage point can be explicitly excluded from coverage by specifying them as ignore_bins.
- Syntax:
ignore_bins ivals = {value1, value3};
ignore_bins itrans = (value1=>value3=>value5); }
- Example:
Let’s take the example of ignore bin for better understanding.
module ignore_bin;
bit [0:1] a;
bit [0:1] values[$]= '{0,1,2,3};
covergroup cov_grp;
c1 : coverpoint a {
ignore_bins b1 ={1,2};
}
endgroup
cov_grp cg = new();
initial
begin
foreach(values[i])
begin
a = values[i];
cg.sample();
$display("val=%d,cov = %.2f %%",a,cg.get_inst_coverage());
end
end
endmodule
In the above example, the total possible values for ‘a’ are 0 to 3. Ignore_bins specified to ignored values 1 and 2. So the Expected values are 0 and 3. Out of these expected values, only 0 and 3 are generated.
- Output snap:
The below figure shows the output of the ignore bin.
coverage report*
In the above example value 1 and value 2 are considered to be ignored that is whenever ‘a’ hits that value it will take the previous coverage.
- When a = 0, covearge of c1 is (1/2)*100= 50% (value 0 is not ignored)
- When a = 1, covearge of c1 = 50% (value 1 is ignored, it takes previous coverage)
- When a = 2, covearge of c1 = 50% (value 2 is ignored, it takes previous coverage)
- When a = 3, covearge of c1 is (2/2)*100= 100% (value 3 is not ignored)
6. Illegal bins#
A set of values or transitions associated with a coverage point can be marked as illegal by specifying them as illegal_bins. All values or transitions associated with illegal bins are excluded from coverage. If an illegal value or transition occurs, a runtime error is issued.
- Syntax:
illegal_bins bad_vals = {value1, value3, value4, value6};
illegal_bins bad_trans = (value2=>value1=>value9, value5=>value3); }
- Example:
Let’s take an example of an illegal bin for better understanding.
module illegal;
bit [0:2] y;
bit [0:2] values[$]= '{1,6,3,7,3,4,3,5};
covergroup cg;
cover_point_y : coverpoint y {illegal_bins b1 = {7};
}
endgroup
cg cg_inst = new();
initial
begin
foreach(values[i])
begin
y = values[i];
cg_inst.sample();
$display("val =%d, cov = %0.2f %%",y,cg_inst.get_inst_coverage());
end
end
endmodule
- Output snap:
The below figure shows the output of the illegal bin.
- Coverage report
In the above example value 7 is considered to be illegal, so when value 7 is hit we will get an error as “Illegal state bin was hit at value=1”.
Git lab code link: https://github.com/muneeb-mbytes/SystemVerilog_Course/blob/production/functional_coverages/bins/illegal_bin/illegal_bin.sv
Git lab output link: https://github.com/muneeb-mbytes/SystemVerilog_Course/blob/production/functional_coverages/bins/illegal_bin/illegal_bin.log
Coverage Options:#
Coverage options control the behavior of the covergroup, coverpoint, and cross. You can specify additional information in the cover group using options. Option method can be specified either for a particular instance or for the entire instances of the program.
1. at_least : This is one of the important option that can be defined inside a coverpoint. By using option.at_least we can identify the features which have coveraed for particular number of cycles. Default value of at_# Coverage Options:
Coverage options control the behavior of the covergroleast is ‘1’.
For example, if there is a variable whose values ranges from 0-7(3-bit), during cover group execution if a particular value is assigned for 2 cycles and rest all are assigned only once. Then use option.at_least
=2, which covers the values which have assigned atleast for 2 cycles.
2. auto_bin_max
This option specifies the number of bins that should be created by coverpoint, only when the bins are not defined explicitly. The default value of auto_bin_max is 64. For example, 128 values are generated for any variable(6- bit data) then it will automatically create only 64 bins and for each bin there will be 2 values assigned they are [0:1],[2:3],[4:5],……..[124:125],[126:127]. You can even create 128 bins using option.auto_bin_max
= 128.
For example, if there is a variable whose values ranges from 0-7(3-bit), during cover group execution there will be 8 bins generated implicitly. But that can be altered and user can set the number the of bins by using option.auto_bin_max
. If option.auto_bin_max=2, only 2 bins are created implicitly instead of 8 bins and whose range are [0:3] for auto[0] and [4:7] for auto[1].
**NOTE :**You can create any number of bins by option.auto_bin_max
.
3. weight :
This options specifies the weightage of a particular coverpoint by multiplying the weight value with the cover point percantage. Using this option accounts for overall coverage percentage but not for coverpoint percentage. If we specify option.weight=0 , we are making that cover point percentage to be multiplied with 0, then that coverpoint percentage will be zero.
By default the weight of cover point is 1.
- Formula
overall percentage = (sum of all cover point)/sum of all weights.
Where, sum of all cover point refers to addition of all cover points multiplied with its weight. . sum of all weights refer to the addition of weights of all cover points.
Example:
covergroup cgrp;
c1: coverpoint s.a {bins b1 = {1};
bins b2 ={3};
option.at_least=2;}
c2: coverpoint s.a {option.weight=2;}
c3: coverpoint s.b{option.auto_bin_max=2;}
endgroup
Here in this snippet the cover group options are defined for some particular cover points. option.at_least
considers only that values which have covered atleast for 2 cycles , option.weight
is defined for cover point c2 which alters the overall coverage by multiplying the coverpoint percent with 2 and option.auto_bin_max
is used to generate only 2 bins for the coverpoint c3. The range of first bin is from [0:7] and second bin is [8:15].
In this example, weight of c1 is 1(default_value) , weight of c2 is 2(specified using option) and the weight of c3 is 1(default_value).
output snap:
Here variable a can have 8 values that is [0-7] and variable ‘b’ can have 16 values that is [0-15].Coverage depends on the options used in different coverpoints.
During 1st iteration a=0 and b=8; For cover point c1, values inside bins must be iterated for atleast 2 cycles till now no bin is covered. Hence coverage of c1 is (0/2)100 = 0% ; coverage of c2 is (1/8) = 12.5% {for over all percentage (12.52) i,e 25%}; coverage of c3 is (auto[0]+auto[1])/2 ,therefore {1/2}*100 = 50% ; overall percentage is sum of coverpoints/sum of weigth ,(0+25+50)/4 = 18.75%
During 2nd iteration a=1 and b=6; coverage of c1 is (0/2) = 0% ; coverage of c2 is (2/8) = 25% {for over all percentage (25*2) i,e 50% }; coverage of c3 is (2/2)*100 = 100 % ; overall percentage is (0+50+100)/4= 37.50% .
During 3rd iteration a=1 and b=8; coverage of c1 is (1/2) = 50% ; coverage of c2 is (2/8) = 25% {for over all percentage (25*2) i,e 50% }; coverage of c3 is (2/2)*100 = 100 % ; overall percentage is (50+50+100)/4= 50% .
During 4th iteration a=3 and b=4; coverage of c1 is (1/2) = 50% ; coverage of c2 is (3/8) = 37.5% {for over all percentage (37.5*2) i,e 75% }; coverage of c3 is (2/2)*100 = 100 % ; overall percentage is (50+75+100)/4 = 56.25%
During 5th iteration a=4 and b=4; coverage of c1 is (1/2) = 50% ; coverage of c2 is (4/8) = 50% {for over all percentage (50*2) i,e 100% }; coverage of c3 is (2/2)*100 = 100 % ; overall percentage is (50+100+100)/4 = 62.50%
Coverage Report