How To: Alternative Ways to Implement Bitwise Coverage

In a previous post, Stefan provided implementations for several bitwise coverage patterns. In this post I will show an alternative way of implementing a couple of them, avoiding the usage of loops to iterate through all bits.

Walking 1 and Walking 0 Coverage

covergroup walking1_cg with function sample(bit [WIDTH-1:0] x);
  walking1_cp: coverpoint $clog2(x) iff ($onehot(x)) {
    bins b[] = { [0:WIDTH-1] };
covergroup walking0_cg with function sample(bit [WIDTH-1:0] x);
  walking0_cp: coverpoint $clog2(~x) iff ($onehot(~x)) {
    bins b[] = { [0:WIDTH-1] };

The $clog2() system function, which rounds up the result of the logarithm, is used to get the index of bit which is equal to 1 (for walking 1 coverage), or equal to 0 (for walking 0 coverage). This works because only one of the bits of the sampled value is equal to 1 (or equal to 0).

Power of Two Coverage

covergroup power_of_two_cg with function sample(bit [WIDTH-1:0] x);
  power_of_two_cp: coverpoint ($clog2(x + { {WIDTH{1'b0}}, 1'b1 }) - 1) iff (x != 0) {
    bins b[] = { [0:WIDTH-1] };

For power of two coverage, where several bits can be equal to 1, getting the index of the leftmost bit which is equal to 1 requires rounding down the result of the logarithm. Since SystemVerilog has no $log2() system function, a formula using $clog2() is needed to compute the required value. Note that the addition is written as x + { {WIDTH{1'b0}}, 1'b1 } instead of x + 1, so overflows are avoided when x has 32 or more bits, all equal to 1.

That’s all!


Sreyas September 24th, 2020 11:11:27

I think there is a typo in the example for walking one/zero. There is an extra “(” in front of the $clog2 call.

    Aurelian Ionel Munteanu September 24th, 2020 15:13:48

    Hi, Sreyas.

    You are right. It is fixed now. Thank you for pointing it out.


Leave a Comment:

Your comment will be visible after approval.

(will not be published)

This site uses Akismet to reduce spam. Learn how your comment data is processed.