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.
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++) begin
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.
13 Responses
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.
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
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
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.
The ignore_bins…with construct will be supported in irun in version 14.2 which should be available before the end of Jan.
Tim
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
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
How does the “binsof()” work?
Hi, Dinesh.
Please see IEEE 1820-2012 Section 19.6.1 Defining cross coverage bins.
Can we do ignore the bins in cross coverage with different cover groups?? Please let me know….??
Hi, Nishchitha.
I don’t think I understand your question. The ignoring of bins is done within one cover group.
What if a bin is not a single value but an interval? How does “xx > yy” apply to intervals?
Hello, Stefan!
Very good question.
‘{xx,yy} will match also an interval.
An xx value of 1 will be able to match also an interval containing value 1 (e.g. [0:2])
This is best illustrated in the example bellow, where the only bins left for the x_y_cross are:
Bins of x_y_cross:
{a,13}, {a,14}, {a,15}, {b,15}
All the other bins are ignored because the x interval (bins a or b) contains a value higher than the y value, which implies that it will be ignored according to the condition xx > yy.
Ignored bins for x_y_cross:
{a,0}, {a,1}, …, {a,12}
{b,0}, {b,1}, …, {b,14}