Functional coverage for three dimensional packed array

Suppose if i have a packed array like “rand bit [7:0][7:0][6:0]” array and i want to write functional coverage like coverpoint array[0][1] = [0:127] then how can i write functional coverage for that ?
In short how can i write functional coverage for three dimensional packed array ?

In reply to Harshad:

coverpoint array[0][1];

In reply to Harshad:

Suppose if i have a packed array like “rand bit [7:0][7:0][6:0]” array and i want to write functional coverage like coverpoint array[0][1] = [0:127] then how can i write functional coverage for that ?
In short how can i write functional coverage for three dimensional packed array ?

I’m maybe overcomplicating things here but you can use an array of coverpoints as mentioned here and here

For example if you do not know the sizes of the packed array you could try something along this lines, in this case I’m creating an array covergroups to cover the third packed dimension of x (assuming that is what you want to cover)

module test();
  bit [1:0][2:0][6:0] x;
  int count; // auxiliary variable to know how many covergroups are required
             // also used to select which covergroup needs to be sampled
  int min;
  int max;
  
  covergroup cg(int min, int max) with function sample(int slice); //if the what you want to cover is greater than 32 bit then change the type of slice 
    option.per_instance = 1;
    cp_range: coverpoint slice {
      bins valid[] = {[min:max]};
    }
  endgroup
  
  initial begin
    cg m_cg[]; //dynamic array of covergroups
    min = 0;
    max = 127;
    
    foreach(x[i,j,]) begin //create an entry in the array every [i][j] in this case a total of 2*3 = 6
      count++;
      m_cg = new[count](m_cg); // resize the covergroup array
      m_cg[count-1] = new(min, max);   // create the covergroup
    end
    
    repeat (2) begin
      
      if(!std::randomize(x)) $fatal(1, "Randomize Failed");
      //somewhere in your sample logic
      count = 0; // reset count
      foreach(x[i,j,]) begin //skip the third packed dimension to get x[i][j] = [7:0] in this case 
        m_cg[count].sample(x[i][j]);
        $display("x[%0d][%0d] = %p", i, j, x[i][j]);
        count++;
      end
      
      foreach(m_cg[i]) begin
        $display("m_cg[%0d] coverage = %0f", i, m_cg[i].get_inst_coverage());
      end
      
      
   end
  end
endmodule

Which outputs


# x[1][2] = 46
# x[1][1] = 108
# x[1][0] = 8
# x[0][2] = 85
# x[0][1] = 89
# x[0][0] = 108
# m_cg[0] coverage = 0.781250
# m_cg[1] coverage = 0.781250
# m_cg[2] coverage = 0.781250
# m_cg[3] coverage = 0.781250
# m_cg[4] coverage = 0.781250
# m_cg[5] coverage = 0.781250
# x[1][2] = 9
# x[1][1] = 92
# x[1][0] = 19
# x[0][2] = 32
# x[0][1] = 9
# x[0][0] = 13
# m_cg[0] coverage = 1.562500
# m_cg[1] coverage = 1.562500
# m_cg[2] coverage = 1.562500
# m_cg[3] coverage = 1.562500
# m_cg[4] coverage = 1.562500
# m_cg[5] coverage = 1.562500

Probably someone else can provide an optimal solution, or if you know the sizes they you can simplify a lot the code shown above (for example the exact size of the array of covergroups), in any case maybe this can help you, and sorry for the lengthy reply

-R

In reply to rgarcia07:

Thank you it’s really helpul…

In reply to Harshad:

Just one question, sv LRM using “ref” keyword inside sample function like
“…covergroup cg(int min, int max) with function sample(ref int slice);”
So question is that when to use ref and when not ?

In reply to Harshad:

I think the issue of using ref in this particular case is that at somepoint you’ll do sample(x[i][j]) and the LRM does not allow ref for packed arrays slices, According to the LRM
Only the following shall be legal to pass by reference:

— A variable,
— A class property,
— A member of an unpacked structure, or
— An element of an unpacked array.

In general I believe ref is used in a method to improve performance for example when passing large structures/arrays as arguments, you can look for details in section 13.5.2 Pass by reference.

HTH,

-R

In reply to Harshad:

When you do not use ref, the implicit argument direction is input. That is a one time copy the argument by value. You use ref if you need to track the argument’s value over time. You should never need to pass the arguments to the covergroup’s sample method by ref. Also note that type compatibility rules for passing arguments by ref are much stricter, they must have matching types.

covergroup cg(int min, int max, ref int slice)
    option.per_instance = 1;
    cp_range: coverpoint slice {
      bins valid[] = {[min:max]};
    }
endgroup

Typically you would pass the arguments that are used in constructing bins by value, and the expressions to be covered by reference.

In reply to dave_59:

In reply to Harshad:
When you do not use ref, the implicit argument direction is input. That is a one time copy the argument by value. You use ref if you need to track the argument’s value over time. You should never need to pass the arguments to the covergroup’s sample method by ref. Also note that type compatibility rules for passing arguments by ref are much stricter, they must have matching types.

covergroup cg(int min, int max, ref int slice)
option.per_instance = 1;
cp_range: coverpoint slice {
bins valid[] = {[min:max]};
}
endgroup

Typically you would pass the arguments that are used in constructing bins by value, and the expressions to be covered by reference.

Thanks Dave and rgarcia07…