|HOME |ABOUT |ARTICLES |ACK |FEEDBACK |TOC |LINKS |BLOG |JOBS |


Tutorials



CONSTRAINT EXPRESSION




A constraint_expression is any SystemVerilog expression or one of the constraint specific operators( -> (Implication) and dist). Functions are allowed to certain limitation. Operators which has side effects are not allowed like ++,--.




Set Membership



A set membership is a list of expressions or a range. This operator searches for the existences of the value in the specified expression or range and returns 1 if it is existing.



EXAMPLE:
class set_mem;
rand integer Var;
constraint range { Var inside {0,1,[50:60],[90:100]}; }
function void post_randomize();
$write("%0d__",Var);
endfunction
endclass

program set_mem_p_47;
set_mem obj=new();
initial
repeat(10)
void'(obj.randomize());
endprogram

RESULTS:

50__57__60__93__100__94__90__1__54__100__



If you want to define a range which is outside the set, use negation.



EXAMPLE:
class set_mem;
rand bit [0:2] Var;
constraint range { !( Var inside {0,1,5,6});}
function void post_randomize();
$write("%0d__",Var);
endfunction
endclass

program set_mem_p_48;
set_mem obj=new();
initial
repeat(10)
void'(obj.randomize());
endprogram


RESULTS:

7__4__4__4__7__2__2__3__2__7__



Engineers often mistaken that set membership operator is used only in constraint block. It can also be used in other scopes also.


class set_mem;
rand bit [0:2] Var;
endclass

program set_mem_p_48;
set_mem obj=new();
integer repet = 0;
initial
begin
obj.Var = 1;
repeat(10)
begin
void'(obj.randomize());
while ( obj.Var inside {[1:5]})
begin
$display("Var = %0d",obj.Var);
break;
end
end
end
endprogram
RESULTS:

# Var = 4
# Var = 5
# Var = 1
# Var = 1
# Var = 2
# Var = 2




NOTE: X and Z are allowed in set membership operator, but not in constraint block, inside {....} is a statement which returns 0,1 or X .
Expressions are allowed in value set of inside operator.



rand integer y,x;
constraint c1 {x inside {3, 5,[y:2*y], z};}



If an expression in the list is an array then just use the array name in the constraint block. Elements are traversed by descending into the array until reaching a singular value.



int array [$] = '{3,4,5};
if ( ex inside {1, 2, array} )


Weighted Distribution



There are two types of distribution operators.
The := operator assigns the specified weight to the item or, if the item is a range, to every value in the range.
The :/ operator assigns the specified weight to the item or, if the item is a range, to the range as a whole. If there are n values in the range, the weight of each value is range_weight / n.



Var dist { 10 := 1; 20 := 2 ; 30 := 2 }


The probability of Var is equal to 10,20 and 30 is in the ratio of 1,2,2 respectively.


Var dist { 10 := 1; 20 := 2 ; [30:32] := 2 }


The probability of Var is equal to 10,20,30,31 and 32 is in the ratio of 1,2,2,2,2 respectively.
If you use the := operator each element weitht of the range has the assigned weight.
If you want to weight for the whole group,use :/ and the weight is equally distributed for each element in that group.


Var dist { 10 := 1; 20 := 2 ; [30:32] :/ 2 }


The probability of Var is equal to 10,20,30,31,32 is in the ration of 1,2,2/3,2/3,2/3 respectively.

To demonstrate the distribution property,hear is an example.


EXAMPLE:
class Dist;
rand integer Var;
constraint range { Var dist { [0:1] := 50 , [2:7] := 50 }; }
endclass

program Dist_p_49;
Dist obj;
integer count_0, count_1, count_2, count_3, count_4, count_5, count_6, count_7;
integer count_0_1 ,count_2_7 ;

initial
begin
obj=new();
count_0 = 0;count_1 = 0;count_2 = 0;count_3 = 0;
count_4 = 0;count_5 = 0;count_6 = 0;count_7 = 0;
count_0_1 = 0;count_2_7 = 0;
for(int i=0; i< 10000; i++)
if( obj.randomize())
begin
if( obj.Var == 0) count_0 ++;
else if( obj.Var == 1) count_1 ++;
else if( obj.Var == 2) count_2 ++;
else if( obj.Var == 3) count_3 ++;
else if( obj.Var == 4) count_4 ++;
else if( obj.Var == 5) count_5 ++;
else if( obj.Var == 6) count_6 ++;
else if( obj.Var == 7) count_7 ++;
if( obj.Var inside {0,1} ) count_0_1 ++;
else if( obj.Var inside {[2:7]} ) count_2_7 ++;
end

