Tutorials RANDOMIZATION METHODS

Randomization Built-In Methods

SystemVerilog has randomize(),pre_randomize() and post_randomize() built-in functions for randomization. Calling randomize() causes new values to be selected for all of the random variables in an object. To perform operations immediately before or after randomization,pre_randomize() and post_randomize() are used.

Randomize()

Every class has a virtual predefined function randomize(), which is provided for generating a new value.Randomization function returns 1 if the solver finds a valid solution. We cannot override this predefined function. It is strongly recommended to check the return value of randomize function. Constraint solver never fails after one successful randomization, if solution space is not changed. For every randomization call, check the return value, solver may fail due to dynamically changing the constraints.In the following example, there is no solution for Var < 100 and Var > 200,so the randomization fails.

The best way to check status of randomization return value is by using assertion.

assert(obj.randomize());

EXAMPLE:
program Simple_pro_13;
class Simple;
rand integer Var;
constraint c1 { Var <100;}
constraint c2 { Var >200;}
endclass
initial
begin
Simple obj = new();
if(obj.randomize())
\$display(" Randomization sucsessfull : Var = %0d ",obj.Var);
else
\$display("Randomization failed");
end
endprogram

RESULTS:

# Randomization failed

If randomize() fails, the constraints are infeasible and the random variables retain their previous values. In the following example, For the first randomization call there is a solution. When the constraints are changed, the randomization failed. Simulation results show that after randomization failed, random variables hold their previous values.

EXAMPLE:
program Simple_pro_14;
class Simple;
rand integer Var;
integer MIN = 20 ;
constraint c { Var < 100 ; Var > MIN ; }
endclass
Simple obj;
initial
begin
obj = new();
if(obj.randomize())
\$display(" Randomization successful : Var = %0d ",obj.Var);
else
\$display("Randomization failed: Var = %0d ",obj.Var);
obj.MIN = 200;
\$display(" MIN is changed to fail the constraint");
if(obj.randomize())
\$display(" Randomization sucsessfull : Var = %0d ",obj.Var);
else
\$display(" Randomization failed : Var = %0d",obj.Var);
end
endprogram
RESULTS:

# Randomization sucsessfull : Var = 87
# MIN is changed to fail the constraint.
# Randomization failed : Var = 87

Pre_randomize And Post_randomize

Every class contains pre_randomize() and post_randomize() methods, which are automatically called by randomize() before and after computing new random values. When randomize() is called,it first invokes the pre_randomize() then randomize() finally if the randomization is sucesusful only post_randomize is invoked.
These methods can be used as hooks for the user to perform operations such as setting initial values and performing functions after assigning random variables.

EXAMPLE:
program pre_post_15;
class simple;
function void pre_randomize;
\$display(" PRE_RANDOMIZATION ");
endfunction
function void post_randomize;
\$display(" POST_RANDOMIZATION ");
endfunction
endclass
simple obj = new();
initial
void'(obj.randomize());
endprogram

RESULTS:

# PRE_RANDOMIZATION
# POST_RANDOMIZATION

Overriding of pre_randomize and post_randomize functions is allowed by child class. If parent class functions are not called when overriding pre_randomize() and post_randomize functions, parent class function definations will be omitted.

EXAMPLE:
class Base;
function void pre_randomize;
\$display(" BASE PRE_RANDOMIZATION ");
endfunction
function void post_randomize;
\$display(" BASE POST_RANDOMIZATION ");
endfunction
endclass

class Extend_1 extends Base;
function void pre_randomize;
\$display(" EXTEND_1 PRE_RANDOMIZATION ");
endfunction
function void post_randomize;
\$display(" EXTEND_1 POST_RANDOMIZATION ");
endfunction
endclass

class Extend_2 extends Base;
function void pre_randomize;
super.pre_randomize();
\$display(" EXTEND_2 PRE_RANDOMIZATION ");
endfunction
function void post_randomize;
super.post_randomize();
\$display(" EXTEND_2 POST_RANDOMIZATION ");
endfunction
endclass

