SystemVerilog Verification
Lecture 9
Randomization
1/28/2013
Krispan Inc. Confidential
Randomization
Historically Verification Engineers used directed stimuli to test
the functionality of the design. But as designs have become
more complex it is almost impossible to use directed tests to
test all possible scenarios and one will end up not testing all
possible scenarios and potentially a large no of bugs which
were not caught.
Using just randomization also does not solve this purpose
because that may try to test conditions which is not of
interest to the DUT and so it could be a waste of time.
So using constrained random stimulus we can resolve these
problems. But creating constrained random environment is
much more complex and takes a longer time.
1/28/2013
Krispan Inc. Confidential
Randomization
By creating constraints to limit the random values you can get
meaningful scenarios or test cases for the DUT.
Once the environment is created it is much faster to run and
improves productivity.
SystemVerilog supports the following randomization features
Constraints: Random stimulus without any constraints may take a long
time to develop meaningful scenarios. In SystemVerilog you can
constrain the blocks to provide meaningful scenarios.
Randomization: random functions to support constrained and
unconstrained randomization, weighted distribution, weighted range,
uniform range, constraint solver, random variable declaration .
Allows you to create CRT (Constrained Random TestBench) at the
transaction level when you use it with OOP.
1/28/2013
Krispan Inc. Confidential
Randomization
Test Scenarios
Constrain them
input space
Constraint Solver
Find valid solutions
DUT
valid
Exercise valid input scenarios using CRT
1/28/2013
Krispan Inc. Confidential
Random variables and methods available in
SystemVerilog
Random variable modifiers in SystemVerilog
rand:
random variable
randc: random cyclic variable. The random solver does
not repeat a random value until every possible value has
been used.
Object is randomized by calling
randomize() method Readily Available for classes with random
variables
User definable methods
pre_randomize()
post_randomize()
1/28/2013
Krispan Inc. Confidential
Simple class with Random Variables
class packet;
rand bit [31:0] data;
rand bit[15:0] addr;
//constrain the addr for word align
constraint align_addr {addr[1:0] = 2`b0}; //align_addr is the Name of the Constraint
endclass
//Generate 100 random data and word aligned address using method randomize();
packet p1;
initial begin
p1 = new;
repeat (100)
if(p1.randomize() == 1)
$display(addr = %h, data = %h\n, p1.addr, p1.data);
else
$display(randomization failure\n);
end
1/28/2013
Krispan Inc. Confidential
Simple example with random variables
class uses the rand modifier to randomize the address and
data so that a new value of addr and data are used every time
you call the randomize method to randomize the class packet.
A constraint is used to word align the address.
The randomize() method assigns random values to the
variables in the class assigned rand and randc.
You should always check the status from randomize(). If
randomization succeeds the method returns 1. otherwise it
returns 0.
Randomization may fail if you have conflicting constraints. So
you should always check the status from randomize.
1/28/2013
Krispan Inc. Confidential
Constraint details
Constraint programming methods helps you build powerful
reusable objects that can be extended and can be further
constrained in the extended object.
Constraint solver only supports 2 state values. 4 state
variables are treated as 2 state variables in the solver.
Handles cannot be referred to in a constraint block.
One of the main advantages of randomization is inheritance.
If the constraints of the derived class have the same name as
the constraint in the base class, then they can be modified
just like tasks and functions. And the constraints in the
derived class overrides the constraint of the base class.
1/28/2013
Krispan Inc. Confidential
Here is an Example of constraint
details
// The Base Class
class foo;
rand bit[15:0] addr;
rand bit [31:0] data;
constraint range {addr < 100 ; addr > 0;}
endclass : foo
// The Extended Class
class foonew extends foo;
// overrides the base constraint
constraint range {addr < 100 ; addr > 50;}
endclass : foonew
1/28/2013
Krispan Inc. Confidential
Here is an Example of constraint
details
program test;
foonew f1;
int i;
initial begin
f1 = new;
repeat(100)
if(f1.randomize() == 1)
$display(addr = %h, data = %h\n, f1.addr, f1.data);
else
$display(randomization failure\n);
end
endprogram
1/28/2013
Krispan Inc. Confidential
10
More Constraints
Adding new constraints in the derived class will change the solution space. The constraint
solver has to solve both the constraints in the base class and the derived class.
----------------------------------------------------------------------class foo;
rand bit[15:0] addr;
rand bit [31:0] data;
constraint range1 {addr < 100 ; addr > 0;}
endclass : foo
class foonew extends foo;
constraint range2 {addr > 50;}
// new constraint in extended class
endclass : foonew
----------------------------------------------------------------------Constraint solver will look at both the constraints and will use the range between 50 and
100. You can use the same program block as you used in the previous example.
1/28/2013
Krispan Inc. Confidential
11
More constraints
Inline constraints allows you to add extra constraints to
already existing constraints in your class. The solver solves the
constraints with respect to in line constraints
-------------------------------------------------------class foo;
rand bit[15:0] addr;
rand bit [31:0] data;
constraint range {addr < 100 ; addr > 0;}
endclass : foo
--------------------------------------------------------
Now you can add your inline constraints in your program
block
1/28/2013
Krispan Inc. Confidential
12
Inline constraints
program test;
foo f1;
int i;
initial begin
f1 = new;
repeat(100)
if(f1.randomize() == 1 with {addr > 50;} )
$display(addr = %h, data = %h\n, f1.addr, f1.data);
else
$display(randomization failure\n);
end
endprogram
1/28/2013
Krispan Inc. Confidential
13
Global Constraints
SystemVerilog allows you to have constraints between
variables of different objects. These are called global variables
class foo;
rand bit[15:0] src_addr;
rand bit [31:0] data;
constraint range1 {src_addr < 100 ; src_addr > 0;}
endclass : foo
class foonew
rand foo f1;
rand bit[31:0] dst_addr;
constraint global_c{dst_addr < f1.src_addr } // new global constraint
function new();
f1 = new();
endfunction
endclass : foonew
1/28/2013
Krispan Inc. Confidential
14
Global constraints
program test;
foonew fg;
int i;
initial begin
fg = new;
repeat(100)
if(fg.randomize() == 1 )
$display(src_addr = %h, dst_addr = %h, data = %h\n, fg.src_addr, fg.src_addr,
fg.data);
else
$display(randomization failure\n);
end
endprogram
When foonew object fg is randomized using the randomize method you can see all the
constraints are considered simultaneously.
1/28/2013
Krispan Inc. Confidential
15
Disabling constraints
SystemVerilog allows you to change the status of the
constraint block by calling the constraint_mode task and
using the operator 0 to disable and operator 1 to enable. By
default all the constraints are active.
Syntax is constraint_mode(b) where b is 0 or 1
class foo;
rand bit[15:0] addr;
rand bit [31:0] data;
constraint range {addr < 100 ; addr > 0;}
endclass : foo
1/28/2013
Krispan Inc. Confidential
16
Disabling constraint blocks using
constraint_mode
program test;
foo f1;
int i;
initial begin
f1 = new;
f1.randomize();
//By default all constraints are active
$display(addr = %h, data = %h\n, f1.addr, f1.data);
f1.constraint_mode(0);
//constraint for addr is turned off
f1.randomize();
$display(addr = %h, data = %h\n, f1.addr, f1.data);
f1.constraint_mode(1);
//constraint for addr is turned back on
f1.randomize();
$display(addr = %h, data = %h\n, f1.addr, f1.data);
end
endprogram
1/28/2013
Krispan Inc. Confidential
17
Constraints in a file
class foo;
rand bit[15:0] addr;
rand bit [31:0] data;
endclass : foo
You can have the constraint range for addr and data in a file
and the file should include something like this
constraint foo::range {addr < 100 ; addr > 0;}
Here we are assigning a constraint for the address to be
between 0 and 100.
Similarly you can have a constraint for data if you wanted in
the file.
1/28/2013
Krispan Inc. Confidential
18
Static Constraints
When a constraint block has static variables then constraint
mode on that block will affect on instances of the class.
class foo;
rand bit[15:0] src_addr, dst_addr;
rand bit [31:0] data;
constraint src_c{src_addr < 100 ; src_addr > 0;}
static constraint dst_c{dst_addr = 50;}
endclass : foo
dst_addr is static and src_addr is not as seen from the
example above and data is just random and has no
constraints
1/28/2013
Krispan Inc. Confidential
19
Static Constraints
program test;
foo f1, f2;
int i;
f1 = new;
f2 = new;
initial begin
f1.src_c.constraint_mode(0);
//constraint for srcaddr is turned off
f1.dst_c.constraint_mode(0);
//constraint for dstaddr is turned off
repeat (5)
f1.randomize();
$display((src_addr = %h, dst_addr = %h\n, f1.src_addr, f1.dst_addr);
end
endprogram
src_addr and dst_addr constraint is turned off for object f1. Since dst_addr is a static
constraint when it is turned off for object f1 it is automatically turned off for object f2.
1/28/2013
Krispan Inc. Confidential
20
Constraint Range
You can specify a constraint range as an expression in your
constraint block. The solver checks for values in that range. If
you want to specify the range outside of that expression then
you can use the negation operator
class foo;
rand bit[15:0] src_addr, dst_addr;
rand bit [31:0] data;
constraint range {src_addr inside{10, [50:60] [90:100]};}
static constraint dst_c{dst_addr = 50;}
endclass : foo
Here you can see src_addr can take values of 10 anything
between 50 and 60 and anything between 90 and 100. You
have to follow the syntax shown for the expression
1/28/2013
Krispan Inc. Confidential
21
Constraint range expression
class foo;
rand bit[15:0] src_addr, dst_addr;
rand bit [31:0] data;
constraint range {!(src_addr inside{10, [50:60] [90:100]});}
static constraint dst_c{dst_addr = 50;}
endclass : foo
Here we use the negation operator for the src addr constraint
expression.Here you can see src_addr can take values of anything, other
than 10, anything between 50 and 60 and anything between 90 and 100.
You have to follow the syntax shown for the expression as shown in the
example above.
1/28/2013
Krispan Inc. Confidential
22
Here is another way to define a constraint range
class foo;
rand bit[15:0] addr;
int
low, high; //Non random variables set as limits
rand bit [31:0] data;
constraint range { addr inside {[low:high]};
endclass : foo
SystemVerilog uses the values of low and high to calculate the
range of possible values. The range of values for addr is >=
low and <= high.
This is a good way of parameterizing your constraints.
1/28/2013
Krispan Inc. Confidential
23
Here is another way to define a constraint range
class foo;
rand bit[5:0] addr;
int
low, high; //Non random variables set as limits
rand bit [31:0] data;
constraint range { addr inside {[$:10], [20: $]};
endclass : foo
SystemVerilog uses the $ as a shortcut operator for minimum
and maximum values
Values for addr are 0 to 10 and 20 to 63. because $ is used
for the min and max operators.
1/28/2013
Krispan Inc. Confidential
24
Implication
Constraints can also be expressed using implicate operators
class foo;
rand bit[15:0] src_addr, dst_addr;
rand bit [31:0] data;
constraint src_dst_c { src_addr == 50 -> dst_addr == 75;}
endclass : foo
The operator -> in the constrain block states that whenever src_addr is 50 force the
dst_addr to 50. But if dst_addr is == 75 there is no constraint on src_addr. However if you
replace constraint src_dst_c to look something like this what would happen? Can anyone
guess?
class foo;
rand bit[15:0] src_addr, dst_addr;
rand bit [31:0] data;
constraint src_dst_c { dst_addr > 50; ( src_addr ==50 ) -> (dst_addr == 50);}
endclass : foo
1/28/2013
Krispan Inc. Confidential
25
Implication
Hope you guys were able to guess the right answer.
You can see there are two constraints in the
constraint block one which states dst_addr > 50 and
the second which states force dst_addr to 50 if
src_addr is equal to 50
So since dst_addr is forced to a value greater than 50
from the first constraint src_addr can never be equal
to 50.
1/28/2013
Krispan Inc. Confidential
26
If/else clause in constraint block
You can also use the if else operator in the constraint block
class foo;
rand bit[15:0] src_addr, dst_addr;
rand bit [31:0] data;
constraint src_dst_c {
if (src_addr == 0)
dst_addr = 0;
else
dst_addr = 1;
}
endclass : foo
So if src_addr is 0 force dst_addr to 0 otherwise dst_addr is 1 for all other values
of src_addr.
1/28/2013
Krispan Inc. Confidential
27
solvebefore constraint for variable ordering
Solve before constraint can be used in SystemVerilog to order variables in
a constraint block. It will not change the solution space but the probability
distribution changes.
class foo;
rand bit src_addr;
rand bit [1:0] dst_addr;
rand bit [31:0] data;
constraint src_dst_c {
// values of 0 and 1
// values of 0, 1, 2,3
(src_addr == 0) -> (dst_addr == 0);
solve src_addr before dst_addr;
}
endclass : foo
src_addr has equal probability of x = 0 and x =1 so it is a 50% probability
dst_addr has to be 0 when x = 0 and it can be 0,1,2, and 3 when x is 1.
1/28/2013
Krispan Inc. Confidential
28
Probability Distribution
solution
1
2
3
4
5
6
7
8
src_addr
0
0
0
0
1
1
1
1
dst_addr
0
1
2
3
0
1
2
3
probability
1/2
0
0
0
1/8
1/8
1/8
1/8
You can see the dst_addr is forced to 0 when src_addr is 0 and so the
probability of dst_addr being 1, 2, 3 is 0 when src_addr is 0.
Otherwise when src_addr is 1 the probability for the dst_addr being
0,1,2,3 is 1/8.
1/28/2013
Krispan Inc. Confidential
29
solvebefore constraint for variable ordering
class foo;
rand bit src_addr;
rand bit [1:0] dst_addr;
rand bit [31:0] data;
constraint src_dst_c {
// values of 0 and 1
// values of 0, 1, 2,3
(src_addr == 0) -> (dst_addr == 0);
solve dst_addr before src_addr;
}
endclass : foo
In thie example we are changing the variable ordering from
dst_addr to src_addr. The probability distribution is different.
Since the solver solves dst_addr first the probability
distribution of sr_addr being 0 is 1/8 as you can see in the
next diagram for probability distibution.
1/28/2013
Krispan Inc. Confidential
30
Probability Distribution
solution
1
2
3
4
5
6
7
8
src_addr
0
0
0
0
1
1
1
1
dst_addr
0
1
2
3
0
1
2
3
probability
1/8
0
0
0
1/8
1/4
1/4
1/4
You can see the dst_addr and src_addr 0 probability is 1/8 dst_addr 0
src_addr 1 probability is 1/8 when src_addr is 1 and dst_addr is 1, 2, 3
the probability is 1/4.
1/28/2013
Krispan Inc. Confidential
31
Weighted Random Distribution
SystemVerilog uses dist operator to do weighted random
distibution
The weights are seperated by the := and the:/ operator
:= operator specifies that the weights are the same for every value in
the range
:/ operator divides the weight equally among the values
Weights do not have to add up to hundred as they are not
percentages.
Values and weights can be constant or variables.
Lets look at some examples to understand how the weighted
operator dist works
1/28/2013
Krispan Inc. Confidential
32
Weighted Random Distribution
class foo;
rand bit[15:0] src_addr, dst_addr;
rand bit [31:0] data;
constraint src_c src_addr dist{1 := 20, [2:5] := 80};
constraint dst_c {dst_addr < 100 ; dst_addr > 0;}
endclass
src_addr gets the value 1,2,3,4,5. Here are the weights for each of them
src_addr = 1
weight = 20/340
src_addr = 2
weight = 80/340
src_addr = 3
weight = 80/340
src_addr = 4
weight = 80/340
src_addr = 5
weight = 80/340
So the total weight since you have := in the constraint is 80 X 4 + 20 = 340
and you can see the distributions of each of them
1/28/2013
Krispan Inc. Confidential
33
Weighted Random Distribution
class foo;
rand bit[15:0] src_addr, dst_addr;
rand bit [31:0] data;
constraint src_c src_addr dist{1 :/ 40, [2:5] :/80};
constraint dst_c {dst_addr < 100 ; dst_addr > 0;}
endclass
src_addr gets the value 1,2,3,4,5. Here are the weights for each of them
src_addr = 1
weight = 40/120
src_addr = 2
weight = 20/120
src_addr = 3
weight = 20/120
src_addr = 4
weight = 20/120
src_addr = 5
weight = 20/120
So the total weight since you have :/ in the constraint is 40 + 80 = 120 and
you can see the distributions of each of them
1/28/2013
Krispan Inc. Confidential
34
Random number functions
Here are some of the random number functions supported in
SystemVerilog. For more details on dist look into the LRM
$random() - returns signed 32 bit value
$urandom() returns unsigned 32 bit value
$urandom_range()- returns unsigned 32 bit value over a range
$dist_exponential() Exponential decay
$dist_normal() Bell Shaped distribution
$dist_poisson() Bell shaped distribution
$dist_uniform() Flat distribution
The $urandom_range() function takes two arguments an optional low
value and a high value. See example below.
$urandom_range(100) picks a value from 0 to 100
$urandom_range(0,100) also picks a value from 0 to 100
$urandom_range(5,100) now picks a value from 5 to 100
1/28/2013
Krispan Inc. Confidential
35
Array Randomization
SystemVerilog needs to randomize payload packets for the
different protocols we use.
SystemVerilog suuports different types of arrays fixed,
dynamic, associative, queues.
class packet;
rand byte payload[];
rand bit [31:0] data;
constraint pkt_c_size{ payload.size() inside {[48: 1500]}; }
endclass : packet
Here you are saying randomize the dynamic array payload to
be a packet of size between 48 and 1500 bytes.
1/28/2013
Krispan Inc. Confidential
36
Array continuation
program test;
packet p1;
int i;
initial begin
p1 = new;
repeat(100)
if(p1.randomize() == 1 )
$display(packet_size = %h \n, p1.payload.size());
else
$display(randomization failure\n);
end
endprogram
Here is an example wihere you repeat a loop 100 times to get different size
packets of 48 to 1500.
1/28/2013
Krispan Inc. Confidential
37
randcase
SystemVerilog can use the randcase to randomly select one of
the branches
randcase randomly selects one of the branches based on the
weight distribution.
Item weight divided by the sum of all weights gives the
probability of taking that branch.
Used in high level test cases and test mode stimulus
generation like memory fill and transaction ordering.
Branches are not order dependent and the weights need not
add upto 100%.
1/28/2013
Krispan Inc. Confidential
38
randcase
Initial begin
int length;
randcase
1: length = $urandom_range(0, 2); //weight of 1 probability of 1/10
7: length = $urandom_range(3, 7); //weight of 7 probability of 7/10
2: length = $urandom_range(8, 9); //weight of 2 probability of 2/10
endcase
$display(length= %0d, length);
end
Here we use an integer length in the initial block which has a value of
0 1 or 2 1/10th % of the time
3,4,5,6, or 7 7/10th % of the time
8 or 9 2/10th % of the time
1/28/2013
Krispan Inc. Confidential
39
randsequence
Used for randomly generating sequences of stimulus.
Useful for generating command sequences(cfg read, cfg
write, memory read, memory write, etc) with different weight
distributions.
Also another example is an ethernet packet; you can generate
unicast, broadcast, short and jumbo packets with different
weight distributions.
randsequence can be very useful for debugging because it is
procedural code and you could step through the code or add
display statements in the code to find out where the code
failed.
1/28/2013
Krispan Inc. Confidential
40
randsequence
initial begin
repeat(25)
randsequence (stream)
stream : cfg_read := 1 |
io_read := 2 |
mem_read := 5;
cfg_read : { cfg_read_task; } |
mem_read : { mem_read_task; } |
io_read : { io_read_task; }
endsequence
end
task cfg_read_task;
...
endtask
Similarly you will have memory read and io read tasks defined somewhere.
cfg_read has a weight of 1. io_read has twice the weight so is twice as likely to be
chosen. mem_read has weight of 5 so it is the most likely to be chosen
1/28/2013
Krispan Inc. Confidential
41