How to create a specfic bins from single genric covergroup

Hi All,

How to create a separate bins from single cover group.

In below even though i enabled bins only for only Burst_len =4; and Busrt_len =1 .
But i see 16 bins created in coverage database instead of only 2 bins created i.e for Burst_len =4 and Busrt_len =1;

And i am not able to get 100% coverage even though i covered all the scenario for specific module.

Please tell how to create only two bins for below code .

I have created a covergroup with all the 16 bins because for some other module i may need same bus coverage class with all the bins .



class Bus_trans;
   bit [3:0] burst_len;
endclass


class Bus_conf;
   bit [15:0] burst_len_en = 16'hF000;
endclass


class BUS_coverage

Bus_trans  tr;  
Bus_conf conf;

covergroup Bus_trans_coverage;
        Burst_Length  :  coverpoint tr.burst_len 
        { 
            bins                burst_len_01   = {01}  iff (conf.burst_len_en[0] == 1);
            bins                burst_len_02   = {02}  iff (conf.burst_len_en[1] == 1);
            bins                burst_len_03   = {03}  iff (conf.burst_len_en[2] == 1);
            bins                burst_len_04   = {04}  iff (conf.burst_len_en[3] == 1);
            bins                burst_len_05   = {05}  iff (conf.burst_len_en[4] == 1);
            bins                burst_len_06   = {06}  iff (conf.burst_len_en[5] == 1);
            bins                burst_len_07   = {07}  iff (conf.burst_len_en[6] == 1);
            bins                burst_len_08   = {08}  iff (conf.burst_len_en[7] == 1);
            bins                burst_len_09   = {09}  iff (conf.burst_len_en[8] == 1);
            bins                burst_len_10   = {10}  iff (conf.burst_len_en[9] == 1);
            bins                burst_len_11   = {11}  iff (conf.burst_len_en[10] == 1);
            bins                burst_len_12   = {12}  iff (conf.burst_len_en[11] == 1);
            bins                burst_len_13   = {13}  iff (conf.burst_len_en[12] == 1);
            bins                burst_len_14   = {14}  iff (conf.burst_len_en[13] == 1);
            bins                burst_len_15   = {15}  iff (conf.burst_len_en[14] == 1);
            bins                burst_len_16   = {16}  iff (conf.burst_len_en[15] == 1);
        }
endgroup

function new (string _name = "", Bus_conf cf1);
        this.name = _name; 
        this.conf = cf1;
        Bus_trans_coverage = new();       
endfunction

 virtual function trans_sample(Bus_trans tr);
             this.tr = tr;             
             Bus_trans_coverage.sample();
 endfunction

   
endclass
    
class test1 extends uvm_test;

Bus_coverage br;
Bus_conf     b1;

Bus_trans   tr;

function new (string name = "i_test", uvm_component parent);
            super.new (name, parent);
endfunction

function void build_phase (uvm_phase phase);
b1 =new();
b1.burst_len_en = 16'h0009;

br =new("cov",b1);

endunction 


task run_phase(uvm_phase phase);

tr=new();
tr.burst_len = 4;
//send to driver
br.trans_sample(tr);

#10;

tr=new();
tr.burst_len = 1;
#10;
//send to driver
br.trans_sample(tr);

endtask

endclass


Thanks in advance.

Hi there
Your code creates 16 bins at all times, but only SAMPLES a certain number of them, according to your config.

This means that if you configure for 2 bins, then the other 14 bins will never be sampled, which is not your intention of the other 14 bins never being created.

You could instead assign an option.weight to each coverpoint, using the configuration value to set the weight to 1 for values you want to be sampled, and 0 for values you want to ignore.

The coverpoints / bins will still be created, but with a weight of 0, meaning that unwanted bins will not adversely affect your coverage.

Because option.weight can only be used at covergroup or coverpoint level, you would rephrase your code so that instead of one covergroup with one coverpoint and lots of bins, you would still have a single covergroup, but instantiating 1 coverpoint of various weights per possible configuration option, each coverpoint having a single “hit” bin for when a hit occurs.

In reply to Richard Hamer (EnSilica):

Hi Richard,

Thanks for Quick reply . I will try your solution.

Thanks
raku

In reply to raku:

