Coverage is a critical concept in System Verilog, especially in the verification domain of VLSI (Very Large Scale Integration) design. It plays an essential role in ensuring that the design being verified has been thoroughly tested and that all the functional aspects of the design are covered by the test cases. Coverage helps in identifying the untested areas of a design and provides confidence that the verification is exhaustive and accurate.
In this article, we will explore the different types of coverage, specifically code coverage and functional coverage, as well as key System Verilog constructs like cove groups, bins, and the types of bins used in functional coverage.
What is Coverage?
In VLSI verification, coverage is the measure of how much of the design or functionality has been exercised during simulation. It acts as a quality metric for verification by telling how much of the design space or feature set has been covered by the test cases. There are primarily two main types of coverage:
- Code Coverage: This focuses on how much of the source code has been tested during simulation.
- Functional Coverage: This ensures that the functionality specified by the design specifications has been validated.
Code Coverage
Code coverage is a technique used to determine how much of the actual HDL (Hardware Description Language) code has been executed during the verification process. It provides insights into the structural aspects of the design, ensuring that each line of the code has been tested. This can help identify areas of the design that are not well-tested or are never executed.
There are several types of code coverage metrics that tools measure:
- Statement Coverage: This type measures the number of lines or statements of the code that are executed during a simulation. If a statement is never executed, the code coverage tool will highlight it as an uncovered part.
- Branch Coverage: Branch coverage tracks whether all possible branches of decision-making constructs, like
if-elsestatements, have been tested. It ensures that both thetrueandfalsepaths of a decision statement have been exercised. - Condition Coverage: This metric checks whether all the boolean sub-expressions within a decision statement have been evaluated to both
trueandfalse. - FSM (Finite State Machine) Coverage: FSM coverage focuses on whether all the states of a state machine have been reached and all the transitions between those states have been exercised.
Functional Coverage
Functional coverage is more focused on validating whether the functionality of the design has been properly verified against the specification. Unlike code coverage, functional coverage measures how much of the design’s intended behavior has been tested, not just how much of the code has been executed.
Functional coverage is user-defined, meaning it needs to be specified based on what functions or features of the design are important. It is typically captured using covergroups and bins.
Covergroups in SystemVerilog
A covergroup is a System Verilog construct that is used to define functional coverage. It contains coverage points and bins that specify what to monitor during simulation.
- Covergroup Syntax
covergroup cg_name @(posedge clk);
// Coverage points go here
coverpoint data;
endgroup
//Instantiation of covergroup
cg_name cg = new();
Once the covergroup is defined, it can be instantiated and sampled during simulation to track the coverage data. Coverpoints in covergroup can be sampled in two ways.
- Using a clocking event at which coverpoints will be sampled. Used in above example.
- Using a built-in sample method, sampling is triggered.
covergroup cg_name;
// Coverage points go here
coverpoint data;
endgroup
//Instantiation of covergroup
cg_name cg = new();
@(xyz) cg.sample();
Key Components of a Covergroup:
- Coverpoints: These are specific points within the design that you want to monitor. For example, a coverpoint might track the value of a signal or a specific condition.
Example:
coverpoint signal_name {
bins bin_name = {range};
}
- Bins: A bin is used to categorize the values of a coverpoint. For example, bins might group different ranges of values of a signal, and functional coverage tools will report on how many times each bin has been hit during simulation.
Types of Bins
SystemVerilog supports different types of bins to help monitor various aspects of functional coverage.
- Automatic Bins or Implicit Bins: SystemVerilog automatically creates bins for all the values that a coverpoint can take. For example, for a 2-bit signal, SystemVerilog can automatically generate bins for values
00,01,10, and11. It means for a ‘n’ bit, a 2^n no of automatic bins will be created. - Explicit Bins: Users can define their own bins for specific values or ranges. This gives more control to the verification engineer over which values or ranges are of interest. Example:
coverpoint signal_name {
bins low = {0}; //single bin for value = 0
bins a1 = {[1:3]}; // single bin construct for value 1,2,and 3
bins high[3] = {[4:7]}; // create 4 bins high[0], high[1], high[2] and high[3] with values 4,5,6 and 7 respectively
bins a2 = {[10:15],[16:20],22}; //single bin for value 10-15,16-20 and 22
bins a3[] = {25,26,27}; //create 3 bins a3[0], a3[1] and a3[2] with values 25,26 and 27
}
3. Wildcard Bins: Wildcard bins allow the grouping of values based on wildcard expressions. These bins match any value that fits the wildcard pattern.
Example:
coverpoint signal_name {
wildcard bins low = {2'b00, 2'b01}; // Matches '00' or '01'
}
4. Ignore Bins: Ignore bins are used to exclude certain values from coverage calculations. If there are some values or conditions that you do not want to track, you can place them in ignore bins.
5. Illegal Bins: These are used to specify illegal values or conditions that should never occur in the design. Hitting an illegal bin during simulation would indicate a serious issue, as it would mean an unintended or erroneous state has been reached.
Example:
coverpoint signal_name {
illegal_bins error_state = {4'b1111}; // Should never occur
}
6. Transition Bins: Transition bins are used to track how a variable transitions between specific values or states. This allows you to monitor not just the occurrence of individual values but the changes or sequences between values.
- Single-Transition Bins:
- Track transitions from one value to another.
- Example: Transition from
0to1or1to0.
- Multi-Transition Bins:
- Track sequences of transitions over multiple states.
- Example: Transition from
0 -> 1 -> 3.
- Usage:
- Defined using the
=>operator in coverpoints. - Useful for ensuring specific state sequences or events occur during simulation.
- Defined using the
Example:
module tb;
bit [1:0] test_var;
// Coverage group
covergroup cg_transitions;
coverpoint test_var {
bins transitions = (0 => 1), (1 => 2), (2 => 3), (3 => 0);
}
endgroup
cg_transitions cov;
initial begin
cov = new;
// Stimulate the variable
repeat (10) begin
#10 test_var = $urandom_range(0, 3);
cov.sample();
end
end
endmodule
