To check whether the Testbench has satisfactory exercised the design or not? Coverage is used. It will measure the efficiency of your verification implementation.
Code coverage answers the questions like
Have all the lines of the DUT has been exercised?
Have all the states in the FSM has been entered?
Have all the paths within a block have been exercised?
Have all the branches in Case have been entered?
Have all the conditions in an if statement is simulated?
With the above information, verification engineer can plan for more test cases and excursive uncovered areas to find bugs.
By default, every tool disables the code coverage. If user enables then only code coverage is done. By enabling the code coverage there is overhead on the simulation and the simulation takes more time. So it is recommended not to enable the code coverage always. Enabling the code coverage during the regression saves user time a lot.
Types Of Coverage
Implementation of Testbench can be separated by following types of coverage hierarchy.
It specifies that how much deep level the design is checked. There are sub parts of the code coverage that will be discussed bellow.
Statement Coverage /Line Coverage:
This is the easiest understandable type of coverage. This is required to be 100% for every project. From N lines of code and according to the applied stimulus how many statements (lines) are covered in the simulation is measured by statement coverage. Lines like module, endmodule, comments, timescale etc are not covered.
always @(posedge clk)
begin if (a > b) statement 1
begin y = a and b; statement 2
z = a or b; statement 3
end if (a < b)
begin y = a xor b;
z = a xnor b;
end if (a == b)
begin y = not b;
z = a % b;
As seen in example those statements only will execute whose condition is satisfied. Statement coverage will only consider those statements.
The nature of the statement and block coverage looks somewhat same. The difference is that block which is covered by begin-end, if-else or always, those group of statements which is called block counted by the block coverage.
Branch / Decision / Conditional Coverage:
Branch coverage will report the true or false of the branch like if-else, case and the ternary operator (? :) statements. In bellow branch of casez, sequences of statements are given. Their execution is depending upon the implementation of stimulus. The default branch in case statement in RTL is not exercised mostly because the Design guidelines insist to mention all the branches of the case statement.
idle : casez (bus_req)
4'b0000 : next = idle;
4'b1??? : next = grant1;
4'b01?? : next = grant2;
4'b001? : next = grant3;
4'b0001 : next = grant4;
default : next = idle;
As per the case selectivity list it will check all the statements are reached or not?
Due to conditional statements like if-else, case in the design different path is created which diverts the flow of stimulus to the specific path.
Path coverage is considered to be more complete than branch coverage because it can detect the errors related to the sequence of operations. As mentioned in the above figure path will be decided according to the if-else statement According to the applied stimulus the condition which is satisfied only under those expressions will execute, the path will be diverted according to that. Path coverage is possible in always and function blocks only in RTL. Path created by more than one block is not covered. Analysis of path coverage report is not so easy task.
It is the ratio of no. of cases checked to the total no. of cases present. Suppose one expression having Boolean expression like AND or OR, so entries which is given to that expression to the total possibilities is called expression coverage.
y = (a xor b) + (c xor d);
In above example it analyzes the right and side of the expression and counts how many times it executed. The expression which involves the Boolean expression for that expression coverage will make its truth table with number of times it executed. If any expression is uncovered then table will come with plane line.
It makes assures that how many time reg, net and bus toggled? Toggle coverage could be as simple as the ratio of nodes toggled to the total number of nodes.
X or Z --> 1 or H
X or Z --> 0 or L
1 or H --> X or Z
0 or L --> X or Z
Above example shows the signal changes from one level to another. Toggle coverage will show which signal did not change the state. Toggle coverage will not consider zero-delay glitches. All types of transitions mentioned above are not interested. Only 1->0 and 0->1 are much important. This is very useful in gate level simulation.
After the one step of toggle coverage variable coverage comes. Both the coverage looks same but there is a minor different between them is toggle coverage works on gate level but it fail on large quantity. For entity like bus we use variable coverage.
Triggering / Event Coverage:
Events are typically associated with the change of a signal. Event coverage checks the process whenever the individual signal inside the sensitivity list changes.
EXAMPLE: always @(a or b or c)
if ((a & b) | c)
x = 1'b 1;
else x = 1'b 0;
As per the change in above sensitivity list whether the process is triggered or not.
It works on the specification which is defined in the design process. If you have implemented 30bit design instead of 32bit, here code coverage check for the functionality while if your design is parameterized then parameter coverage will give error which shows size mismatch.
It works on the functional part of the stimuli's implementation. Functional coverage will check the overall functionality of the implementation. Verilog does not support functional coverage. To do functional coverage, Hardware verification languages like SystemVerilog, Specman E or Vera are needed.
Fsm Coverage :
It is the most complex type of coverage, because it works on the behavior of the design. In this coverage we look for how many times states are visited, transited and how many sequence are covered. Thats the duty of FSM coverage.
It gives the coverage of no. of states visited over the total no. of states. Suppose you have N number of states and state machines transecting is in between only N-2 states then coverage will give alert that some states are uncovered. It is advised that all the states must be covered.
It will count the no. of transition from one state to another and it will compare it with other total no. of transition. Total no. of transition is nothing but all possible no. of transition which is present in the finite state machine. Possible transition = no. of states * no. of inputs.
suppose your finite state machine detects the particular sequences. So there is more than 1 possibilities of sequences through which your desired output can be achieved. So here sequence coverage will check which sequence is covered and which is missed? This is a small and corner problem but stimulus should be such a way that all the possibilities must be covered.
Coverage tool should have following features:
Capability to merge reports generated by different test cases.
Capability to disable specified block,statement,module,signal.
A GUI report for easy analysis.
Capability to enable or disable any type of coverage.
User options for default branch in case statement coverage.
Limitation Of Code Coverage:
Coverage does not know anything about what design supposed to do. There is no way to find what is missing in the code. It can only tell quality of the implementation. Sometime we get the bug because of the incorrectly written RTL code. If we found that all the lines of the code are used, it doesn't mean that we have tasted all the lines. Sometimes we want the 2nd input of the mux but due to mistake in stimulus if it has taken 1st during that cycle. So whether we got he correct data or not? This cannot tell by coverage. Thats depend on us weather we are feeding correct stimulus or not?
so remember "VERIFICATION IS NOT COMPLETED EVEN AFTER 100% CODE COVERAGE"