program pre_post_16;
Base B = new();
Extend_1 E1 = new();
Extend_2 E2 = new();
initial
begin
void'(B.randomize());
void'(E1.randomize());
void'(E2.randomize());
end
endprogram

In the extended class EXTEND_1, when overiding the builtin functions, parent class functions are not called. In the extended class EXTEND_2, super.methods are called which invokes the parent class methods also.

RESULTS:

# BASE PRE_RANDOMIZATION
# BASE POST_RANDOMIZATION
# EXTEND_1 PRE_RANDOMIZATION
# EXTEND_1 POST_RANDOMIZATION
# BASE PRE_RANDOMIZATION
# EXTEND_2 PRE_RANDOMIZATION
# BASE POST_RANDOMIZATION
# EXTEND_2 POST_RANDOMIZATION

The pre_randomize() and post_randomize() methods are not virtual. However, because they are automatically called by the randomize() method, which is virtual, they appear to behave as virtual methods. This example demonstrates that these functions are not virtual but simulation results show that, it executed extended class definition functions. Extended class object is created and assigned to base class object. Calls to pre_randomize and post_randomize calls in object B ,executed the extended class definitions.

EXAMPLE:
class Base;
function void pre_randomize;
\$display(" BASE PRE_RANDOMIZATION ");
endfunction
virtual function void post_randomize;
\$display(" BASE POST_RANDOMIZATION ");
endfunction
endclass

class Extend extends Base;
function void pre_randomize;
\$display(" EXTEND PRE_RANDOMIZATION ");
endfunction
function void post_randomize;
\$display(" EXTEND POST_RANDOMIZATION ");
endfunction
endclass

program pre_post_17;
Base B ;
Extend E = new();
initial
begin
B = E ;
void'(B.randomize());
void'(E.randomize());
end
endprogram

RESULTS:

There should be compilation error.

In the above example compilation error is due to the declaration of post_randmoize() function as virtual. By removing the virtual keyword for the post_randomize() function, calling the randomize() function by parent and child class, both will execute functions of child class only. Which is a virtual function behaviour.

EXAMPLE:
class Base;
function void pre_randomize;
\$display(" BASE PRE_RANDOMIZATION ");
endfunction
function void post_randomize;
\$display(" BASE POST_RANDOMIZATION ");
endfunction
endclass

class Extend extends Base;
function void pre_randomize;
\$display(" EXTEND PRE_RANDOMIZATION ");
endfunction
function void post_randomize;
\$display(" EXTEND POST_RANDOMIZATION ");
endfunction
endclass

program pre_post_17;
Base B ;
Extend E = new();
initial
begin
B = E ;
void'(B.randomize());
void'(E.randomize());
end
endprogram

RESULTS:

# EXTEND PRE_RANDOMIZATION
# EXTEND POST_RANDOMIZATION
# EXTEND PRE_RANDOMIZATION
# EXTEND POST_RANDOMIZATION

If the class is a derived class and no user-defined implementation of pre_randomize() and post_randomize() exists, then pre_randomize() and post_randomize() will automatically invoke super.pre_randomize() and super.post_randomize() respectively.

EXAMPLE:
class Base;
function void pre_randomize;
\$display(" BASE PRE_RANDOMIZATION ");
endfunction
function void post_randomize;
\$display(" BASE POST_RANDOMIZATION ");
endfunction
endclass

class Extend extends Base;
endclass

program pre_post_19;
Extend E = new();
initial
void'(E.randomize());
endprogram

RESULTS:

# BASE PRE_RANDOMIZATION
# BASE POST_RANDOMIZATION

EXAMPLE:
class Base;
function void pre_randomize;
\$display(" BASE PRE_RANDOMIZATION \n");
endfunction
function void post_randomize;
\$display(" BASE POST_RANDOMIZATION \n");
endfunction
endclass

class Extend extends Base;
function void pre_randomize;
super.pre_randomize();
\$display(" EXTENDED PRE_RANDOMIZATION \n");
endfunction
function void post_randomize;
\$display(" EXTENDED POST_RANDOMIZATION \n");
endfunction
endclass

program pre_post;
Base B;
Extend E = new();
initial
begin
B = E;
if(B.randomize())
\$display(" randomization done \n");
end
endprogram

