Systemverilog Constraint Random Stmulus Generaion :
We have seen how to get random values and constrain them. These constraints are at very low level of abstraction. Todays verification needs a better way to describ the constraints. SystemVerilog has randomization constructs to support todays verification needs.
Following are the features of SystemVerilog which support Constraint Random Verification (CRV) :
1) Constraints : Purely random stimulus takes too long to generate interesting senarious. Specify the interesting subset of all possible stimulus with constraint blocks. These are features provided by SystemVerilog for constraining randomness. Random variable generated in verilog Boolean expressions, foreach (for constraining elements of array), set membership, inline constraints, rand case, rand sequence, Conditional constraints and implication constraints.
2) Randomization : random function, constrained and unconstrained randomization, uniform distribution, weighted distribution,weighted range, weighted case, pre randomization, post randomization, declaration of random variable and non repeating sequence.
3) Dynamic constraints : inline constraints, guarded constraints, disabling/enabling constraints, disabling/enabling random variables and overriding of constraint blocks.
4) Random Stability : Thread stability, object stability and manual seeding.
In verilog only system functions like $random are used for stimulus generation.
In SystemVerilog, constraint random stimulus can be generated in following ways.
Random Number Generator System Functions
In addition to the system function which are in verilog, SystemVerilog has $urandom() and $urandom_range(). $urandom() and $urandom_range() returns a unsigned values.
The following example demonstrates random generation of unsigned numbers.
EXAMPLE: module Tb();
integerunsigned address;
initial begin repeat(5)
begin address = $urandom();
$display("address = %d;",address);
end end
The seed is an optional argument that determines the sequence of random numbers generated. The seed can be any integral expression. The random number generator (RNG) shall generate the same sequence of random numbers every time the same seed is used.
EXAMPLE: module Tb();
integer num,seed,i,j;
initial begin for(j = 0;j<4 ;j=j+1)
begin seed = 2;
$display(" seed is set %d",seed);
void'($urandom(seed));
for(i = 0;i < 10; i=i+1)
begin num = $urandom() % 10;
$write("| num=%2d |",num);
end $display(" ");
end end endmodule
The $urandom_range() function returns an unsigned integer within a specified range.
The syntax for $urandom_range() is as follows:
function int unsigned $urandom_range( int unsigned maxval,int unsigned minval = 0 );
The function shall return an unsigned integer in the range of maxval ... minval.
EXAMPLE: module Tb();
integer num_1,num_2;
initial begin repeat(5)
begin #1;
num_1 = $urandom_range(25,20);
num_2 = $urandom_range(55,50);
$display("num_1 = %0d,num_2 = %0d",num_1,num_2);
end end endmodule
The scope randomize function, randomize(), enables users to randomize data in the current scope.Variables which are passed as arguments are randomized and there is no limit on the number of arguments.For simpler applications,randomize() function leads to stright farward implimentation.This gives better control over the $random,as it allows to add constraints using inline constraints and constraint solver gives valid solution.Variables which are in the constraint block and not passed as arguments to randomize() function are not randomized.In the following example Variable Var is randomized and MIN is not randomized.
EXAMPLE: module scope_3;
integer Var;
initial begin for ( int i = 0;i<6 ;i++)
if( randomize(Var))
$display(" Randomization sucsessfull : Var = %0d ",Var);
else $display("Randomization failed");
$finish;
end endmodule
RESULTS:
Randomization sucsessfull : Var = -826701341 Randomization sucsessfull : Var = 541037099 Randomization sucsessfull : Var = -457978538 Randomization sucsessfull : Var = -683182079 Randomization sucsessfull : Var = 978699393 Randomization sucsessfull : Var = 717199556 Randomization sucsessfull : Var = 1114265683
Scope randomize function gives better control over the $random, as it allows to add constraints using inline constraints and constraint solver gives valid solution. Variables which are in the constraint block and not passed as arguments to randomize() function are not randomized. In the following example Variable Var is randomized and MIN is not randomized.
EXAMPLE: module scope_4;
integer Var;
integer MIN;
initial begin MIN = 50;
for ( int i = 0;i<100 ;i++)
if( randomize(Var) with { Var < 100 ; Var > MIN ;})
$display(" Randomization sucsessfull : Var = %0d Min = %0d",Var,MIN);
else $display("Randomization failed");
$finish;
end
endmodule
RESULTS:
# Randomization sucsessfull : Var = 94 Min = 50 # Randomization sucsessfull : Var = 69 Min = 50 # Randomization sucsessfull : Var = 53 Min = 50 # Randomization sucsessfull : Var = 71 Min = 50 # Randomization sucsessfull : Var = 51 Min = 50 # Randomization sucsessfull : Var = 78 Min = 50 # Randomization sucsessfull : Var = 95 Min = 50
In randomize function, the solver can't solve if X or Z is used. randomize(Var) with { Var == 'bx ;} or {MIN = 'bx} will result in an error.
Randomizing Objects
Generating random stimulus within objects :
SystemVerilog allows object-oriented programiming for random stimulus generation, subjected to specified constraints. During randomization, variables declared as rand or randc inside class are only considered for randomization. Built-in randomize() method is called to generate new random values for the declared random variables.
EXAMPLE: program Simple_pro_5;
class Simple;
randinteger Var;
endclass Simple obj;
initial begin obj = new();
repeat(5)
if(obj.randomize())
$display(" Randomization successful : Var = %0d ",obj.Var);
else $display("Randomization failed");
end endprogram
RESULTS:
# Randomization sucsessfull : Var = -82993358 # Randomization sucsessfull : Var = -112342886 # Randomization sucsessfull : Var = -867551972 # Randomization sucsessfull : Var = -34537722 # Randomization sucsessfull : Var = 1977312553
Random Unpacked Structs:
SystemVerilog allows unpackedstructs to be declared as rand for randomization. Only members of struct which are declared as rand or randc are only randomized. randc is not allowed on unpacked structs. If Struct is not declared as rand, solver considers it as state variable.
EXAMPLE: class Rand_struct;
typedefstruct {
randcint Var1;
int Var2;
} Struct_t;
rand Struct_t Str; // To randomize Var1 and Struct_t type has to declared as rand
endclass
program stru_rand_6;
Rand_struct RS ;
initial begin RS = new();
repeat(10)
if(RS.randomize())
$display(" Var1 : %d",RS.Str.Var1);
end endprogram
SystemVerilog structs are static objects, where as class instances are dynamic objects, declaring a class instance does not allocate memory space for object. Calling built in new() function creates memory for object. Class have built in functions and tasks, where as struct dont, this speeds up simulation time if structs are used. Check your data structure, if they need simple encapsulation use struct otherwise if they need object oriented mechanisms then choose class.
Rand Case :
You can use randcase to make a weighted choice between different items, without having to create a class and instance. An items weight divided by the sum of all weights gives the probability of taking that branch. More details are discussed in the following units.
Rand Sequence :
SystemVerilog provides randsequnce to generate random sequencess of operation. It will be useful for randomly generating structured sequences of stimulus such as instructions or network traffic patterns.