Why is it necessary ?

Functional coverage is a measure of what functionalities/features of the design have been exercised by the tests. This can be useful in constrained random verification (CRV) to know what features have been covered by a set of tests in a regression.

What are its limitations ?

This is only as good as the code written for it. Say you have 10 features mentioned in the design document, and you somehow overlooked/missed or were not aware of 3 features, you'll write functional coverage code for only 7 of them. And if all the 7 have been hit in the tests, you might come to the conclusion that all the features are covered. So, you need to make sure that all the required information from the design specification is included in the functional coverage block.

How do you do it ?

The idea is to sample interesting variables in the testbench and analyze if they have reached certain set of values.

module test;
  bit [3:0] mode;
  bit [1:0] key;
  // Other testbench code
mode can take 16 values, while key can take 4 values. So, if there's something to monitor these two variables in a simulation and report what values of mode and key have been exercised, you'll know if the test covered a particular feature or not. The good part is that there are options in a simulator to dump out such coverage details into a file so that it can be reviewed after the simulation has finished. Moreover, you can merge all such coverage files from different tests into a single database and review them as a whole. If test A covered feature X and test B covered feature Y, the merged database will show that you have covered both X and Y.

What's the code for functional coverage ?
class myTrns;
  rand bit [3:0]   mode;
  rand bit [1:0]   key;
   function display ();
      $display ("[%0tns] mode = 0x%0h, key = 0x%0h", $time, mode, key);
  covergroup CovGrp;
    coverpoint mode {
      bins featureA   = {0};
      bins featureB   = {[1:3]};
      bins common []   = {4:$};
      bins reserve  = default;
    coverpoint key;


  • Variables are mentioned as a coverpoint.
  • Coverpoints are put together in a covergroup block.
  • Multiple covergroups can be created to sample the same variables with different set of bins
  • bins are said to be "hit/covered" when the variable reaches the corresponding values. So, the bin featureB is hit when mode takes either 1,2 or 3.
  • bin reserve is a single bin for all values that do not fall under the other bins.
  • common will have 4 separate bins, one for each value.

I ran the simulation and I don't see any bins. Why is that ?

You have to enable the tool vendor specific command-line switch to dump coverage details. Then open a coverage viewer tool like Cadence ICCR/IMC and open the coverage dump file.

How do I mention when to sample ?

There are two ways to trigger coverage collection in a covergroup.

  • Use sample() method of a particular covergroup to sample coverpoints within that group.
    class myCov;
      covergroup CovGrp;
      function new ();
        CovGrp = new;           // Create an instance of the covergroup
    module tb_top;
      myCov myCov0 = new ();     // Create an instance of the class
      initial begin
        myCov0.CovGrp.sample ();
  • Mention the event at which the covergroup should be sampled
    covergroup CovGrp @ (posedge clk);     // Sample coverpoints at posedge clk
    covergroup CovGrp @ (eventA);       // eventA can be triggered with ->eventA;

Any way to specify conditional coverage ?

Yes, you have two ways to conditionally enable coverage.

  • Use iff construct
    covergroup CovGrp;
      coverpoint mode iff (!_if.reset) {
          // bins for mode
  • Use start and stop functions
    CovGrp cg = new;
    initial begin
      #1 _if.reset = 0;
      cg.stop ();
      #10 _if.reset = 1;

Was this article helpful ?