Parameterized Covergroup V/S Overriding function sample()

Hi ,

A parameterized covergroup can be used to sample values of different variables .

  covergroup cg ( ref int x , ref int y ); //  ' ref '  type  arguments
     coverpoint  x ;
     coverpoint  y ;

  cg  cg_inst1  =  new( a , b ) ;
  cg  cg_inst2  =  new( c , d ) ;

So essentially we define the covergroup once and pass different actual arguments to sample .

However LRM Section 19.8.1 Overriding the built-in sample method , mentions the following ::

covergroup p_cg with function sample(bit a, int x);  //  input  instead  of  ' ref ' type
  coverpoint x;
   cross x, a;
endgroup : p_cg

It also states the following ( which I am not fully clear about ) ::
“Overriding the predefined sample() method with a triggering function that accepts arguments facilitates
sampling coverage data from contexts other than the scope enclosing the covergroup declaration. For
example, an overridden sample method can be called with different arguments to pass directly to a
covergroup the data to be sampled from within an automatic task or function, or from within a particular
instance of a process, or from within a sequence or property of a concurrent assertion”

I have 3 questions ::

(1) Explanation for the above LRM quote

(2) Advantages of overridden sample() over parameterized covergroup and vice-versa

(3) Does the argument have to be of input direction always when overriding sample() ?

In reply to MICRO_91:

The purpose of ref arguments for any method, whether it be the constructor of a covergroup or a task, is that the values of these arguments are tracked for the the lifetime of the covergroup or task call. input arguments copy their values at the point in time the method gets called and never change value until the method gets called again. For the sample() method, it would not make any difference if the arguments were input or ref, they are copying the values at the point in time the sample calling.

These covergroup arguments give you 3 layers of interaction

  • values for the type
  • values for the instance
  • values for the sample
bit W,X,Y,Z,Q;
covergroup cg(bit a, ref bit b) with sample(bit c);
  cp1: coverpoint W { // type covers W
    bins hit = {a}; // bin value is set at construction of coverpoint
  cp2: coverpoint b;  // instance covers whatever is passed to b

  cross cp1,cp2,c;    // sample covers whatever is passed to c

cg cg1 = new(0,X); // cp2 tied to X
cg cg2 = new(1,Y); // cp2 tied to Y

cg1.sample(Z); // cross W.hit(0), X, Z
cg2.sample(Q); // cross W.hit(1), Y, Q

In reply to dave_59:

Dave ,

Thanks for the explanation .

(1) Is it legal for actual argument to argument of ref direction of overridden sample() be an automatic variable ?

For example : Actual could be local argument in sequence , property .
( sample() called from function in sequence , property )

(2) Regarding the LRM quotes above ,

For parameterized covergroup the actual to ref argument is in the scope of the covergroup whereas for the overridden sample() the argument need not be present in the scope of the covergroup . It could be a variable in another component or static entity which would be passed as argument to sample() .

 Is  my  interpretation  correct ? 

Thanks in advance .

In reply to MICRO_91:

Regardless of what the LRM says, defining sample() arguments with any other direction than input does not make any sense. A ref argument in a covergroup does not behave the same way as it does in a task/function. I think it was an oversight that the LRM does not restrict ref arguments to sample, or treat ref arguments the same as an input. See 0006817: Enable passing nets by const ref to functions and tasks - Accellera Mantis

In reply to dave_59:

Thanks Dave ,

  • Even when defined as ref , the actual would need to be passed every time on calling sample() ( since no default ) . This is same as defining input direction .
  • Unlike task / function which can modify the ref argument a covergoup / coverpoint can’t modify .