$display(" count_0 = %0d , count_1 = %0d, count_2 = %0d, count_3 = %0d, count_4 = %0d, count_5 = %0d, count_6 = %0d, count_7= %0d ",count_0, count_1, count_2, count_3, count_4, count_5, count_6, count_7);
$display(" count_0_1 = %0d ;count_2_7 = %0d ",count_0_1,count_2_7);
$finish;
end
endprogram

RESULTS:

# count_0 = 1290 , count_1 = 1244, count_2 = 1286, count_3 = 1265, count_4 = 1230, count_5 = 1243, count_6 = 1189, count_7= 1253
# count_0_1 = 2534 ;count_2_7 = 7466



Now change the constraint to



constraint range { Var dist { [0:1] :/ 50 , [2:7] :/ 50 }; }

EXAMPLE:
class Dist;
rand integer Var;
constraint range { Var dist { [0:1] :/ 50 , [2:7] :/ 50 }; }
endclass

program Dist_p_50;
Dist obj;
integer count_0, count_1, count_2, count_3, count_4, count_5, count_6, count_7;
integer count_0_1 ,count_2_7 ;

initial
begin
obj=new();
count_0 = 0;count_1 = 0;count_2 = 0;count_3 = 0;
count_4 = 0;count_5 = 0;count_6 = 0;count_7 = 0;
count_0_1 = 0;count_2_7 = 0;

for(int i=0; i< 10000; i++)
if( obj.randomize())
begin
if( obj.Var == 0) count_0 ++;
else if( obj.Var == 1) count_1 ++;
else if( obj.Var == 2) count_2 ++;
else if( obj.Var == 3) count_3 ++;
else if( obj.Var == 4) count_4 ++;
else if( obj.Var == 5) count_5 ++;
else if( obj.Var == 6) count_6 ++;
else if( obj.Var == 7) count_7 ++;
if( obj.Var inside {0,1} ) count_0_1 ++;
else if( obj.Var inside {[2:7]} ) count_2_7 ++;
end

$display(" count_0 = %0d , count_1 = %0d, count_2 = %0d, count_3 = %0d, count_4 = %0d, count_5 = %0d, count_6 = %0d, count_7= %0d ",count_0, count_1, count_2, count_3, count_4, count_5, count_6, count_7);
$display(" count_0_1 = %0d ;count_2_7 = %0d ",count_0_1,count_2_7);
$finish;
end
endprogram

RESULTS:

# count_0 = 2496, count_1 = 2508, count_2 = 846, count_3 = 824, count_4 = 833, count_5 = 862, count_6 = 820, count_7= 811
# count_0_1 = 5004 ;count_2_7 = 4996





Both the results show, how may times each value occured.

NOTE: If no weight is specified for items,the default weight is 1. Weight 0 is also allowed.
NOTE: Variable declared as randc are not allowed int dist.

If there are constraints on some expressions that cause the distribution weights on these expressions to be not satisfiable, implementations are only required to satisfy the non dist constraints. Use dist only on a one variable in a set of constraint expression variable.
In the following example, Even though probability of Var2 is equal to 0 to 1 is in ratio of 50, 50 to satisfy other constraints, the dist is ignored.




EXAMPLE:
class Dist;
rand integer Var1,Var2;
constraint dist_c { Var2 dist { [0:1] := 50 , [2:7] := 50 }; }
constraint relation_c { Var1 < Var2; }
constraint range_c { Var2 inside {2,3,4};}
endclass

program Dist_p_51;
Dist obj;
integer count_0, count_1, count_2, count_3, count_4, count_5, count_6, count_7;
integer count_0_1 ,count_2_7 ;

initial
begin
obj=new();
count_0 = 0;count_1 = 0;count_2 = 0;count_3 = 0;
count_4 = 0;count_5 = 0;count_6 = 0;count_7 = 0;
count_0_1 = 0;count_2_7 = 0;

for(int i=0; i< 10000; i++)
if( obj.randomize())
begin
if( obj.Var2 == 0) count_0 ++;
else if( obj.Var2 == 1) count_1 ++;
else if( obj.Var2 == 2) count_2 ++;
else if( obj.Var2 == 3) count_3 ++;
else if( obj.Var2 == 4) count_4 ++;
else if( obj.Var2 == 5) count_5 ++;
else if( obj.Var2 == 6) count_6 ++;
else if( obj.Var2 == 7) count_7 ++;
if( obj.Var2 inside {0,1} ) count_0_1 ++;
else if( obj.Var2 inside {[2:7]} ) count_2_7 ++;
end

$display(" count_0 = %0d , count_1 = %0d, count_2 = %0d, count_3 = %0d, count_4 = %0d, count_5 = %0d, count_6 = %0d, count_7= %0d ",count_0, count_1, count_2, count_3, count_4, count_5, count_6, count_7);
$display(" count_0_1 = %0d ;count_2_7 = %0d ",count_0_1,count_2_7);
$finish;
end
endprogram

