330 likes | 450 Views
Random Constrained Stimuli Generation. Jean-Michel Chabloz. Classes. Data type including data (properties) and subroutines (methods) class Packet ; //data or class properties bit [3:0] command; bit [40:0] address; bit [4:0] master_id; integer time_requested;
E N D
Random Constrained Stimuli Generation Jean-Michel Chabloz
Classes • Data type including data (properties) and subroutines (methods) class Packet ; //data or class properties bit [3:0] command; bit [40:0] address; bit [4:0] master_id; integer time_requested; integer time_issued; integer status; function new(); command = IDLE;address = 41'b0; master_id = 5'bx; endfunction task clean(); command = 0; address = 0; master_id = 5'bx; endtask task issue_request( int delay ); // send request to bus endtask function integer current_status(); current_status = status; endfunction endclass
Classes creation and access • To create an object of the type defined by the class, use: • Packet P; //generate a handle to an object of type Packet – initialized to null • P=new; //allocate the space for the object and automatically execute the function new() in the class for initialization • the function new() is the constructor – no return value. The constructor can be omitted from the class: in this case, the space for the new object is allocated and the initial values of the properties are retained. • new() can take arguments: • function new(bit [40:0] a); • address = a; • endfunction
Classes – Properties and methods access • Properties and methods of a class object can be accessed through: • P.master_id = 3; • a = P.command; • r = P.current_status() • etc. • Only after the class object has been created through “new”
Example: Queue of classes class InputData; bit a; bit [15:0] b; function new() begin a=0; b=0; end endclass; InputData q[$]; initial begin for(int i=0; i<10;i++) begin InputData id; id = new; id.b=i; id.a=$urandom(); q.push_front(id); end end initial begin ##10; while(q.size()!=0) begin InputData id; id=q.pop_back(id); $display(id.a,id.b); end end
Example: Queue of classes class InputData; bit a; bit [15:0] b; function new() begin a=$urandom; b=$urandom; end endclass; InputData q[$]; initial begin for(int i=0; i<10;i++) begin InputData id = new; //automatically assigns random values to a and b; q.push_front(id); end end
Classes • We only saw 1% of the things we can do with classes. • Classes in SV support more or less all the things that classes in C++ support: • inheritance • data hiding and encapsulation • virtual methods • polymorphism • …
Example of CRSG class Bus; rand bit [15:0] addr; rand bit [31:0] data; constraint word_align {addr[1:0] == 2’b0;} constraint addr_data_dep {addr==0 -> data==0;} endclass initial begin Bus busInst; busInst = new; // now busInt.addr and busInst.data are both zeroes if (!busInst.randomize()) begin $display(“randomization failed”); $finish(); end // now bustInst.addr and busInst.data have random values // that satisfy the constraints if (!busInst.randomize()) begin $display(“randomization failed”); $finish(); end // now bustInst.addr and busInst.data have other random values // that satisfy the constraints end
Constraints • Specify an expression that must be true • can optionally have a name • useful to turn them on and off • can include any type of expression: • {a ^ b == 8’b10000111 && a + b==255;} • {a > b || a + b==255;}
Inside keyword • Can be useful to indicate constraints class inData; rand bit[2:0] b; constraint bc {b inside {0, 3, [5:7]};}; endclass; class inData; rand bit[7:0] b; rand bit[7:0] c; constraint bc {b inside {0, 3, [c+1:255]};}; endclass;
Implication • Implication constraints: • constraint c1 {mode == little -> len < 10;}; • constraint c2 {mode == big -> len > 100;}; • If mode is little, then len must be < 10; • if mode is big, then len must be > 100; • Alternative syntax – uses if-else constraint c {if(mode == little) len < 10; else if(mode == big) len > 100;}
Implication • Implication {cond1 -> cond2;} • meaning: • if condition 1 is false it doesn’t matter if cond2 is true or false • if condition 1 is true than cond2 must be true • It means: cond1 cannot be true and cond2 be false at the same time • Equivalent to: {!(cond1 & !cond2);}
Implication • bit a,b; • constraint {a->b;} • possible solutions: • a==0, b==0 • a==0, b==1 • a==1, b==1 • a==1, b==0 is not acceptable
randomize • Every time we randomize a class, one among all possible combination of all random variables satisfying all constraints is selected randomly Bus bus = new; repeat (50) begin if ( bus.randomize() == 1 ) $display ("addr = %16h data = %h", bus.addr, bus.data); else $display ("Randomization failed"); end
randomize function • returns 1 if it succeeds, 0 if it fails • Why should it fail?
Randomize function • The randomize function fails when constraints are conflicting class inData; rand bit [15:0] a; constraint c1 {a > 10;} constraint c2 {a < 8;} endclass class inData; rand bit a; rand bit[31:0] data; constraint c1 {a == 1;} constraint c2 {a -> data!=0;} constraint c3 {data==0;} endclass
Adding constraints when randomizing • res = bus.randomize() with {addr[0] || addr[1];}; • in addition to all constraints given in the class, for only this randomization we add the constraint that addr[0] or addr[1] must be 1
Turning off constraints class Bus; rand bit[15:0] addr; rand bit[31:0] data; constraint word_align {addr[1:0] == 2’b0;} constraint addr_data_dep {addr==0 -> data==0;} endclass bus.randomize(); // turn off the word_align constraint bus.word_align.constraint_mode(0); bus.randomize(); bus.randomize() with {addr[0]==1;}; // turn on the word_align constraint bus.word_align.constraint_mode(1); bus.randomize();
Pre- and post-randomize class Bus; rand bit[15:0] addr; rand bit[31:0] data; constraint word_align {addr[1:0] == 2’b0;} constraint addr_data_dep {addr==0 -> data==0;} function void pre_randomize(); $display("Before randomize x=%0d, y=%0d", x, y); endfunction function void post_randomize(); $display("After randomize x=%0d, y=%0d", x, y); endfunction endclass
Pre- and post- randomize • Automatically executed just before and after the randomization takes place when calling p.randomize() • the execution flow will be as follows: • p.pre_randomize(); • p is randomized • p.post_randomize();
dist keyword class id; rand int x; constraint {x dist{100 := 1, 200 := 2, 300 := 5};} endclass; • x can take the values 100, 200, 300 with probability 1/8, 2/8, 5/8 (weights 1,2,5). • x cannot take any other values (such as 97, 262, etc.) • If there is an additional constraint x!=200, or other constraints that make x==200 not acceptable, then x takes the values 100 with 1/6 probability and 300 with 5/6 probability.
dist • dist can be made conditional: • constraint c {a -> b dist{0 := 1, 1 := 4;};} • if a is true then b is distributed according to the dist
randc • Instead of rand, members can be called as randc. • The random solver will iterate through all values in a random order, then restart a new cycle • Example: class inData; randc bit[2:0] b; endclass; 1st cycle 100 111 011 010 101 001 000 110 111 010 101 000 110 100 001 011 2nd cycle
Probability distribution • class id; • rand bit a; • rand bit [7:0] b; • constraint c1 {a==1 -> b==0;}; • endclass; • What is the probability to have a=1 after randomization?
Probability distribution • class id; • rand bit a; • rand bit [7:0] b; • constraint c1 {a==1 -> b==0;}; • endclass; • Probability is 1/257: • 1 legal combination of values with a==1 • 256 legal combination of values with a==0
Probability distribution • Rule: all combinations of legal values have the same probability to occur • To determine the probability of an event to occur, just write down all legal combinations and determine how many satisfy all constraints.
Solving order class B; rand bit s; rand bit [31:0] d; constraint c { s -> d == 0; } constraint order { solve s before d; } endclass • first the elements in s will be solved deactivating all constraints that include an element which is different than s, then s is taken as a fixed value and d is solved after turning on again all constraints
Solving order class B; rand bit a, b; rand bit [7:0] c; constraint c1 { a -> b;}; constraint c2 { a & b -> c inside {[0,4]};}; constraint c3 {c inside {[0,3]} -> a==0;} constraint order { solve a,b before c; } endclass • first c2,c3 are deactivated, a and b are randomized with only c1 active. Then c2, c3 are reactivated, all legal combinations are calculated based on the values of a and b, and c is randomized.
Solving order • first randomization: a and b are randomized with a -> b. • Legal combinations: • a=1,b=1 • a=0, b=0 • a=0, b=1 • All three have the same probability to occur
Solving order • Often it is a good idea to make a strict order between all rand variables, such as: • solve pktType before length, outPort, payload; • solve outPort before length, payload; • solve length before payload;
dynamic vector randomization • Choose length randomly, then make a random-values vector of size length • foreach gives constraints on every element of the dynamic vector • Note: without the solving order constraint, vectors with a high value of size have much higher probability to be generated class C; rand int length rand byte v[] ; constraint CL {length>3 & length <16; } constraint vSize {v.size()==length;} constraint C1 {foreach ( v [ j ] ) v[j] > 2 * j; } constraint order {solve length before v;} endclass
rand and non-rand members • classes can have both rand and non-rand members • when randomizing a class, we randomize only the random variables, the non-random keep their values • constraint can mix them together, the constraints depend on the value of the state variables class B; rand bit a, b; bit c, d; constraint c1 { d -> b;}; constraint c2 { a & b == c;}; endclass • It is possible to force this default behaviour by specifying which variables to randomize: • Binst.randomize(a) // only randomize a, consider b as a state variable • Binst.randomize(a,c) // only randomize a,c; b and d considered as state vars
Turn off a random variable • After this statement: • packet_a.source_value.rand_mode(0); • source_value inside packet_a object is considered as a state variable (not randomized when issuing randomize()) • To turn it on again use: • packet_a.source_value.rand_mode(1);