Coverpoint in Functional Coverage
A coverpoint is an integral expression or variable that has to be covered on sampling the covergroup. A covergroup can have one or more coverage points that can be labeled. Each coverpoint is associated with single or multiple bins that can be explicitly defined.
In simple words:
– The coverpoint tells us what to observe.
– The bins tell us which values are important.
– Sampling tells us when to observe the value.
Syntax:
covergroup <covergroup_name>;
<coverpoint label>: coverpoint <variable_or_expression>;
<coverpoint label>: coverpoint <variable_or_expression>;
...
endgroup
//Example:
covergroup cg @(posedge clk);
cp1: coverpoint addr;
cp2: coverpoint data;
endgroup : cg The label is not compulsory, but meaningful labels make coverage reports much easier to read.
Coverpoint Example
module coverpoint_example;
logic clk;
logic [3:0] addr;
logic [2:0] data;
covergroup bus_cg @(posedge clk);
cp_addr: coverpoint addr;
cp_data: coverpoint data;
endgroup
bus_cg bus_cov = new();
endmodule At every positive edge of `clk`:
– `cp_addr` samples the current value of `addr`.
– `cp_data` samples the current value of `data`.
Because no bins are explicitly declared, the simulator creates automatic bins.
Bins in functional coverage
A bin is a coverage bucket. When a sampled value belongs to a bin, the hit count of that bin increases.
Suppose a two-bit signal can have values 0, 1, 2, and 3. If the coverage model has one bin for each value, sampling value 2 increases the hit count of the bin that represents value 2. Bins help us see which values occurred and which values are still missing.
The construct bins provide a facility to create a set of bins for a particular range or all possible values in the range for the mentioned coverpoint variable.
- The bins can be generated automatically or explicitly written by an engineer.
- They can be excluded or ignored from the coverage.
- They can also be marked as illegal.
Syntax:
covergroup <covergroup_name>;
<coverpoint label>: coverpoint <coverpoint_name> {bins <bin_name> = {<values>} };
...
endgroup Automatic Bins
When a coverpoint does not contain an explicit bin declaration, SystemVerilog creates automatic bins.
module automatic_bins_example;
logic [3:0] addr;
logic [2:0] data;
logic en;
covergroup automatic_cg;
cp_addr: coverpoint addr;
cp_data: coverpoint data;
cp_en: coverpoint en;
endgroup
automatic_cg automatic_cov = new();
initial begin
addr = 4'd5;
data = 3'd3;
en = 1'b1;
automatic_cov.sample();
end
endmodule
Since bins are not 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], cp3.auto[1] |
When sample() is called:
- The bin for address 5 is hit.
- The bin for data 3 is hit.
- The bin for enable 1 is hit.
For a large integral range, the simulator limits and distributes automatic bins according to the auto_bin_max option. Use explicit bins when the values need to be grouped according to the specification.
Explicit bins
Explicit bins allow the verification engineer to decide how values should be grouped.
Syntax:
covergroup <covergroup_name>;
<label>: coverpoint <variable_or_expression> {
bins <bin_name> = {<values_or_ranges>};
}
endgroup
Explicit bins are useful for:
- Important individual values
- Boundary values
- Groups of related values
- Small, medium, and large ranges
- Legal, ignored, or illegal values
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:7};
}
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 9 bins i.e. |
|
|
bins b3[4] = {0:7}; |
Constructs 4 bins with possible values as b3[2] = 4~5, b3[3] = 6~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 |
Common Mistakes
Expecting a List to Create Separate Bins
bins selected = {1, 10, 12}; This creates one bin containing three values. To create a separate bin for each value, use an unsized bin array:
bins selected[] = {1, 10, 12}; Writing a Range Without Square Brackets
Incorrect: bins groups[4] = {0:7};
Correct: bins groups[4] = {[0:7]};
Using a Comma When a Range Is Intended
bins upper = {4, $};
This lists two values: 4 and the maximum value. To include every value from 4 through the maximum, write:
bins upper = {[4:$]};
Forgetting to Sample
An eventless covergroup does not collect coverage just because a variable changes. Call its sample() method after assigning the values to be measured.
Best Practices
- Give each coverpoint and bin a meaningful name.
- Define bins from the specification, not from convenience.
- Separate important boundary values when they need individual attention.
- Group ordinary values when individual bins would not provide useful insight.
- Sample only stable and valid transaction data.
- Avoid overlapping bins unless the overlap is intentional and documented.
- Investigate unhit bins before changing or excluding them.
Functional Coverage