RESULTS:

BASE PRE_RANDOMIZATION
EXTENDED PRE_RANDOMIZATION
EXTENDED POST_RANDOMIZATION
randomization done

Results show that, if extended class is having new definition, explicitly super.pre_ or post_ has to be called.
super.pre_randomize() is called in extended class, but super.post_randomize() is not called in above example. See the difference in results.
If a class A instance is in Class B,To randomize class A by calling the randomize function of class B,Class A instance has to be declared as rand variable.

EXAMPLE:
class A;
rand integer Var;
endclass

class B;
rand A obj_1 = new() ;
A obj_2 = new();
endclass

program a_b_20;
B obj=new();
initial
begin
obj.obj_1.Var = 1;
obj.obj_2.Var = 1;
repeat(10)
begin
void'(obj.randomize());
\$display(" Var1 = %d ,Var2 = %d ",obj.obj_1.Var,obj.obj_2.Var );
end
end
endprogram

RESULTS:

# Var1 = 733126180 ,Var2 = 1
# Var1 = -119008195 ,Var2 = 1
# Var1 = 342785185 ,Var2 = 1
# Var1 = 679818185 ,Var2 = 1
# Var1 = -717162992 ,Var2 = 1
# Var1 = 664520634 ,Var2 = 1
# Var1 = -1944980214 ,Var2 = 1
# Var1 = -1350759145 ,Var2 = 1
# Var1 = -1374963034 ,Var2 = 1
# Var1 = -462078992 ,Var2 = 1

Look at the results. Variable of obj_2 is not randomized. Only variable of obj_1 which is declared as rand is ranomized.

Upon calling the randomize method of B object which contains rand A object, First B prerandomize is called, then A prerandomize method is called, then B is randomized, if a solution was found, new values are assigned to the random A objects.If solution was found, for each random object that is a class instance it's post_randomize method is called. That means if randomization is successful next B postrandomize, next A postrandomize functions are called. Upon calling B randomize function this is sequence it follow.

B-Prerandomize --> A-prerandomize --> A.randomize --> B-postrandomize --> A-postrandomize

EXAMPLE:
class A;
rand integer Var;
function void pre_randomize;
\$display(" A PRE_RANDOMIZATION ");
endfunction
function void post_randomize;
\$display(" A POST_RANDOMIZATION ");
endfunction
endclass

class B;
rand A obj_a;
function new();
obj_a = new();
endfunction
function void pre_randomize;
\$display(" B PRE_RANDOMIZATION ");
endfunction
function void post_randomize;
\$display(" B POST_RANDOMIZATION ");
endfunction
endclass

program pre_post_21;
B obj_b = new();
initial
void'(obj_b.randomize());
endprogram

RESULTS:

# B PRE_RANDOMIZATION
# A PRE_RANDOMIZATION
# B POST_RANDOMIZATION
# A POST_RANDOMIZATION

If randomization failed for obj_a, then post_randomize of obj_a and post_randomize of obj_b won't be called, and randomization will fail for obj_b also.

EXAMPLE:
class A;
rand bit [2:0] Var;
constraint randge_c { Var > 2 ; Var < 2;}
function void pre_randomize;
\$display(" A PRE_RANDOMIZATION ");
endfunction
function void post_randomize;
\$display(" A POST_RANDOMIZATION ");
endfunction
endclass

class B;
rand A obj_a;
function void pre_randomize;
\$display(" B PRE_RANDOMIZATION ");
endfunction
function void post_randomize;
\$display(" B POST_RANDOMIZATION ");
endfunction
function new();
obj_a = new();
endfunction
endclass

program pre_post_22;
B obj_b = new();
initial
void'(obj_b.randomize());
endprogram

RESULTS:

# B PRE_RANDOMIZATION
# A PRE_RANDOMIZATION

Disabling Random Variable

