Randomization is the ablity in systemverilog to generate psuerandom values using differnt constructs and keywords. Randomization when used along with OOPs cocenpts give the engineer the strong ability to create random stimulus. Given below are the most important keywords which one must be familiar with when it comes to the SystemVerilog randomization topic.
rand
randc
constraint
solve-before
soft
disable soft
:=
:/
->
inside {}
dist {}
randomize
randomize with {}
randcase
randsequence
// Constraint can be disabled by // a. Calling constraint_mode on the specific constraint // b. Extending the parent class and overriding the original constraint by declaring it again in the child class
// Constraint randomization has the following advantages over directed randomization // 1. Its easier to write the value ranges in which we want a randim value // 2. Easier to manage constraints through the OOPs concepts // 3. Its possible to write distribution based rand value generation // 4. More input stimulus combinations can be covered with almost no manual effort // 5. Makes testing far more easier and quicker
// Systemverilog randomization has the following advantages over verilog randomization // 1. Its possible to write constraints/rules to define the range of values which the solve can psuerandomly pick // 2. Its possible to generate a n-bit random number unlike verilog, where atmost 32bit can be generated using $random // 3. Constraint solvers now are much more efficient and easily cover a large range of random value more efficiently // 4. Its easier to add new rules while making sure older restrictions are intact unlike in verilog where everything has to be rechecked // 5. Combined with the OOPs concepts, systemverilog randomization is more robust, easy to code and future proof
class cons; rand bit [7:0]array1[10]; constraint y{foreach(array1[i]) array1[i]%3==0 && array1[i] inside {[1:100]};} constraint z{unique{array1};} endclass cons c; module test; initial begin c=new; assert(c.randomize); $display("%0p",c.array1); end endmodule
class cons; rand int a[10]; real b[10]; constraint x{foreach(a[i]) a[i] inside {[990:1000]};} constraint z{foreach(a[i]) foreach(a[j]) if(i!=j) a[i]!=a[j];} function void post_randomize(); foreach(b[i]) b[i]=a[i]/10.0; $display("10 unique numbers between 99 and 100 are:%0p",b); endfunction endclass cons c; module test; initial begin c=new; assert(c.randomize); end endmodule
class cons; rand bit [7:0]a; constraint x{a dist {[0:100]:/70,[101:255]:/30};} function void post_randomize(); $display(a); endfunction endclass cons c; module top; int count; initial begin c=new; repeat(100) begin c.randomize; if(c.a<101) count=count+1; end $display("No of entries less than 100 are %0d",count); $display("No of entries less than 100 are %0d",100-count); end endmodule
class cons; rand int a[]; constraint x{a.size inside {[10:20]};} constraint y{foreach(a[i]) if(i>1) (a[i]+a[i-1]+a[i-2])%2==0;} constraint z{foreach(a[i]) a[i] inside {[0:10]};} function void post_randomize; $display("array is %0p",a); endfunction endclass cons c; module top; initial begin c=new; c.randomize; end endmodule
class cons; rand bit [8:0]a; rand bit [8:0]b; constraint not_equal{a!=b;} constraint count{$countones(a)==5;} function void post_randomize; $display("a is %0b\n b is %0b",a,b); endfunction endclass cons c; module top; initial begin c=new; c.randomize; end endmodule
class cons; rand bit [3:0]a; int que[$]; constraint x{!(a inside {que});} function void post_randomize; que.push_front(a); if(que.size==6) que.pop_back; $display("a is %0d",a); endfunction endclass cons c; module top; initial begin c=new; repeat(8) c.randomize; end endmodule
class cons; rand bit [1:0] a; int que[$]; constraint x{!(a inside {que});} function void post_randomize(); que.push_front(a); if(que.size==2**$size(a)) begin que={}; end $display("a is %0d",a); endfunction endclass cons c; module top; initial begin c=new; repeat(8) c.randomize; end endmodule
class ex; rand bit [31:0] rand_var; constraint odd_num { $countones( rand_var ) & 1'b1 == 1; } constraint limit { rand_var < 100; } endclass module top; ex R; initial begin R = new(); repeat( 10 ) begin R.randomize(); $display( "R.rand_var : %d ( %b )", R.rand_var, R.rand_var ); end end endmodule
class sv_class; rand int rand_var; constraint odd_num_lt_1000 { rand_var % 2 == 1; rand_var < 1000; } endclass module top; sv_class sv; initial begin sv = new; repeat( 10 ) begin sv.randomize(); $display( "rand_var : %h ( %d ) ( %b )", sv.rand_var, sv.rand_var, sv.rand_var ); end end endmodule
class decimal_palindrome; rand bit [31:0] rand_num; rand int palin_arr[]; rand int palin_arr_pow_10s[]; constraint digit_count { palin_arr.size() <= 9; // 32b can generate a maximum of 9 digit decimal palin_arr.size() > 0; palin_arr_pow_10s.size() == palin_arr.size(); } constraint array_val { foreach( palin_arr[i] ) { palin_arr[i] < 10 && palin_arr[i] >= 0; if( i == 0 ) { palin_arr[i] != 0; } } } constraint palindrome_condition { foreach( palin_arr[i] ) { if( !( ( 1 == palin_arr.size()%2 ) && ( palin_arr.size()/2 == i ) ) ) { palin_arr[i] == palin_arr[palin_arr.size()-i-1]; } } } constraint load_palin_arr_pow_10s_with_10s_powers { foreach( palin_arr_pow_10s[i] ) { if( i == 0 ) { palin_arr_pow_10s[i] == 1; } else { palin_arr_pow_10s[i] == palin_arr_pow_10s[i-1]*10; } } } constraint convert_array_to_num { foreach( palin_arr[i] ) { (rand_num/palin_arr_pow_10s[i])%10 == palin_arr[i]; } rand_num/(palin_arr_pow_10s[palin_arr_pow_10s.size()-1]*10) == 0; } endclass module top; decimal_palindrome p; initial begin p = new; repeat( 10 ) begin p.randomize(); //$display( "Array : %p", p.palin_arr ); $display( "Val : %d", p.rand_num ); end end endmodule
class sv_class; rand int rand_var; rand int fib_arr[]; constraint populate_fib_arr { fib_arr.size != 0; fib_arr.size < 1000; // Issues with leaving the upper boundary unconstrained foreach( fib_arr[i] ) { if( i == 0 || i == 1 ) { fib_arr[i] == 1; } else { fib_arr[i] == fib_arr[i-1] + fib_arr[i-2]; } } } constraint rand_var_value { rand_var inside {fib_arr}; } endclass module top; sv_class sv; initial begin sv = new; repeat( 10 ) begin sv.randomize(); $display( "rand_var : %h ( %d ) ( %b )", sv.rand_var, sv.rand_var, sv.rand_var ); end end endmodule
class sv_class; rand int rand_var; constraint odd_num_lt_1000 { rand_var % 2 == 1; rand_var < 1000; } endclass module top; sv_class sv; initial begin sv = new; repeat( 10 ) begin sv.randomize(); $display( "rand_var : %h ( %d ) ( %b )", sv.rand_var, sv.rand_var, sv.rand_var ); end end endmodule
class practice; rand bit[31:0]a; bit[2:0] pattern=3'b110; rand int b[]; constraint b_size { b.size ==3; //for 3 counts } constraint b_cond_1 { foreach(b[i]) { b[i] > 0; b[i] <30; } } constraint b_cond_2{ //condition for the indices not to overlap foreach(b[i]) { foreach(b[j]) { if(i!=j) { unsigned'(b[i]-b[j]) >='d3 ; } } } } constraint a_set { foreach(a[i]) { if(i inside {b}) { a[i+:3] == pattern; } else { (i<29)->a[i+:3] != pattern ; } } } endclass module test; practice p; initial begin p=new(); assert(p.randomize); $display("%b :var:%p",p.a,p.b); end endmodule
class ex; rand bit [31:0] rand_var; constraint x11 { rand_var % 11 == 0; } endclass module top; ex R; initial begin R = new(); repeat( 10 ) begin R.randomize(); $display( "R.rand_var : %d ( %b )", R.rand_var, R.rand_var ); end end endmodule
class ex; rand bit [31:0] rand_var; constraint power_of_2 { $countones( rand_var ) == 1; } endclass module top; ex R; initial begin R = new(); repeat( 10 ) begin R.randomize(); $display( "R.rand_var : %d ( %b )", R.rand_var, R.rand_var ); end end endmodule
class ex; rand bit [31:0] rand_var; rand int digits; rand bit [3:0] ele[]; constraint solve_bf { solve digits before ele; } constraint digit { ele.size == digits; digits <= 32/4; digits > 0; } constraint hex_palindrome { soft rand_var == 32'd0; foreach( ele[i] ) { if( i < ele.size/2 ) { ele[i] == ele[ele.size-i-1]; } } ele[0] != 0; } function void post_randomize(); foreach( ele[i] ) begin rand_var[4*i+:4] = ele[i]; end endfunction endclass module top; ex R; initial begin R = new(); repeat( 10 ) begin R.randomize(); $display( "R.rand_var : %d ( %h )", R.rand_var, R.rand_var ); end end endmodule
class ex; rand bit [31:0] rand_var; rand int digits []; constraint digit_count { digits.size > 0 && digits.size < 11; } constraint sum_17 { foreach( digits[i] ) { digits[i] >= 0 && digits[i] < 10; } digits.sum == 17; } function void post_randomize(); rand_var = 0; foreach( digits[i] ) begin rand_var += (10**i)*digits[i]; end endfunction endclass module top; ex R; initial begin R = new(); repeat( 10 ) begin R.randomize(); $display( "R.rand_var : %d ( %h ) ( digits : %p )", R.rand_var, R.rand_var, R.digits ); end end endmodule
class ex; rand bit [31:0] rand_var; rand int bit_count; constraint bit_cnt_solve { solve bit_count before rand_var; } constraint bit_cnt { bit_count < 32; bit_count > 0; bit_count % 3 == 0; } constraint bit_msb_x3 { foreach( rand_var[i] ) { if( i < bit_count ) { rand_var[32-1-i] == 1'b1; } else if( i == bit_count ) { rand_var[32-1-i] == 1'b0; } } } endclass module top; ex R; initial begin R = new(); repeat( 10 ) begin R.randomize(); $display( "R.rand_var : %b ( %h ) ( bit_count : %d )", R.rand_var, R.rand_var, R.bit_count ); end end endmodule
// Important Note : This code is only solvable efficiently by Xcelieum & VCS simulators. // On Questasim the solver will fail in many instances but on some instances correct output will be generated. class prime; rand int prime_num; rand bit prime_size[]; constraint prime_check { prime_num % 2 != 0; // Must not be an even number //( prime_num == 2 | prime_num == 3 | ( prime_num > 3 ) ) == 1; // Can generate 2,3 or any number more than 3 foreach( prime_size[i] ){ if( i > 1 ){ i % 2 != 0 -> prime_num % i != 0; // Makes sure no value of i is a divisor of prime_num } } }; constraint a { prime_num < 20000; prime_size.size() == prime_num/2; prime_num > 3; } function void post_randomize(); if( prime_num inside { 1,2,3 } ) begin // Special prime $display( "Special prime generated" ); end else begin for( int i = 2; i <= prime_num/2; i++ ) begin if( prime_num % i == 0 ) begin $display( "Not a prime. Number is %d", prime_num ); $finish; end end end endfunction endclass module top; prime p; initial begin p = new(); repeat( 30 ) begin p.randomize(); $display( "Randomized Prime Number : %0d", p.prime_num ); end end endmodule
class ex; rand bit [31:0] rand_var; rand int num []; rand int digits; constraint num_size { digits < 10; digits > 0; digits[0] == 0; num.size == digits/2; } constraint num_val { foreach( num[i] ) { if( i > 0 ) { num[i] == num[i-1] + 1; } num[i] < 100 && num[i] > 9; } } function void post_randomize(); rand_var = 0; foreach( num[i] ) begin rand_var += ((100**(i))*(num[num.size-1-i])); end endfunction endclass module top; ex R; initial begin R = new(); repeat( 10 ) begin R.randomize(); $display( "R.rand_var : %d ( %h ) ( %p )", R.rand_var, R.rand_var, R.num ); end end endmodule
class ex; rand bit [31:0] rand_var; rand int digits; rand int num []; constraint sol_b { solve digits before num; solve digits before rand_var; solve rand_var before num; } constraint digits_len { digits < 6; digits > 1; num.size == digits; } constraint arm_sum { foreach( num[i] ) { num[i] == ((rand_var/(10**i))%10)**digits; } num.sum == rand_var; } endclass module top; ex R; initial begin R = new(); repeat( 10 ) begin R.randomize(); $display( "R.rand_var : %d ( %h ) ( %p )", R.rand_var, R.rand_var, R.num ); end end endmodule
class ex; rand int rand_arr []; constraint uniq_element { rand_arr.size < 10; foreach( rand_arr[i] ) { rand_arr[i] > 0 && rand_arr[i] < 10000; foreach( rand_arr[j] ) { if( j > i ) { rand_arr[i] != rand_arr[j]; } } } } constraint decending_order { foreach( rand_arr[i] ) { if( i > 0 ) { rand_arr[i-1] > rand_arr[i]; } } } endclass module top; ex R; initial begin R = new(); repeat( 10 ) begin R.randomize(); $display( "R.rand_arr : %p", R.rand_arr ); end end endmodule
class ex; rand bit [31:0] rand_arr []; constraint elements { rand_arr.size < 10; } constraint sum_100 { rand_arr.sum == 100; foreach( rand_arr[i] ) { rand_arr[i] < ( 2**32 - 1 ); rand_arr[i] > 0; } } endclass module top; ex R; initial begin R = new(); repeat( 10 ) begin R.randomize(); $display( "R.rand_arr : %p", R.rand_arr ); end end endmodule
class ex; rand bit [31:0] rand_arr []; constraint elements { rand_arr.size < 10; rand_arr.size > 0; } constraint inc_pow_of_5 { foreach( rand_arr[i] ) { if( i == 0 ) { rand_arr[i] == 1; } else { rand_arr[i] == 5*rand_arr[i-1]; } } } endclass module top; ex R; initial begin R = new(); repeat( 10 ) begin R.randomize(); $display( "R.rand_arr : %p", R.rand_arr ); end end endmodule
class ex; rand bit [31:0] rand_arr []; constraint elements { rand_arr.size < 100; rand_arr.size > 0; } constraint fib { foreach( rand_arr[i] ) { if( i == 0 || i == 1 ) { rand_arr[i] == 1; } else { rand_arr[i] == rand_arr[i-1]+rand_arr[i-2]; } } } endclass module top; ex R; initial begin R = new(); repeat( 10 ) begin R.randomize(); $display( "R.rand_arr : %p", R.rand_arr ); end end endmodule
// Important Note : This code is only solvable efficiently by Xcelieum & VCS simulators. // On Questasim the solver will fail in many instances but on some instances correct output will be generated. class prime_num; rand int prime_num; rand bit prime_size[]; constraint prime_check { prime_num % 2 != 0; // Must not be an even number //( prime_num == 2 | prime_num == 3 | ( prime_num > 3 ) ) == 1; // Can generate 2,3 or any number more than 3 foreach( prime_size[i] ){ if( i > 1 ){ i % 2 != 0 -> prime_num % i != 0; // Makes sure no value of i is a divisor of prime_num } } }; constraint a { prime_num < 2000; // For faster solver solution prime_size.size() == prime_num/2; prime_num > 3; } function void post_randomize(); if( prime_num inside { 1,2,3 } ) begin // Special prime $display( "Special prime generated" ); end else begin for( int i = 2; i <= prime_num/2; i++ ) begin if( prime_num % i == 0 ) begin $display( "Not a prime. Number is %d", prime_num ); $finish; end end end endfunction endclass class ex; rand bit [31:0] rand_arr []; constraint elements { rand_arr.size < 10; rand_arr.size > 0; } function void post_randomize(); prime_num p; p = new(); foreach( rand_arr[i] ) begin p.randomize(); rand_arr[i] = p.prime_num; end endfunction endclass module top; ex R; initial begin R = new(); repeat( 10 ) begin R.randomize(); $display( "R.rand_arr : %p", R.rand_arr ); end end endmodule
class ex; rand bit [31:0] rand_arr []; rand int arr_size; constraint soft_default { rand_arr.size == 1; soft arr_size < 100; // Modifiable arr_size > 0; } function x3_x_1_next_lfsr_val( int start_seed ); // x3+x+1 bit [2:0] ini; bit [2:0] ini_temp; ini = start_seed; ini_temp[2] = ini[2]; ini_temp[1] = ini[1]; ini_temp[0] = ini[0]; ini[2] = ini_temp[0]; ini[1] = ini_temp[2]; ini[0] = ini_temp[1] ^ ini_temp[0]; return ini; endfunction function void post_randomize(); // Generate a sequence of x3+x+1 based on rand_arr[0]'s value rand_arr = new[arr_size](rand_arr); $display( "Initial Value : %p", rand_arr ); foreach( rand_arr[i] ) begin if( i > 0 ) begin rand_arr[i] = x3_x_1_next_lfsr_val( rand_arr[i-1] ); end end endfunction endclass module top; ex R; initial begin R = new(); repeat( 10 ) begin R.randomize(); $display( "R.rand_arr : %p", R.rand_arr ); end end endmodule
class ex; rand bit rand_arr [8][8]; // Horizontal, Vertical rand bit [7:0] h [8]; rand bit [7:0] v [8]; constraint board_conditions { foreach( h[i] ) { $countones(h[i]) == 1; $countones(v[i]) == 1; } foreach( v[i] ) { foreach( v[j] ) { v[j][i] == h[i][j]; rand_arr[i][j] == h[i][j]; } } } function void print_board(); int t; t = 0; foreach( rand_arr[i] ) begin foreach( rand_arr[j] ) begin if( t != i ) begin $display( "" ); t = i; end $write( "%1d ", rand_arr[i][j] ); end end $display( "\n" ); endfunction endclass module top; ex R; initial begin R = new(); repeat( 10 ) begin R.randomize(); R.print_board(); end end endmodule
class ex; rand bit [31:0] rand_arr []; rand int arr_size; constraint soft_default { rand_arr.size == 1; soft arr_size < 100; // Modifiable arr_size > 0; } function x3_x_1_next_lfsr_val( int start_seed ); // x3+x+1 bit [2:0] ini; bit [2:0] ini_temp; ini = start_seed; ini_temp[2] = ini[2]; ini_temp[1] = ini[1]; ini_temp[0] = ini[0]; ini[2] = ini_temp[0]; ini[1] = ini_temp[2]; ini[0] = ini_temp[1] ^ ini_temp[0]; return ini; endfunction function void post_randomize(); // Generate a sequence of x3+x+1 based on rand_arr[0]'s value rand_arr = new[arr_size](rand_arr); $display( "Initial Value : %p", rand_arr ); foreach( rand_arr[i] ) begin if( i > 0 ) begin rand_arr[i] = x3_x_1_next_lfsr_val( rand_arr[i-1] ); end end endfunction endclass module top; ex R; initial begin R = new(); repeat( 10 ) begin R.randomize(); $display( "R.rand_arr : %p", R.rand_arr ); end end endmodule
class cons; rand int throw_value; int throw_seq[$]; constraint x{ if(throw_seq.size > 0) throw_seq.sum + throw_value < 101 ; } constraint z{throw_value inside {[1:6]} ;} function void post_randomize; throw_seq.push_back(throw_value); $display("throw_value is %0d ,Position is %0d",throw_value,throw_seq.sum()); endfunction endclass cons c; module top; initial begin c = new; forever begin c.randomize; if(c.throw_seq.sum == 100) break; end end endmodule
class practice; rand bit[31:0] a; rand int count[32]; rand int b; constraint set_count { foreach(count[i]) { count[i]==a[i]; } } constraint set_b { count.sum()%2==0 ; b == count.sum() ; } endclass module test; practice p; initial begin p=new(); assert(p.randomize); $display("a:%0d b:%0d count:%p",p.a,p.b,p.count); //$display("a=%0d div=%0d",p.); end endmodule
class ran; rand int base_addr[]; rand int offset[]; /* Example: ---------- -> 1024KB ( 2^20 -> 20bits ) | | | | | | | | | | | | -> offset[n+1]+base_addr[n+1] | | -> base_addr[n+1] -> ( SEGMENT N+1 ) | | | | | | | | | | -> offset[n]+base_addr[n] | | | | | | -> base_addr[n] -> ( SEGMENT N ) . . . . . . | | ---------- -> 0B */ constraint segments { base_addr.size == 8; offset.size == 8; } constraint addr { foreach( base_addr[i] ) { if( i > 0 ) { base_addr[i] >= base_addr[i-1]+offset[i-1]; } base_addr[i] >= 0 && base_addr[i] < 2**20; offset[i] >= 0 && offset[i] < 2**20; } } endclass
class ran; rand int base_addr[]; rand int offset[]; constraint segments { base_addr.size == 8; offset.size == 8; } constraint addr { foreach( base_addr[i] ) { base_addr[i][1:0] == 2'd0; // All generated addresses are 4Byte aligned offset[i] >= 16; // Minimum of 16Bytes if( i > 0 ) { base_addr[i] >= base_addr[i-1]+offset[i-1]; } base_addr[i] >= 0 && base_addr[i] < 2**20; offset[i] >= 0 && offset[i] < 2**20; } } endclass
class cons; rand int a[]; constraint x{a.size==10;} constraint y{foreach(a[i]) if(i%2==0) a[i]==0; else a[i]==1;} function void post_randomize(); $display("Randomized data is %0p",a); endfunction endclass cons c; module top; initial begin c=new(); assert(c.randomize()); end endmodule
class cons; rand int a[]; constraint size{a.size==6;} constraint x{foreach(a[i]) if(i%2==0) a[i]==(i*5)+5; else a[i]==-5*(i+1);} function void post_randomize(); $display("Required pattern is %0p",a); endfunction endclass cons c; module top; initial begin c=new(); assert(c.randomize()); end endmodule
class cons; rand int a; real b; constraint size{a inside {[1350:2570]};} function void post_randomize(); b=a/1000.0; $display("Random number in between 1.35 and 2.57 is %0f",b); endfunction endclass cons c; module top; initial begin c=new(); repeat(10) assert(c.randomize); end endmodule
class cons; rand bit [63:0]a; constraint no_of_ones{$countones(a)==12;} //We can use constraint no_of_ones{$countbits(a,1)==12;} constraint x{foreach(a[i]) if(i>0&&a[i]==1) a[i]!=a[i-1];} function void post_randomize(); $display("Randomized 64 bit variable having 12 ones is:%0b",a); $display("Displaying no of ones in the variable that we randomized is %0d",$countones(a)); endfunction endclass cons c; module test; initial begin c=new; c.randomize; end endmodule
class cons; rand int even[]; rand int odd[]; //function for doing the factorial function int fact(int i); if(i==0) fact=1; else fact=i*fact(i-1); endfunction //constraint constraint size{even.size==5;} //for even numbers factorial constraint even_fact{foreach(even[j]) even[j]==fact(2*(j+1));} //for odd numbers factorial constraint odd_fact{foreach(odd[k]) odd[k]==fact((2*k)+1);} function void post_randomize(); $display("Factorial of 1st five even numbers is %0p",even); //$display("Factorial of 1st five odd numbers is %0p",odd); endfunction endclass cons c; module test; initial begin c=new; c.randomize; end endmodule
class cons; rand int eo[]; constraint size{eo.size inside {[10:20]};} constraint range{foreach(eo[i]) eo[i] inside {[1:100]};} constraint x{foreach(eo[i]) if(i%2==0) eo[i]%2==1; else eo[i]%2==0;} function void post_randomize(); $display("After randomizing data is %0p",eo); endfunction endclass cons c; module test; initial begin c=new; c.randomize; end endmodule