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


Tutorials



RANDOM STABILITY




In verilog,if the source code does not change,with the same seed,the simulator producess the same random stimulus on any mechine or any operating system.Verilog has only one Random number generator.Random stimulus is generated using $random(seed) where the seed is input to the RNG.$random will always return the same value for same seed.


EXAMPLE:
module seed_74();
initial
repeat(5)
$display("random stimuls is %d",$random(Seed);
endmodule



While debugging to produce the same simulation, we should make sure that calls to RNG is not disturbed. In Verilog if source code changes it is very unlikely that same stimulus is produced with the same seed and we miss the bug.

In SystemVerilog seeding will be done hierachily. Every module instance, interface instance, program instance and package has initialization RNG. Every thread and object has independent RNG . When ever dynamic thread is created its RNG is initialized with the next random value from its parent thread. RNG initialization and RNG generation are different process.During RNG initialization,only seed is set to RNG. When ever static thread is created its RNG is initialized with the next random value from the initialization RNG of module instance, interface instance, program interface or package containing thread declaration. RNG initialization and RNG generation are different process. During RNG initialization,only seed is set to RNG.
The random number generator is deterministic. Each time the program executes, it cycles through the same random sequence. This sequence can be made nondeterministic by seeding the $urandom function with an extrinsic random variable, such as the time of day.

SystemVerilog system functions $urandom and $urandom_range are thread stable. Calls to RNG using these system function, uses the RNG of that thread. So next time while using $random in SystemVerilog,think twice.

NOTE: The same stimulus sequence can not be produced on different simulators as the LRM does not restrict the vendors to impliment specific constraint solver. Verilog LRM specifies the RNG algorithm for $random ,so the same stimulas can be produced on different simulators(not always as I discussed in one of the above topic). Even if the SystemVerilog LRM specifies RNG algorithm ,the same sequence cannot be produced on different vendors because of the following are few reasons :
-> LRM doesnot restrict the constraint solver algorithm.
-> Order of threads creation.
-> Order of thread execution.



EXAMPLE:
class Ran_Stb_1;
rand bit [2:0] Var;
endclass

program Ran_Stb_p_75;
Ran_Stb_1 obj_1 = new();
initial
repeat(10)
begin
void'(obj_1.randomize());
$display(" Ran_Stb_1.Var : %0d ",obj_1.Var);
end
endprogram

RESULTS:

# Ran_Stb_1.Var : 4
# Ran_Stb_1.Var : 5
# Ran_Stb_1.Var : 1
# Ran_Stb_1.Var : 1
# Ran_Stb_1.Var : 0
# Ran_Stb_1.Var : 2
# Ran_Stb_1.Var : 2
# Ran_Stb_1.Var : 7
# Ran_Stb_1.Var : 6
# Ran_Stb_1.Var : 0



Stimulus generated in a thread or object is independed of other stimulus. So changes in the source code will not effect threads or objects. This is Valid as long as the order of the threads is not distrubed. If a new object is created, make sure that that they are added at the end.


EXAMPLE:
class Ran_Stb_1;
rand bit [2:0] Var;
endclass

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

program Ran_Stb_p_76;
Ran_Stb_1 obj_1 = new();
Ran_Stb_2 obj_2 = new();
initial
repeat(10)
begin
void'(obj_1.randomize());
$display(" Ran_Stb_1.Var : %0d ",obj_1.Var);
end
endprogram



New object obj_2 is added after all the objects. Look at the simulation results,they are same as the above.


RESULTS:

# Ran_Stb_1.Var : 4
# Ran_Stb_1.Var : 5
# Ran_Stb_1.Var : 1
# Ran_Stb_1.Var : 1
# Ran_Stb_1.Var : 0
# Ran_Stb_1.Var : 2
# Ran_Stb_1.Var : 2
# Ran_Stb_1.Var : 7
# Ran_Stb_1.Var : 6
# Ran_Stb_1.Var : 0



If a new thread is added, make sure that it is added after all the threads.


EXAMPLE:
class Ran_Stb_1;
rand bit [2:0] Var;
endclass

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

program Ran_Stb_p_77;
Ran_Stb_1 obj_1 = new();
Ran_Stb_2 obj_2 = new();
initial
begin
repeat(5)
begin
void'(obj_1.randomize());
$display(" Ran_Stb_1.Var : %0d ",obj_1.Var);
end
repeat(5)
begin
void'(obj_2.randomize());
$display(" Ran_Stb_2.Var : %0d ",obj_2.Var);
end
end
endprogram



The results show clearly that Random values in obj_1 are same as previous program simulation.


RESULTS:

# Ran_Stb_1.Var : 4
# Ran_Stb_1.Var : 5
# Ran_Stb_1.Var : 1
# Ran_Stb_1.Var : 1
# Ran_Stb_1.Var : 0
# Ran_Stb_2.Var : 3
# Ran_Stb_2.Var : 3
# Ran_Stb_2.Var : 6
# Ran_Stb_2.Var : 1
# Ran_Stb_2.Var : 1



Order of the randomize call to different objects doesnot effect the RNG generation.



EXAMPLE:
class Ran_Stb_1;
rand bit [2:0] Var;
endclass

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

program Ran_Stb_p_78;
Ran_Stb_1 obj_1 = new();
Ran_Stb_2 obj_2 = new();
initial
begin
repeat(5)
begin
void'(obj_2.randomize());
$display(" Ran_Stb_2.Var : %0d ",obj_2.Var);
end
repeat(5)
begin
void'(obj_1.randomize());
$display(" Ran_Stb_1.Var : %0d ",obj_1.Var);
end
end
endprogram

RESULTS:

# Ran_Stb_2.Var : 3
# Ran_Stb_2.Var : 3
# Ran_Stb_2.Var : 6
# Ran_Stb_2.Var : 1
# Ran_Stb_2.Var : 1
# Ran_Stb_1.Var : 4
# Ran_Stb_1.Var : 5
# Ran_Stb_1.Var : 1
# Ran_Stb_1.Var : 1
# Ran_Stb_1.Var : 0



Adding a constraint in one class, will only effect the stimuls of that object only.


EXAMPLE:
class Ran_Stb_1;
rand bit [2:0] Var;
constraint C { Var < 4 ;}
endclass

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

program Ran_Stb_p_79;
Ran_Stb_1 obj_1 = new();
Ran_Stb_2 obj_2 = new();
initial
repeat(5)
begin
void'(obj_1.randomize());
void'(obj_2.randomize());
$display(" Ran_Stb_1.Var : %0d :: Ran_Stb_2.Var : %0d ",obj_1.Var,obj_2.Var);
end
endprogram

RESULTS:

# Ran_Stb_1.Var : 0 :: Ran_Stb_2.Var : 3
# Ran_Stb_1.Var : 1 :: Ran_Stb_2.Var : 3
# Ran_Stb_1.Var : 1 :: Ran_Stb_2.Var : 6
# Ran_Stb_1.Var : 1 :: Ran_Stb_2.Var : 1
# Ran_Stb_1.Var : 0 :: Ran_Stb_2.Var : 1


Srandom



When an object or thread is created, its RNG is seeded using the next value from the RNG of the thread that creates the object. This process is called hierarchical object seeding. Sometimes it is desirable to manually seed an objects RNG using the srandom() method. This can be done either in a class method or external to the class definition. Example to demonstrate seeding in objects.


EXAMPLE:
class Rand_seed;
rand integer Var;
function new (int seed);
srandom(seed);
$display(" SEED is initised to %0d ",seed);
endfunction

function void post_randomize();
$display(": %0d :",Var);
endfunction
endclass

program Rand_seed_p_80;
Rand_seed rs;
initial
begin
rs = new(20);
repeat(5)
void'(rs.randomize());
rs = new(1);
repeat(5)
void'(rs.randomize());
rs = new(20);
repeat(5)
void'(rs.randomize());
end
endprogram

RESULTS:

# SEED is initised to 20
# : 1238041889 :
# : 1426811443 :
# : 220507023 :
# : -388868248 :
# : -1494908082 :
# SEED is initised to 1
# : 1910312675 :
# : 632781593 :
# : -453486143 :
# : 671009059 :
# : -967095385 :
# SEED is initised to 20
# : 1238041889 :
# : 1426811443 :
# : 220507023 :
# : -388868248 :
# : -1494908082 :



Simulation results show that same sequence is repeated when the same seed is used for initialization.

Example to demonstrate seeding a thread.


EXAMPLE:
integer x, y, z;
fork //set a seed at the start of a thread
begin process::self.srandom(100); x = $urandom; end
//set a seed during a thread
begin y = $urandom; process::self.srandom(200); end
// draw 2 values from the thread RNG
begin z = $urandom + $urandom ; end
join




The above program fragment illustrates several properties:
Thread locality: The values returned for x, y, and z are independent of the order of thread execution. This is an important property because it allows development of subsystems that are independent, controllable, and predictable.
Hierarchical seeding: When a thread is created, its random state is initialized using the next random value from the parent thread as a seed. The three forked threads are all seeded from the parent thread.





IEEE 2005 SystemVerilog LRM does not specify whether scope randomization function is random stable or not.

From LRM
13.13 Random stability
The RNG is localized to threads and objects. Because the sequence of random values returned by a thread or object is independent of the RNG in other threads or objects, this property is called random stability.

Random stability applies to the following:

The system randomization calls, $urandom() and $urandom_range()
The object and process random seeding method, srandom()
The object randomization method, randomize()

In above its mentioned that "object randomization method, randomize()". There is nothing mentioned about std::randomize() method random stability.


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