The random nature of variables declared as rand or randc can be turned on or off dynamically. To change the status of variable which is declared as rand or randc to state variable, built in rand_mode() method is used. State variables are not randomized by randomize() mehod. By default all rand and randc variables are active. When called as a task, the arguments to the rand_mode method determines the operation to be performed. If the arguments is 0, then all the variables declared as rand and randc will become non random i.e all random variables treated as state variables. IF argument is 1, then all variables declares as rand and randc will be randomized.

EXAMPLE:
class rand_mo;
rand integer Var1;
rand integer Var2;
endclass

program rand_mo_p_23;
rand_mo obj = new();
initial
begin
void'(obj.randomize());
\$display(" Var1 : %d Var2 : %d ",obj.Var1,obj.Var2);
obj.rand_mode(0); // Var1 and Var2 will be treated as State variables.
void'(obj.randomize());
\$display(" Var1 : %d Var2 : %d ",obj.Var1,obj.Var2);
obj.rand_mode(1); // // Var1 and Var2 will be treated as random variables.
void'(obj.randomize());
\$display(" Var1 : %d Var2 : %d ",obj.Var1,obj.Var2);
end
endprogram

RESULTS:

# Var1 : 733126180 Var2 : -119008195
# Var1 : 733126180 Var2 : -119008195
# Var1 : 342785185 Var2 : 679818185

If arguments are Variable name, then only that variable will be non random.

EXAMPLE:
class rand_mo;
rand integer Var1;
rand integer Var2;
endclass

program rand_mo_p_24;
rand_mo obj = new();
initial
begin
void'(obj.randomize());
\$display(" Var1 : %d Var2 : %d ",obj.Var1,obj.Var2);
obj.Var1.rand_mode(0); // Var1 will become State variable
void'(obj.randomize());
\$display(" Var1 : %d Var2 : %d ",obj.Var1,obj.Var2);
obj.Var2.rand_mode(0); // Var2 will also become State variable
\$display(" Var1 : %d Var2 : %d ",obj.Var1,obj.Var2);
obj.Var1.rand_mode(1); // // Var1 will become random variable
void'(obj.randomize());
\$display(" Var1 : %d Var2 : %d ",obj.Var1,obj.Var2);
end
endprogram

RESULTS:

# Var1 : 733126180 Var2 : -119008195
# Var1 : 733126180 Var2 : 342785185
# Var1 : 733126180 Var2 : 342785185
# Var1 : 679818185 Var2 : 342785185

When rand_mode method is called as function, it returns the active status of the specified random variable.

EXAMPLE:
class rand_mo;
rand integer Var1;
rand integer Var2;
endclass

program rand_mo_p_24;
rand_mo obj = new();
initial
begin
void'(obj.randomize());
\$display(" Var1 : %d Var2 : %d ",obj.Var1,obj.Var2);
obj.Var1.rand_mode(0);
void'(obj.randomize());
\$display(" Var1 : %d Var2 : %d ",obj.Var1,obj.Var2);
if(obj.Var1.rand_mode())
\$display(" Var1 is random");
else
\$display(" Var1 is nonrandom");
void'(obj.randomize());
\$display(" Var1 : %d Var2 : %d ",obj.Var1,obj.Var2);
end
endprogram

RESULTS:

# Var1 : 733126180 Var2 : -119008195
# Var1 : 733126180 Var2 : 342785185
# Var1 is nonrandom
# Var1 : 733126180 Var2 : 679818185

If you are changing the status of a variable, which is not existing it is compilation error.

EXAMPLE:
class rand_mo;
rand integer Var1;
rand integer Var2;
endclass

program rand_mo_p_24;
rand_mo obj = new();
initial
begin
void'(obj.randomize());
\$display(" Var1 : %d Var2 : %d ",obj.Var1,obj.Var2);
obj.Var3.rand_mode(0);
void'(obj.randomize());
\$display(" Var1 : %d Var2 : %d ",obj.Var1,obj.Var2);
if(obj.Var3.rand_mode())
\$display(" Var3 is nonrandom");
void'(obj.randomize());
\$display(" Var1 : %d Var2 : %d ",obj.Var1,obj.Var2);
end
endprogram

A compiler error shall be issued if the specified variable does not exist within the class hierarchy or eventhough it exists but not declared as rand or randc. The following example illustrates the second case.

