How to Ignore Cross Coverage Bins Using Expressions in SystemVerilog

Lately, I’ve been playing with the coverage features of SystemVerilog. One thing I wanted to do was to filter out some bins from the auto-generated list of cross bins. I searched the Internet for a solution, but only found similar questions with no clear answers. Therefore, I started to work on this problem and came up with two solutions, which I will share with you.

To better illustrate the problem, let’s assume that we want to generate two variables – one always less than or equal to the other, and collect the valid coverage for the generated value.

rand bit[3:0] x, y;

constraint c {
  x <= y;
}

We will use SystemVerilog coverage constructs like covergroup, coverpoint and cross to confirm that we’ve generated all legal values.

auto_generated_bins_of_a_cross_coverage

Because we are interested only in values x <= y, we’ll need to have some kind of filtering on the cross coverage bins. As you can notice in the picture above, we must filter 120 bins out of the total of 256 bins. It would be a tedious work to try to exclude them bin by bin. So, here are my solutions:

Using ‘with’

The simplest way to filter unwanted bins is ‘with’ inside an ignore_bins construct:

covergroup cover_me;
  x_cp : coverpoint x;
  y_cp : coverpoint y;

  x_y_cross: cross x_cp, y_cp {
    ignore_bins ignore_x_values_higher_than_y = x_y_cross with (x_cp > y_cp);
  }
endgroup

Using CrossQueueType

The second solution is to use CrossQueueType. CrossQueueType is the type of a cross coverage bin. Starting with the SystemVerilog standard 2012 (IEEE1800-2012), you can define a function that returns a queue of type CrossQueueType and use it to define the ignored cross coverage bins.

Pay attention, the function returns the ignored bins, not the valid ones!

covergroup cover_me;
  x_cp : coverpoint x;
  y_cp : coverpoint y;

  x_y_cross : cross x_cp, y_cp {
    function CrossQueueType createIgnoreBins();
      // Iterate over all bins
      for (int xx=0; xx<=15; xx++) begin
        for (int yy=0; yy<=15; yy++)
          if (xx > yy)
            // Ignore this bin
            createIgnoreBins.push_back('{xx,yy});
          else
            // This is a valid bin
            continue;
        end
      end
    endfunction

    ignore_bins ignore_x_values_higher_than_y = createIgnoreBins();
  }
endgroup

Unfortunately, not all simulators support the above constructs. I prepared two complete code examples – test_with.sv and test_CrossQueueType.sv, which are ready to be compiled and run. You may want to download them to see what works for you.

There may be other solutions as SystemVerilog is quite complex. In case you have knowledge of other solutions please share them.


Comments

ToddM September 27th, 2014 23:45:21

More generically, you can punch out any pattern you’d like by following the pattern here. Not better, just different. This way does make you manually enter all of the X-Y coordinates, but if your pattern is random, then this works.

covergroup cg1 ;
 cA: coverpoint myenumA  {
   bins a_bin[] = {[A1:A3]};
 } 
 cB: coverpoint myenumB {
  bins b_bin [] = {[B1:B3]};
 } 
 cC: coverpoint myenumC {
  bins c_bin[] = {[C1:C3]};
 } 
// Remember - the spec says that when a bin is named it's taken *out* of
// the autobin list.  So the
aXb: cross cA, cB, cC { 
   // Keep triple combinations = {A1+B2+C3} and {A1+B1+C1}
   bins A1B2C3 = binsof (cA) intersect {A1}  &&
              binsof (cB) intersect {B2}  &&
              binsof (cC) intersect {C3} ; 
   bins A1B1C1 = binsof (cA) intersect {A1}  &&
              binsof (cB) intersect {B1}  &&
              binsof (cC) intersect {C1} ; 
   // should ignore everything that's not above ^^
   ignore_bins IGNORE_A_B =
            ( !binsof (cA) intersect {A1}  ||
              !binsof (cB) intersect {B2}   ||
              !binsof (cC) intersect {C3}     ) 
            &&
            ( !binsof (cA) intersect {A1}   ||
              !binsof (cB) intersect {B1}   ||
              !binsof (cC) intersect {C1}     )
           ; 
} 
endgroup

    Aurelian Ionel Munteanu September 29th, 2014 11:31:58

    Hi, Todd.

    Thank you for sharing your oppinion.
    Yes, that’s the “classical” style aproach. But as you’ve noticed, it’s not scalable when bins number is large. It is error prone and difficult to read.

    In my oppinion you may use any convenient solution (‘with clause’, ‘CrossQueueType’ or ‘binsof() +intersect’) when there are less than 8 bins but when there are more bins involved you need to pick the easiest solution.

    Regards,
    Aurelian


Nages September 28th, 2014 05:59:57

Hi,

Thanks for sharing your knowledge. I faced one problem while I am writing coverage. Can tell me if you know.

http://asic-verification-methodologies.blogspot.in/2014/09/hello-can-any-body-tell-me-how-to.html?m=1

Thanks,
Nagesh


Leon Ren October 29th, 2014 09:50:25

Hi, Aurelian,

I have met exactly the same problem with you.I searched the whole internet and your post is the ONLY solution.

Your first method passed the vcs, and the second failed both vcs and irun.

Since our team choose irun as our main simulator, so i have no choice but ToddM’s traditional way.

Anyway, thanks for your share, maybe i will use it next time.


Tim January 5th, 2015 23:30:07

The ignore_bins…with construct will be supported in irun in version 14.2 which should be available before the end of Jan.

Tim


Very helpful. Great !! April 12th, 2015 16:30:27

Hi Aurelian Ionel Munteanu,

I was searching exactly for this kind of solution, which is not present in System Verilog LRM. It works well with QuestaSim. Don’t know why it is not mentioned in LRM though. Or did I miss it?

Thanks !!

Murali


    Aurelian Ionel Munteanu April 22nd, 2015 07:46:12

    Hi, Murali.

    The ‘with’ operator and the ‘CrossQueueType’ are mentioned in the SystemVerilog standard 2012 (IEEE1800-2012), in chapters 19.5.1.1 and 19.6.1.3 respectively.

    The solution itself, as mentioned in my article, is not found in the LRM, but it might be a good idea to have it mentioned in future versions of the LRM. A real project need and the lack of LRM suggestions on ignoring cross coverage bins, made me come up with those solutions.

    Anyway, i’m glad it helped you.

    Best regards,
    Aurelian


Dinesh November 8th, 2017 14:22:58

How does the “binsof()” work?


    Stefan Birman November 8th, 2017 14:54:14

    Hi, Dinesh.

    Please see IEEE 1820-2012 Section 19.6.1 Defining cross coverage bins.


Leave a Comment:

Your comment will be visible after approval.

(will not be published)