Tutorials VARIABLE ORDERING

SystemVerilog constraints provide a mechanism for ordering variables so that some variables can be chosen independently of some variables. The solution space remains the same, but the probability of picking up the solution space changes. The syntax for variable ordering is "solve x before y". The exact meaning of this statement is "choos x before y" as the this statement is to guide the distribution, but not the solution space.
Only rand variables are allowed.

EXAMPLE:
class Var_order_56;
rand bit a;
rand bit [3:0] b;
constraint bidirectional { a -> b == 0; }
endclass

The probability of a=1 is 1/((2**5)-15)=1/17, as constraints are bidirectional i.e both the values of a and b are determined together. Constraints will be solved only once, the solver picks the one solution from the possible set of {a,b} which has 17 solutions. To guide the probability of selecting a= 0 to 50% and a = 1 to 50%, use

constraint order { solve a before b ;}

This guides the solver to give highest priority to a than b while picking the solution from solution space. This is explicit variable ordering. The solver follows the implicit variable ordering also, like randc are solved before rand variables. In dynamic arrays size and elements are solved with two constraints( size constraint and element value constraint) ,array size is solved before element.

EXAMPLE:
class if_57;
rand bit a;
rand bit [3:0] b;
constraint c { if(a == 0) (b == 1); }
constraint order { solve a before b;}
endclass

program if_p;
if_57 obj;
integer count_0 ,count_1 ;

initial
begin
count_0 = 0;count_1 = 0;
for(int i=0; i< 10000; i++)
begin
obj = new();
if( obj.randomize())
if( obj.a == 0 ) count_0 ++;
else if( obj.a == 1 ) count_1 ++;
end
\$display(" count_0 = %0d;count_1 = %0d;",count_0 ,count_1);
end
endprogram

RESULTS:

# count_0 = 4974;count_1 = 5026;

Too many explicit variable ordering may lead to circular dependency. The LRM says that "Circular dependencies created by the implicit variable ordering shall result in an error." and "circular dependency is not allowed". But it does not put restriction on what to do if a explicit circular dependency exists. Check with your tool, if explicit Circular dependency is existing, it may report warning,it may fail solver or proceed by just ignoring the order.

EXAMPLE:
program Cir_Dip_p_58;
class Cir_Dep;
rand integer a,b,c;
constraint a_c { solve a before b ;}
constraint b_c { solve b before c ;}
constraint c_c { solve c before a ;}
endclass

Cir_Dip obj=new();
initial
void'(obj.randomize());
endprogram

RESULTS:

Error: Cird.sv(14): Cyclical dependency between random variables specified by solve/before constraints.

LRM says, if the outcome is same, solver can solve without following the rule. In the following case, x has only one possible assignment (0), so x can be solved for before y. The constraint solver can use this flexibility to speed up the solving process.

EXAMPLE:
class slove_before;
rand integer x,y;
constraint C {x == 0;
x < y;
solve y before x; }
endclass

program s_b_59;
slove_before obj ;
initial
begin
obj = new();
repeat(5)
if(obj.randomize())
\$display(" x : %d :: y :%d ",obj.x,obj.y);
else
\$display("Randomization failed ");
end
endprogram

RESULTS:

# x : 0 :: y : 2064490291
# x : 0 :: y : 2035140763
# x : 0 :: y : 1279931677
# x : 0 :: y : 2112945927
# x : 0 :: y : 1977312554

Functions

Functions are allowed in constraints. It will be useful in applications like constrain the max packet size based on the bandwidth other parameters. Constraint statements are more error pron. Functions in constraints are called before constraints are solved. The return value of the function is used to solve the constraint and it is treated as state variable. There is an implicit variable ordering when solving these constraints. Function should not be declared as static and should not modify the constraints, for example calling the rand_mode and constraint_mode methods.

EXAMPLE:
class B_61;
rand int x, y;
constraint C { x <= F(y); }
constraint D { y inside { 2, 4, 8 } ; }
endclass

Random variables used as function arguments shall establish an implicit variable ordering or priority. Constraints that include only variables with higher priority are solved before other lower priority constraints. Random variables solved as part of a higher priority set of constraints, become state variables to the remaining set of constraints. In above example y is solved before x. If y is not rand variable, then F(y) is equalent to calling it in the pre_randomize method.

Iterative Constraints

Iterative constraints allow Constraining individual elements of fixed-size, dynamic, associative arrays or queue. foreach construct specifies iteration over the each elements of array.

EXAMPLE:
class Eth_pkt_60;
rand byte Payload[] ;
constraint size_c { Payload.size() inside {[10:1500]}; }
constraint element_c { foreach ( Payload[ i ] ) Payload[ i ] inside {[50:100]}; }
function void post_randomize;
\$display( " Payload[ %0d ] :%d ",i,Payload[ i ] );
endfunction
endclass

program iterative_60;
Eth_pkt_60 obj;
initial
begin
obj = new();
if(obj.randomize())
\$display(" RANDOMIZATION DONE ");
end
endprogram

RESULTS:

# Payload[ 0 ] : 87
# Payload[ 1 ] : 52
# Payload[ 2 ] : 70
# Payload[ 3 ] : 76
# Payload[ 4 ] : 71
# Payload[ 5 ] : 63
# Payload[ 6 ] : 62
# Payload[ 7 ] : 63
# Payload[ 8 ] : 66
# Payload[ 9 ] : 85
# Payload[ 10 ] : 95
# Payload[ 11 ] : 57
# Payload[ 12 ] : 78

NOTE: Remember while randomizing each element of array also array should be declared as random variable otherwise randomization wont happen.
 << PREVIOUS PAGE TOP NEXT PAGE >> 