Generic covergroup definitions for range bins and other such frequently occurring needs

Hi,
Can anyone point me to a collection of generic covergroup definitions that may have been implemented for reuse for purposes like range analysis or other such commonly recurring cases. For instance, for range analysis I’d like something like this, though note that what I have here is a work in progress and is not going to do what I want really becuase there will always be unintended bins that won’t get filled:

covergroup cg (ref int v, int width);
   coverpoint v {
      bins bounds[] = {0, 1, (1<<(width-1))-1, 1<<(width-1)}; // or {0, 1, $-1, $};

      bins range_2nd_lsb = {[2:3]}         iff (width >= 2);
      bins range_3rd_lsb = {[4:7]}         iff (width >= 3);
      bins range_4th_lsb = {[8:15]}        iff (width >= 4);
      ...
      bins range_nth_lsb = {[32768:65536]} iff (width >= 16);
      ...
   }
endgroup

Basically, I am working in a plain module-based SV environment, no UVM, few classes, and want to add some functional coverage here and there, but not have to create a dedicated coverage group definition for every covergroup instance I need to cover certain things like value ranges. I’d rather have a collection of generic covergroup definitions to be reused.

Someone, somewhere must have put some of these together (possibly even with the assistance of macros).

Thanks for any help.

Hans

In reply to HvdS:

Sometimes you have to abandon the desire to express everything in one coverpoint and use an array of covergroups instead.

module top;
covergroup cg (ref int v, input int lsb);
  option.per_instance=1;
   coverpoint v {
     bins range = {[int'(lsb>0)<<lsb:(1<<lsb+1)-1]};
   }
endgroup
  int width=16;
  int signal;
  cg cg_inst[];
  
  initial begin
    cg_inst = new[width];
    for(int i=0;i<width;i++) begin
      $display("Constructng range [%0d:%0d]",int'(i>0)<<i,(1<<i+1)-1);
      cg_inst[i] = new(signal,i);
    end
  end
endmodule

In reply to dave_59:

Hi Dave,
I figured no one better to ask than you, albeit indirectly.
This is a pretty interesting solution indeed. Would not have thought to create an array of covergroups. And I guess by virtue of the (array) name association of each covergroup instance in the array they would still appear in any report in an intuitive manner.

Frankly, I don’t see any other way of going about this, safe perhaps from using (a) “conditional generate” macro(s) to generate the desired covergroup code for the width at hand, so that the macro effectively provides for reuse?

Anyway, I’ll be playing with this.

Thanks - Hans

In reply to HvdS:

BTW, my code only works with widths up to 30 bits because the largest positive int is 30 bits. To do larger widths, you’ll have to cast both ends of the range to a wider type.

typedef bit [63:0] uint64_t;
covergroup cg (ref uint64_5 v, input int lsb);
  option.per_instance=1;
   coverpoint v {
     bins range = {[uint_64_t'(lsb>0)<<lsb:uint64_t'(1<<lsb+1)-1]};
   }
endgroup