Functional Coverage And Basic Examples

     Hello , so in this blog post we will see what is functional coverage is and some basic examples of it. first lets understand what coverage is in verification process. Coverage is used to measure tested and untested portions of the design. Coverage is defined as the percentage of verification objectives that have been met.

There are two types of coverage 1)Functional coverage and 2)Code coverage. we will see functional coverage.

//what is functional coverage?
    Functional coverage is a user-defined metric that measures how much of the design specification has been exercised in verification.

// simple example
    In below example we will see whether all possible combinations of variable "sel" is covered or not during simulation. since functional coverage is user defined we have to write covergroup and coverpoints. covergroup encapsulate coverpoint and in coverpoint we define bins for variables. there are automatc bins and explicit bins. below example is of automatic bins.

 

Simple Example To Understand Functional Coverage

// simple coverage example for understanding sunctional coverage

module tb;

    bit [3:0] sel; // 4bit , total no of possiblities = 2^4 = 16
    // in this example we will see that all 16 possible combinations
    // cover during simulation or not.
    // for that we have to first create covergroup for sel and then 
    // apply stimulus to seliable "sel"
    
    
    // covergroup for "sel"
    // syntax -> covergroup covergroup_name (input_variables) @(sampling event)
    //           . . . . 
    //           endgroup

    covergroup cg;
        option.per_instance=1;
        option.comment="covergroup for sel";
        SEL:coverpoint sel;
    endgroup

    // apply stimulus
    initial begin
        // create instance of covergroup cg
        cg inst_1 = new();

        for(int i=0 ; i<16 ;i++)
            begin
                #5;
                sel=i;
                $display("\t sel = %04b ",sel);
                inst_1.sample();
                // samples value of covergroup cg from here
            end
            #10;
            $display("--------------------------------------------------");
            $display("coverage of instance inst_1 is %f ",inst_1.get_inst_coverage());
            $display("--------------------------------------------------");
    end
endmodule

/* OUTPUT
# KERNEL:    sel = 0000 
# KERNEL:    sel = 0001 
# KERNEL:    sel = 0010 
# KERNEL:    sel = 0011 
# KERNEL:    sel = 0100 
# KERNEL:    sel = 0101 
# KERNEL:    sel = 0110 
# KERNEL:    sel = 0111 
# KERNEL:    sel = 1000 
# KERNEL:    sel = 1001 
# KERNEL:    sel = 1010 
# KERNEL:    sel = 1011 
# KERNEL:    sel = 1100 
# KERNEL:    sel = 1101 
# KERNEL:    sel = 1110 
# KERNEL:    sel = 1111 
# KERNEL: --------------------------------------------------
# KERNEL: coverage of instance inst_1 is 100.000000 
# KERNEL: --------------------------------------------------

*/


 
Coverage Report 

 
     so, as you can see from coverage report all possible value of "sel" is covered during simulation.

    //Example of explicit bins
