Randomization of a class object inside a class in SystemVerilog

class c2; rand bit[1:0] a; rand bit[1:0] b; function void my_print(); $display("a = %b", a); $display("b = %b", b); endfunction
endclass
class c1; rand bit[1:0] i; rand bit[1:0] j; rand c2 o2; function new(); o2 = new(); endfunction function void my_print(); $display("i = %b", i); $display("j = %b", j); endfunction
endclass
program p1; c1 o1 = new; c2 o2_local = new; initial begin if (o1.randomize() with {o2 == o2_local;}) begin o1.my_print(); o2.my_print(); end
endprogram

In this program, randomization is getting failed for o1.randomize(). If I take individual variables for o2 and use inline constraint with that (like o2.a == o2_local.a), then it works.

Is there any alternative way to do this type of randomization, as my original class contains almost 38 variable, and individual assignments would be troublesome.

1

2 Answers

The == operator when applied to object doesn't do what you think it does. It only compares the handles. The solver is failing because it sees that o1.o2 and o2_local are different objects and thus aren't "equal".

If o2_local isn't supposed to be changed by the randomization then you can just do the following:

o1.o2 = o2_local;
o1.o2.rand_mode(0);
if (o1.randomize()) begin o1.print(); o1.o2.print();
end
o1.o2.rand_mode(1);

This way you've assigned o2_local to o2 and if you were to have any constraints that referenced fields of o2 and of o1 they would be solved.

The problem with object equivalence is symptomatic to all OOP languages. You'd need a function that takes all fields of the object into account to determine if two objects are equal:

class c2; // ... function bit equals(c2 obj); return a == obj.a && b == obj.b; endfunction
endclass

This function works fine in procedural code, but it won't help you for randomization as using functions in constraints is trickier.

An ugly solution would also be to declare a macro that expands to the body of the equals(...) function, because having the == statements unrolled will work in a constraint.

3

If all the variables in the c2 class needs to be randomized "with" did not have much impact since "with" is used to constrain only certain values, A simple method would do all variable randomization, I doubt because of this reason LRM doesn't talk much about inline constraints of nested classes

 initial begin if (o1.randomize()) begin if (o2_local.randomize()) begin o1.my_print(); o2_local.my_print(); end end else $fatal ("Randomize failed"); end
endprogram

As you have figured how to constraint each variable, this would help in if only specific values are to be constrained inline.

1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like