RESULTS:

# count_0 = 0 , count_1 = 0, count_2 = 3362, count_3 = 3321, count_4 = 3317, count_5 = 0, count_6 = 0, count_7= 0
# count_0_1 = 0 ;count_2_7 = 10000



Calling a new(), resets the distrubution algorithem. If new() is called to creat an object when ever randomized is called,the dist algorithm restarts and the distribution may not be what is expected.



EXAMPLE:
class Dist;
rand integer Var;
constraint range { Var dist { [0:1] := 50 , [2:7] := 50 }; }
endclass

program Dist_p_52;
Dist obj;
integer count_0_1 ,count_2_7 ;

initial
begin
obj=new();
count_0_1 = 0;count_2_7 = 0;
for(int i=0; i< 10000; i++)
begin
obj = new();
if( obj.randomize())
if( obj.Var inside {0,1} ) count_0_1 ++;
else if( obj.Var inside {[2:7]} ) count_2_7 ++;
end
$display("count_0_1 : %0d : count_2_7 : %0d ",count_0_1,count_2_7);
end
endprogram

RESULTS:

# count_0_1 : 3478 : count_2_7 : 6522




The distribution is not followed if the variable is declared as randc as distribution may require repetition and randc doesnot allow. In the below example try changing the weights in distribution function, you will get always same results otherwise compilation error.



EXAMPLE:
class Dist;
randc byte Var;
constraint range { Var dist { [0:1] := 50 , [2:7] := 50 }; }
endclass

program Dist_p_52;
Dist obj;
integer count_0_1 ,count_2_7 ;

initial
begin
obj=new();
count_0_1 = 0;count_2_7 = 0;
for(int i=0; i< 10000; i++)
begin
if( obj.randomize())
if( obj.Var inside {0,1} ) count_0_1 ++;
else if( obj.Var inside {[2:7]} ) count_2_7 ++;
end
$display("count_0_1 : %0d : count_2_7 : %0d ",count_0_1,count_2_7);
end
endprogram





To constraint enumerated values using dist, if they are less number, give weights individually. If you want to give weights to enumerated values in groups, then give a continues group. As enumeration is represented in integer, the discontinuation in the declaration may not result properly.



EXAMPLE:
program enums_53;
typedef enum {V_SMALL,SMALL,MEDIUM,LARGE,V_LARGE} size_e;
class dist_c;
rand size_e size_d;
constraint size_dist{size_d dist {[V_SMALL:MEDIUM] :/40,[LARGE:V_LARGE] :/ 60}; }
endclass

initial begin
dist_c obj;
obj=new;
for (int i=0; i<=10; i++)
begin
obj.randomize();
$display (" size_d = %0s ", obj.size_d);
end
end
endprogram

Implication



Implication operator can be used to declare conditional relation. The syntax is expression -> constraint set. If the expression is true,then the constraint solver should satisfy the constraint set. If the expression is false then the random numbers generated are unconstrainted by constraint set. The boolean equivalent of a -> b is (!a || b).



rand bit a;
rand bit [3:0] b;
constraint c { (a == 0) -> (b == 1); }


a is one and b is 4 bit, So there are total of 32 solutions. But due to constraint c (when ever a is 0 b should be 1) 15 solutions are removed. So probability of a = 0 is 1/(32-15) = 1/17. If u observe the following program results count_0/count_1 approximately equal to 1/17.



EXAMPLE:
class impli;
rand bit a;
rand bit [3:0] b;
constraint c { (a == 0) -> (b == 1); }
endclass

program impli_p_54;
impli obj;
integer count_0 ,count_1 ;

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

RESULTS:

# count_0 = 571;count_1 = 9429;


If..Else



Just like implication, if...else style constraints are bidirectional.Above example applies hear too.


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

program if_else_p_55;
if_else obj;
integer count_0 ,count_1 ;

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

RESULTS:

# count_0 = 571;count_1 = 9429;

Index
Constrained Random Verification
Verilog Crv
Systemverilog Crv
Randomizing Objects
Random Variables
Randomization Methods
Checker
Constraint Block
Inline Constraint
Global Constraint
Constraint Mode
External Constraints
Randomization Controlability
Static Constraint
Constraint Expression
Variable Ordering
Constraint Solver Speed
Randcase
Randsequence
Random Stability
Array Randomization
Constraint Guards
Titbits

Report a Bug or Comment on This section - Your input is what keeps Testbench.in improving with time!





<< PREVIOUS PAGE

TOP

NEXT PAGE >>

copyright 2007-2017 :: all rights reserved www.testbench.in::Disclaimer