Before we start with functional coverage, it is required to understand the term coverage. The coverage provides a set of metrics that are used to measure verification progress.
Need for Coverage
- As you are aware that verification is a long-lasting process and we never know what type of input stimulus can capture the bug. Hence, it is essential to have a set of metrics that decide the endpoint for verification of the design once all metrics are satisfied.
- It is also essential to see whether we verified all kinds of features supported by the design and cover every line from the design code.
Types of Coverage
There are two types of coverage supported
- Code coverage
- Functional coverage
Code coverage deals with covering design code metrics. It tells how many lines of code have been exercised w.r.t. block, expression, FSM, signal toggling.
The code coverage is further divided as
- Block coverage – To check how many lines of code have been covered.
- Expression coverage – To check whether all combinations of inputs have been driven to cover expression completely.
- FSM coverage – To check whether all state transitions are covered.
- Toggle coverage – To check whether all bits in variables have changed their states.
- Code coverage does not specify that the code behavior is correct or not. It is simply used to identify uncovered lines, expressions, state transitions, dead code, etc. in the design. Hence, it does not indicate design quality.
- Verification engineers aim to achieve 100% code coverage.
- There are industry tools available that show covered and missing code in code coverage.
Functional coverage deals with covering design functionality or feature metrics. It is a user-defined metric that tells about how much design specification or functionality has been exercised. The functional coverage can be classified into two types
- Data intended coverage – To check the occurrence of data value combinations.
Example: Writing different data patterns in a register.
- Control intended coverage – To check the occurrence of sequences in the intended fashion.
Example: Reading a register to retrieve reset values after releasing a system reset.
Since it is user-defined metrics, it is up to the verification engineer to consider all features because if some features are missed to add in functional coverage and remaining features are covered then functional coverage will show up 100% even though some cover points are missed to add.
Define a coverage model: covergroup
The covergroup is a user-defined construct that encapsulates coverage model specification. 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.
The covergroup includes
- 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 and that has to be specified in the new operator too.
covergroup cg (<list of arguments>); ... endcovergroup