cyclic randomization of array in SV
Defining a class variable as randc will result in cyclic randomization, meaning that all the values in a range will be obtained before a new cycle begins and the values will repeat.
But what if we want to randomize an array and obtain a different permutation in each randomization in a cyclic manner?
Spoiler! The code below won't have the work done :
randc int array [array_size] ;
Let's see how it can be done, and to make the example more fun I'll add some constraints:
Here is the code :
领英推荐
class Permutations #(int arr_size = 6, int max_number = 7) ;
? ?const int num_of_perm = calc_num_of_perm(arr_size, max_number) ;
? ? ? ? ?int arr [arr_size] ;
? ?rand? bit [0:arr_size-1][$clog2(max_number)-1 : 0] packed_arr ;
? ? ? ? ?bit [arr_size*$clog2(max_number)-1 : 0] list [$] ;
? ?constraint c_sorted {
? ? ? foreach (packed_arr[i])
? ? ? ? ?if (i > 0)
? ? ? ? ? ? packed_arr[i] > packed_arr[i-1] ;
? ?}
? ?constraint c_range {
? ? ? foreach (packed_arr[i])
? ? ? ? ?packed_arr[i] inside {[1:max_number]} ;
? ?}
? ?constraint c_not_in_list {
? ? ? !(packed_arr inside {list}) ;
? ?}
//---Functions---
? ?function void post_randomize() ;
? ? ? if (list.size == num_of_perm - 1)
? ? ? ? ?list.delete() ;
? ? ? else
? ? ? ? ?list.push_back(packed_arr) ;
? ? ? foreach (packed_arr[i])
? ? ? ? ?arr[i] = int'(packed_arr[i]) ;
? ?endfunction
//---
? ?function int factorial (int arr_size) ;
? ? ? if (arr_size == 1)
? ? ? ? ?return 1 ;
? ? ? else?
? ? ? ? ?return arr_size * factorial(arr_size-1) ;
? ?endfunction
//---
? ?function int calc_num_of_perm (int arr_size, int max_number) ;
? ? ? int result = 1;
? ? ? for (int i = 0; i < arr_size; i++)
? ? ? ? ?result *= (max_number - i) ;
? ? ? result = result / factorial(arr_size) ;
? ? ? return result ;
? ?endfunction
endclass
Beware! making arr also rand and adding the next constraint may look harmless but will result in much greater solving time.
foreach (arr[i])
arr[i] == packed_arr[i] ;
Here is a simple testbench to check the results:
module perm_tb ;
? ?Permutations my_perm ;
? ?initial begin
? ? ? my_perm = new() ;
? ? ? for (int i=0; i<10; i++) begin
? ? ? ? ?void'(my_perm.randomize()) ;
? ? ? ? ?$display("%p", my_perm.arr) ;
? ? ? end
? ?end
endmodule
And the results. We can easily see that the first 7 arrays are unique, and then the cycle restarts.
'{1, 2, 3, 4, 6, 7}
'{1, 2, 4, 5, 6, 7}
'{1, 2, 3, 4, 5, 7}
'{1, 2, 3, 4, 5, 6}
'{1, 3, 4, 5, 6, 7}
'{1, 2, 3, 5, 6, 7}
'{2, 3, 4, 5, 6, 7}
'{1, 2, 4, 5, 6, 7}
'{2, 3, 4, 5, 6, 7}
'{1, 2, 3, 4, 5, 6}
Can you think of other ways to have the job done? What do you think about my solution?