Randomization chaining/recursion

I recently saw an example code that declared class object as rand inside the parent class.
This got me thinking as I have not seen such an usage of rand before.

Anyway, what happens when a class object is declared as rand?
Does the rand variables declared in the class object get randomized when the parent object is randomized using object.randomize()?
Similarly, the object declared with rand can itself have other class object declared with rand qualifier.
So, would there be chaining in terms of randomize calls?

I have also created an example that is listed below. It confirms the above understanding. But any pointer to LRM will help me to read further.

module test;
  class cl_a;
    rand int a;  
  endclass
  
  class cl_b;
    rand int a;
    rand cl_a cl_a_inst = new();
  endclass
  
  class cl_c;
    rand cl_b cl_b_inst = new();
  endclass
  
  initial begin
    cl_c cl_c_inst = new();
    cl_c_inst.randomize();
    
    $display ("a in cl_b %d a in cl_a %d", cl_c_inst.cl_b_inst.a, cl_c_inst.cl_b_inst.cl_a_inst.a);
  end
endmodule

In reply to verif_learner:
From this online paper http://events.dvcon.org/2015/proceedings/papers/04P_11.pdf
“… A class may declare an object
member (i.e. class instance) as “rand”. When the top-level object is randomized, the lower level objects are also randomized. All rand variables and constraints in the top- and lower-level objects are solved simultaneously…”

The exact example from the IEEE 1800-2017 SV LRM section 18.5.9 Global constraints


class A; 
rand bit [7:0] v;
endclass
class B extends A;
rand A left;
rand A right;
constraint heapcond {left.v <= v; right.v > v;}
endclass

HTH,

In reply to rgarcia07:

In reply to verif_learner:
From this online paper http://events.dvcon.org/2015/proceedings/papers/04P_11.pdf
“… A class may declare an object
member (i.e. class instance) as “rand”. When the top-level object is randomized, the lower level objects are also randomized. All rand variables and constraints in the top- and lower-level objects are solved simultaneously…”
The exact example from the IEEE 1800-2017 SV LRM section 18.5.9 Global constraints


class A; 
rand bit [7:0] v;
endclass
class B extends A;
rand A left;
rand A right;
constraint heapcond {left.v <= v; right.v > v;}
endclass

HTH,

Thanks, Garcia. Second part of my question was related to randomize chaining or recursion.
For example, in you case, if class A had another class instance which is also declared with rand qualifier, would that also get randomized when randomize for the parent object is called?
Are you aware of any LRM section that explains this?

In reply to verif_learner:

Apologies if I’m not getting your question correctly, but I think the LRM specifies this in that section I mentioned:
“First, determine the set of objects that are to be randomized as a whole. Starting with the object that
invoked the randomize() method, add all objects that are contained within it, are declared rand,
and are active (see rand_mode in 18.8). The definition is recursive and includes all of the active
random objects that can be reached from the starting object
. The objects selected in this step are
referred to as the active random objects”

In reply to rgarcia07:

In reply to verif_learner:
Apologies if I’m not getting your question correctly, but I think the LRM specifies this in that section I mentioned:
“First, determine the set of objects that are to be randomized as a whole. Starting with the object that
invoked the randomize() method, add all objects that are contained within it, are declared rand,
and are active (see rand_mode in 18.8). The definition is recursive and includes all of the active
random objects that can be reached from the starting object
. The objects selected in this step are
referred to as the active random objects”

Thank you, Garcia. I do see that on page 482 of LRM.

In reply to rgarcia07:

In reply to verif_learner:
Apologies if I’m not getting your question correctly, but I think the LRM specifies this in that section I mentioned:
“First, determine the set of objects that are to be randomized as a whole. Starting with the object that
invoked the randomize() method, add all objects that are contained within it, are declared rand,
and are active (see rand_mode in 18.8). The definition is recursive and includes all of the active
random objects that can be reached from the starting object
. The objects selected in this step are
referred to as the active random objects”

thanks for that,

very important question for my organization,
about this power of solver to see the whole picture of constraints, is it similar between this example and using array with foreach?
for example:


class A; 
    rand bit [7:0] v;
endclass

class B extends A;
    rand A left;
    rand A right;
    constraint heapcond {left.v <= v; right.v > v;}
endclass

Class C extends A;
    rand A[];
    constraints heapcond { 
        A.size() == CHAINS_SPLIT;
        foreach(A[i]){
            (A.size() > i+1) -> A[i] <= A[i+1];
        }
    }
endclass

in other words, is there a difference between the work of solver on B vs C?

thanks - Chaim.

In reply to Gottlieb Chaim:

I’m not sure what you mean by “is there a difference between the work of solver on B vs C?” The size of the tree structure in B determines how many random variables there are and how many constraint relationships there are. The size of the array list in C determines how many random variables there are and how many constraint relationships there are. The foreach loop gets unrolled based on the size of the array.
Realize that calling randomize() does not construct any class objects—that needs to happen before making the call. It does not matter if the random variables and constraints are in separate objects to start with; they all get solved simultaneously.

For this to work, I think you meant

 class C extends A;
    rand A list[];
    constraint list { 
      list.size() == CHAINS_SPLIT;
      foreach(list[i]) list.size() > i+1 -> list[i].v <= list[i+1].v;
    }
 endclass

In reply to dave_59:

Thanks Dave
u r right, I forgot the array name and class var.
but u got me, thanks a lot.