IEEE SystemVerilog 2005 LRM does not specify the constraint solver algorithm. So different vendors use different consraint solver algorithms. Some vendors may get the solution quickly, some may not.
All the points discussed in this are not specific to a vendor. Just check your tool with these examples to know how ur vendor constraint solver works.
As it is handy to type int and integer, we always declare some data types like size of dynamic arrays as integer and constraint it to required range.
This will create 2^32 values and solver has to choose random number and solve the constraint which will hit only few times.
Probability of a random value to be in solution space is less than appearing it outside the solution space. To speed up ur solver, use the proper data types.
In the following example i showed the results of Questasim tool.
integer is 32 bit datatype.
shortint is 16 bit datatype.
byte is 8 bit datatype.
EXAMPLE: program inte_p_62;
class inte;
randinteger Var;
constraint randge_c { Var inside {[0:10]};}
endclass inte obj=new();
initial begin repeat(10000)
void'(obj.randomize());
$finish(2);
end endprogram RESULT:
# ** Note: Data structure takes 3407960 bytes of memory # Process time 2.78 seconds
EXAMPLE: program inte_p_62;
class inte;
randbit [4:0] Var;
constraint randge_c { Var inside {[0:10]};}
endclass inte obj=new();
initial begin repeat(10000)
void'(obj.randomize());
$finish(2);
end endprogram
RESULT:
# ** Note: Data structure takes 3407960 bytes of memory # Process time 1.95 seconds
To generate a random value which is one of the 2**0,2**1,2**2,......2**31.
If data type is integer and randomizing it will consume lot of simulation time.
constraint C { Var inside {2**0,2**1,2**2,......2**31};}
Write a function to check only one bit is high.
constraint C { $countones(array) == 1 ;)
constraint C { Var == (1 << index) ;}
Instead declare an 5 bit variable index, randomize it and set the index bit to 1 in post randomize.
EXAMPLE: class expo_cons_64;
randbit [0:4] index;
integer array; // No need to randomize array
functionvoid post_randomize;
array = 'b0;
array[index]=1'b1;
endfunction endclass
Adding smaller constraints in to a single block, speeds up simulation for some simulators. Check these examples with your simulator. Some Solver may need more iterations to get the valid solution. Split the constraints as small as possible. With this controllability on constraint blocks is also improved.
EXAMPLE:1 class constr;
randint a,b,c,d;
constraint C { (a == 10)&&( b < 20 ) && (c > 30) && (d < 40) ;}
endclass
program constr_p_65;
constr obj;
initial begin obj=new();
repeat(10000)
void'(obj.randomize());
$finish(2);
end endprogram RESULT:
# ** Note: Data structure takes 3276888 bytes of memory # Process time 9.44 seconds
EXAMPLE:2 class constr;
randint a,b,c,d;
constraint Ac {(a == 10);}
constraint Bc {(b < 20) ;}
constraint Cc {(c > 30) ;}
constraint Dc {(d < 40) ;}
endclass
program constr_p_66;
constr obj;
initial begin obj=new();
repeat(10000)
void'(obj.randomize());
$finish(2);
end endprogram RESULT:
# ** Note: Data structure takes 3407960 bytes of memory # Process time 9.27 seconds
EXAMPLE:3 class constr_67;
randint a,b,c,d;
constraint Ac { (a == 10) ; ( b < 20 ) ; (c > 30) ; (d < 40) ;}
endclass
program constr_p_67;
constr_p_67 obj;
initial begin obj=new();
repeat(10000)
void'(obj.randomize());
$finish(2);
end endprogram RESULT:
# ** Note: Data structure takes 3407960 bytes of memory # Process time 9.24 seconds
Run all the above three examples with your simulator and check how your simulation speed varies.
When iterative constraints are used on arrays, each element has a constraint on it. If the constraints are simple enough to implement with out using constraint block, simulation time may be saved. In the following example, there are two constraints blocks, one for size other for each element. In reality there may be more constraint blocks.
EXAMPLE: class Eth_pkt;
randbyte Payload[] ;
constraint size_c { Payload.size() inside {[46:1500]}; }
constraint element_c { foreach ( Payload[ i ] ) Payload[ i ] inside {[50:100]}; }
endclass
program iterative_68;
Eth_pkt obj;
initial begin obj = new();
for(int i=0;i< 10000;i++)
begin if(obj.randomize())
$display(" RANDOMIZATION DONE ");
end $finish(2);
end endprogram RESULT:
# ** Note: Data structure takes 3407960 bytes of memory # Process time 705.51 seconds
The above logic can implemented using post_randomize. Check how these two example with ur vendor tool and look at the simulation speed. You may find difference.
program iterative_69;
Eth_pkt obj;
initial begin obj = new();
for(int i=0;i< 10000;i++)
begin if(obj.randomize())
$display(" RANDOMIZATION DONE ");
end $finish(2);
end endprogram
# ** Note: Data structure takes 3539032 bytes of memory # Process time 3.92 seconds