EXAMPLE:
class rand_mo;
rand integer Var1;
integer Var2;
endclass

program rand_mo_p_24;
rand_mo obj = new();
initial
begin
void'(obj.randomize());
\$display(" Var1 : %d Var2 : %d ",obj.Var1,obj.Var2);
obj.Var2.rand_mode(0);
void'(obj.randomize());
\$display(" Var1 : %d Var2 : %d ",obj.Var1,obj.Var2);
if(obj.Var2.rand_mode())
\$display(" Var1 is nonrandom");
void'(obj.randomize());
\$display(" Var1 : %d Var2 : %d ",obj.Var1,obj.Var2);
end
endprogram

In the above example, Var2 is state variable. If the random variable is an object handle, only the mode of the object is changed, not the mode of random variables within that object.

EXAMPLE:
class rand_var;
rand integer Var2;
endclass
class rand_mo;
rand integer Var1;
rand rand_var rv;
function new();
rv = new();
endfunction
endclass

program rand_mo_p_23;
rand_mo obj = new();
initial
begin
void'(obj.randomize());
\$display(" Var1 : %d Var2 : %d ",obj.Var1,obj.rv.Var2);
obj.rand_mode(0);
void'(obj.randomize());
\$display(" Var1 : %d Var2 : %d ",obj.Var1,obj.rv.Var2);
void'(obj.rv.randomize());
\$display(" Var1 : %d Var2 : %d ",obj.Var1,obj.rv.Var2);
end
endprogram

RESULTS:

Var1 : 345345423 Var2 : 234563556
Var1 : 345345423 Var2 : 234563556
Var1 : 345345423 Var2 : -2456456

Random Static Variable

Randomization does not depend on life time of variable. Even if a variable is static,randomization is specfic to object.So rand_mode() on static variable,only switches off the randomization on the variable of that object.This is true for dist and randc.
In the following example, Var1 is static and Var2 is automatic.Var1 and Var2 in obj_2 are made nonrandom using rand_mode(0).Var1 and Var2 in obj_1 are getting randomized.The only difference between Var1 and Var2 is that new random value for Var1 is appreas on both objects.

EXAMPLE:
class A;
rand static integer Var1;
rand integer Var2;
endclass

program A_p_27;
A obj_1 = new;
A obj_2 = new;

initial
begin
obj_2.Var1.rand_mode(0);
obj_2.Var2.rand_mode(0);
repeat(2)
begin
void'(obj_1.randomize());
void'(obj_2.randomize());
\$display("obj_1.Var1 : %d ,obj_1.Var2 : %d : obj_2.Var1 : %d ,obj_2.Var2 : %d :",obj_1.Var1,obj_1.Var2,obj_2.Var1,obj_2.Var2);
end
end
endprogram

RESULTS:

obj_1.Var1 : 934734534,obj_1.Var2 : 234232342: obj_2.Var1 : 934734534 ,obj_2.Var2 : 0 :
obj_1.Var1 : 908123314,obj_1.Var2 : 121891223: obj_2.Var1 : 908123314 ,obj_2.Var2 : 0 :

Random variables declared as static are shared by all instances of the class in which they are declared. Each time the randomize() method is called, the variable is changed in every class instance.

Randomizing Nonrand Varible

All the variables(randc, rand and nonrandom variables) randomization nature can be changed dynamically. Using rand_mode() rand and randc varibles changes its nature. The random nature of variables which are not declared as rand or randc can also be randomized dynamically. When the randomize method is called with no arguments, it randomizes the variables which are declared as rand or randc,so that all of the constraints are satisfied. When randomize is called with arguments, those arguments designate the complete set of random variables within that object, all other variables in the object are considered state variables.

EXAMPLE:
class CA;
rand byte x, y;
byte v, w;
constraint c1 { x < v && y > w ;}
endclass