Hi Raku
The quickest way would be to conditionally instantiate one covergroup per configuration value, each with a single coverpoint, but that ends up with a lot of covergroups everywhere!

In reply to Richard Hamer (EnSilica):

To clarify …

If you only ever had a few configured options and did want to do it that way to avoid having unhit zero-weight bins in your coverage report, then you would only need to declare the covergroup once. You could parameterise the value you wanted it to cover, and the conditionally instantiate once per possible value.

Not my preferred solution though!

In reply to Richard Hamer (EnSilica):

Hi Richard,

Thanks for your time and answering me .

I did not understand the last solution.

if possible can you show some small example.

Thanks

In reply to raku:

Hi Raku
Here is an example for my first (preferred) solution using coverpoint weightings within a single covergroup:


    covergroup cg_burst_len(input bit [15:0] burst_len_en);
       option.per_instance = 1;

       cp_hit_1  : coverpoint tr.burst_len {option.weight = burst_len_en[0];  bins HIT = {1};  }
       cp_hit_2  : coverpoint tr.burst_len {option.weight = burst_len_en[1];  bins HIT = {2};  }
       <snip>
       cp_hit_16 : coverpoint tr.burst_len {option.weight = burst_len_en[15]; bins HIT = {16}; }
    endgroup

   cg_burst_len cg_burst_len;

   function void build_phase (uvm_phase phase);   
     <snip>
     cg_burst_len  = new(conf.burst_len_en);
   endfunction

Here is an example for a solution if you are certain you do not want to see any unwanted values, whether contributing to coverage scores or not. Although it hides all unwanted values, unlike the first solution it does not automatically scale and needs to be rewritten whenever the range of possible burst values changes. This, along with the multiple covergroups, is why I do not favour this solution.


    // Requires a global sampling signal and covergroup declared outside the class - ugly!
    event e_sample_burst_len;

    covergroup cg_burst_len(input bit [3:0] cfg_value, ref bit [4:0] burst_len) @(e_sample_burst_len);
       option.per_instance = 1;

       cp_hit  : coverpoint burst_len {
         bins HIT = {cfg_value};  
       }
    endgroup 

   cg_burst_len cg_burst_len_1;
   cg_burst_len cg_burst_len_2;
   <snip>
   cg_burst_len cg_burst_len_16;

   function void build_phase (uvm_phase phase);   
     <snip>

     if (burst_cfg[0])  cg_burst_len_1  = new(0,  burst_len);
     if (burst_cfg[1])  cg_burst_len_2  = new(1,  burst_len);
     <snip>
     if (burst_cfg[15]) cg_burst_len_16 = new(15, burst_len);
   endfunction

  // And then the following instead of cg_*.sample()
  -> e_sample_burst_len;       


By the way, you have a ranging problem in your definition of burst_len - it can only carry values 0 to 15 but your covergroup checks for values 1 to 16.


class Bus_trans;
   bit [3:0] burst_len;
endclass

<snip>
        Burst_Length  :  coverpoint tr.burst_len 
            bins                burst_len_16   = {16}  iff (conf.burst_len_en[15] == 1);


Richard

There is a much easier way to do this using the new bin set_covergroup_expression construct introduced in 1800-2012. This allows you to create an array of values and use that array as the set of values for bins.

class BUS_coverage
Bus_trans  tr;  
Bus_conf conf;
bit [3:0] bin_set[$];
 
covergroup Bus_trans_coverage;
        Burst_Length  :  coverpoint tr.burst_len 
        { 
            bins burst_len[] = bin_set;
endgroup
 
function new (string _name = "", Bus_conf cf1);
        this.name = _name; 
        this.conf = cf1;
        foreach(conf.burst_len_en[i]) if (conf.burst_len_en[i]) bin_set.push_back(i);
        Bus_trans_coverage = new();       
endfunction

Sorry, I did not have time to compile this for typos.

In reply to Richard Hamer (EnSilica):

Hi Richard,

Ya thanks for taking time and showing the solution with example.
Also i too don’t prefer second way of creating many covergroups because i have so many other parameters for coverage so there will lot of covergroups created .

In reply to dave_59:

Hi Dave,

Thanks for showing this nice solution.

In reply to raku:

Thanks Dave, that’s a neat construct, I’m glad 1800-2012 addressed this issue!