In this example we will see how to define bins explicitly and also see ignore_bins and illegal_bins.
Example 2
module coverage_example;

    parameter           WIDTH=8;
    bit [WIDTH-1:0]     data;
    bit                 rd_wr;
    bit [(WIDTH/2)-1:0] opcode;
    bit                 clk;

    initial begin
        clk   <=0;
        data  <=0;
        rd_wr <=0;
        opcode<=0;
    end

    //  Covergroup: cg_identifier
    //
    covergroup cg @(posedge clk);
        option.per_instance=1;
        option.comment="covergroup example1";
        DATA : coverpoint data {
            option.auto_bin_max=256;
            bins hit1[] = {[1:64]};
            bins hit2[] = {[65:127]};
            bins hit3[] = {[128:254]};
            bins min    = {0};
            bins max    = {255};
        }

        RD_WR : coverpoint rd_wr{
            bins READ  = {0};
            bins WRITE = {1};
        }

        OPCODE : coverpoint opcode{
            bins add   = {4'b0001};
            bins sub   = {4'b0010};
            bins mul   = {4'b0011};
            bins div   = {4'b0100};
            bins mod   = {4'b0101};
            bins and_  = {4'b0110};
            bins or_   = {4'b0111};
            bins nand_ = {4'b1000};
            bins nor_  = {4'b1001};

            ignore_bins ignore     = {[4'b1010:4'b1110]};
            illegal_bins not_valid = {4'b1111};
 
            // when you run simulation , there wiil be error messages 
            // on console because illegal_bins not_valid is hit during
// simulation. 
        }
        
    endgroupcg
    always #5 clk=~clk;

    initial begin
      cg cov_inst = new();

      for(int i=0; i<520 ;i++) begin
            @(posedge clk);
            {data,rd_wr} = i;
            opcode=i%16;
        end
        #10;
        $display("----------------------------------------------------");
        $display("coverage is %f ",cov_inst.get_inst_coverage());
        $display("----------------------------------------------------");
        $finish;
    end
 
endmodule

/**********************  run.do  **************************
vsim +access+r;
run -all;
acdb save;
acdb report -db fcover.acdb -html -o coverage_data.html;
exit
**********************************************************/


 
ignore_bins and illegal_bins has no effect during coverage calculation, in coverage report we can see how many times they hit during simulation. illegal_bins gives error message if specified bin hit during simulation. simulate above example for result.
 
Example 3
 
module coverage_example;

    parameter           WIDTH=8;
    bit [WIDTH-1:0]     data;
    bit                 rd_wr;
    bit [(WIDTH/2)-1:0] opcode;
    bit                 clk;

    initial begin
        clk   <=0;
        data  <=0;
        rd_wr <=0;
        opcode<=0;
    end

    //  Covergroup: cg_identifier
    //
    covergroup cg;
        option.per_instance=1;
        option.comment="covergroup example1";
        
        DATA : coverpoint data {
            option.auto_bin_max=256;
            bins hit1[] = {[1:64]};
            bins hit2[] = {[65:127]};
            bins hit3[] = {[128:254]};
            bins min    = {0};
            bins max    = {255};
        }

        RD_WR : coverpoint rd_wr{
            bins READ  = {0};
            bins WRITE = {1};
        }

        OPCODE : coverpoint opcode{
            bins add   = {4'b0001};
            bins sub   = {4'b0010};
            bins mul   = {4'b0011};
            bins div   = {4'b0100};
            bins mod   = {4'b0101};
            bins and_  = {4'b0110};
            bins or_   = {4'b0111};
            bins nand_ = {4'b1000};
            bins nor_  = {4'b1001};

            ignore_bins  ignore    = {[4'b1010:4'b1110]};
            illegal_bins not_valid = {4'b1111};
 
            // when you run simulation , there wiil be error messages 
            // on console because illegal_bins not_valid is hit during
// simulation.
 
        }
        
    endgroupcg
  
    always #5 clk=~clk;

    initial begin
        cg cov_inst = new();
        cg cov_inst2 = new();
        for(int i=0; i<520 ;i++) begin
            @(posedge clk);
            {data,rd_wr} = i;
            opcode       = i%16;
            cov_inst.sample();
            if(i%2==0) cov_inst2.sample();
        end
      
        #10;
        $display("---------------------------------------------------");
        $display("coverage of cov_inst is  %f ",cov_inst.get_inst_coverage());
        $display("coverage of cov_inst2 is %f ",cov_inst2.get_inst_coverage());
        $display("---------------------------------------------------");
        $finish;
    end


endmodule

/*
# KERNEL: ---------------------------------------------------
# KERNEL: coverage of cov_inst is 100.000000 
# KERNEL: coverage of cov_inst2 is 64.814815 
# KERNEL: ---------------------------------------------------


*/
 
 
 Cross Coverage :
        Cross Coverage is specified between the cover points or variables. Cross coverage is specified using the cross construct.see below image for understanding cross coverage.





Cross Coverage Example

module cross_example;

    bit a;
    bit [1:0]b;
    
    covergroup cg;
        option.per_instance=1;
        option.comment="cross coverage example";
        A:coverpoint a {
            bins LOW  = {0};
            bins HIGH = {1};
        }
        B:coverpoint b{
            bins b_00 = {0};
            bins b_01 = {1};
            bins b_10 = {2};
            bins b_11 = {3};
        }
        // a=2^1=2
        // b=2^2=4
        // AXB=axb=2x4=8
        AXB:cross A,B;

    endgroup:cg

    initial begin
        // create instance of covergroup
        cg cg_inst = new();
        for(int i=0 ; i<10 ; i++) begin
            {a,b}=i;
            #5;
            cg_inst.sample();
            $display("\t a=%0b b=%2b ",a,b);
        end
        #10;
        $display("----------------------------------------------------");
        $display("coverage of cg_inst is %f ",cg_inst.get_inst_coverage());
        $display("----------------------------------------------------");
    end

endmodule


/* OUTPUT
# KERNEL:    a=0 b=00 
# KERNEL:    a=0 b=01 
# KERNEL:    a=0 b=10 
# KERNEL:    a=0 b=11 
# KERNEL:    a=1 b=00 
# KERNEL:    a=1 b=01 
# KERNEL:    a=1 b=10 
# KERNEL:    a=1 b=11 
# KERNEL:    a=0 b=00 
# KERNEL:    a=0 b=01 
# KERNEL: ----------------------------------------------------
# KERNEL: coverage of cg_inst is 100.000000 
# KERNEL: ----------------------------------------------------

*/
 
 Coverage Report
    For viewing coverage report download files from edaplayground and open coverage_data.html file in browser.
    Quiz : what will happen if option.per_instance is set to 0?
 
Wildcard bins : a wildcard bin is where all x, z, and ? will be treated as wildcards for 0 or 1.means unknown value will be treated as wildcard for o or 1.
 
Example for wildcard bins :
module wildcard_example;

    bit   [3:0]a;
    logic [3:0] arr[4]='{4'b1110,4'b0110,4'b1010,4'b1100};

    covergroup cg;
        option.per_instance = 1;
        option.name         = "cg";
        option.comment      = "wildcard bins";
        option.at_least     = 1;

        A:coverpoint a{
            wildcard bins even={4'b???0};
            wildcard bins odd ={4'b???1};
        }
    endgroup:cg

    initial begin
        cg cg_inst=new();
        for(int i=0;i<4;i++) begin
            a=i;
            $display("a = %4b",a);
            #5;
            cg_inst.sample();
        end
        #5;
      
        foreach(arr[i]) begin
          a=arr[i];
          $display("a = %4b",a);
          cg_inst.sample();
        end
        $display("coverage of cg_inst is : %f",cg_inst.get_inst_coverage());
    
    end
endmodule

/* OUTPUT
# KERNEL: a = 0000
# KERNEL: a = 0001
# KERNEL: a = 0010
# KERNEL: a = 0011
# KERNEL: a = 1110
# KERNEL: a = 0110
# KERNEL: a = 1010
# KERNEL: a = 1100
# KERNEL: coverage of cg_inst is : 100.000000
*/
 
 
 
Thank you for reading , i will update this post with more example on functional coverage.
 
Reference : https://verificationguide.com/systemverilog
Share:
Copyright © VLSI Verification Concepts . Designed by OddThemes