program CA_p_28;
CA a = new;
initial
begin
a.x = 10;a.y = 10;a.v = 10;a.w = 10;
\$display(" x : %3d y : %3d : v : %3d : w : %3d ",a.x,a.y,a.v,a.w);
void'(a.randomize()); // random variables: x, y state variables: v, w
\$display(" x : %3d y : %3d : v : %3d : w : %3d ",a.x,a.y,a.v,a.w);
void'(a.randomize(x)); // random variables: x state variables: y, v, w
\$display(" x : %3d y : %3d : v : %3d : w : %3d ",a.x,a.y,a.v,a.w);
void'(a.randomize(v,w)); // random variables: v, w state variables: x, y
\$display(" x : %3d y : %3d : v : %3d : w : %3d ",a.x,a.y,a.v,a.w);
void'(a.randomize(w,x)); // random variables: w, x state variables: y, v
\$display(" x : %3d y : %3d : v : %3d : w : %3d ",a.x,a.y,a.v,a.w);
end
endprogram

RESULTS:

# x : 10 y : 10 : v : 10 : w : 10
# x : -71 y : 96 : v : 10 : w : 10
# x : -37 y : 96 : v : 10 : w : 10
# x : -37 y : 96 : v : -22 : w : 80
# x : -90 y : 96 : v : -22 : w : -41

In above example x and y are rand variables, v and w are state variables. When a.randomize() is called, all rand varibles are randomized and state variables are hold the same value. When a.randomize(w) is called, only w is considered as rand variable and all others as state varibles. Here w is in constraint block so it has to satisfy the constraints. v,y and x also are state variables now, they also need to satisfy the constraint else it fails.

Replacing the class variables, with its hierarchical result also should result same.

EXAMPLE:
program CA_p_29;
CA a = new;
initial
begin
a.x = 10;a.y = 10;a.v = 10;a.w = 10;
\$display(" x : %3d y : %3d : v : %3d : w : %3d ",a.x,a.y,a.v,a.w);
void'(a.randomize()); // random variables: x, y state variables: v, w
\$display(" x : %3d y : %3d : v : %3d : w : %3d ",a.x,a.y,a.v,a.w);
void'(a.randomize( a.x )); // random variables: x state variables: y, v, w
\$display(" x : %3d y : %3d : v : %3d : w : %3d ",a.x,a.y,a.v,a.w);
void'(a.randomize( a.v, a.w )); // random variables: v, w state variables: x, y
\$display(" x : %3d y : %3d : v : %3d : w : %3d ",a.x,a.y,a.v,a.w);
void'(a.randomize( a.w, a.x )); // random variables: w, x state variables: y, v
\$display(" x : %3d y : %3d : v : %3d : w : %3d ",a.x,a.y,a.v,a.w);
end
endprogram

RESULTS:

# x : 10 y : 10 : v : 10 : w : 10
# x : -71 y : 96 : v : 10 : w : 10
# x : -37 y : 96 : v : 10 : w : 10
# x : -37 y : 96 : v : -22 : w : 80
# x : -90 y : 96 : v : -22 : w : -41

If you are not interested to satisfy the constraints in constraint block, instead of switching off the constraint block, just randomize the variables using scope randomize() function. Scope randomize provide the ability to randomize class variables also along with non class variables.

EXAMPLE:
program CA_p_30;
integer x,y,v,w;
initial
begin
x = 10;y = 10;v = 10;w = 10;
\$display(" x : %3d y : %3d : v : %3d : w : %3d ",x,y,v,w);
randomize( x ); // random variables: x state variables: y, v, w
\$display(" x : %3d y : %3d : v : %3d : w : %3d ",x,y,v,w);
randomize(v,w ); // random variables: v, w state variables: x, y
\$display(" x : %3d y : %3d : v : %3d : w : %3d ",x,y,v,w);
randomize(w,x ); // random variables: w, x state variables: y, v
\$display(" x : %3d y : %3d : v : %3d : w : %3d ",x,y,v,w);
end
endprogram

RESULTS:

# x : 10 y : 10 : v : 10 : w : 10
# x : -826701341 y : 10 : v : 10 : w : 10
# x : -826701341 y : 10 : v : 541037099 : w : -457978538
# x : 978699393 y : 10 : v : 541037099 : w : -683182079

 << PREVIOUS PAGE TOP NEXT PAGE >> 