Generate unique elements in an array

In reply to ayehia:

Thanks for your detailed answer. I agree with you. For long vectors your last solution has much better performance. Thanks for the insight in the constraint solver performance.

I have also noticed that if we would have been talking about a transaction item class, then the user can also create random variables and a flag (e.g. fullrandom_or_definedbyuser) so that he can assign their user-values in the post randomization phase. In that way, the user can decide if he want to find a new solution (using your last code) or test a previous solution defined (hardcoded) in the explicit part of the item randomization.

For example:


class c;
  rand bit [31:0] start_addr[];
  rand bit [5:0] length[];//size of 
  rand bit user_define_all_rand_members=0;
  bit [31:0] start_end_addr_hash [bit[31:0]];
  constraint c {
     length.size()==start_addr.size();
     soft user_define_all_rand_members==0; 
  } //end contraint c
endclass
 
...
c c1 = new;
... 
repeat(number_of_blocks2generate) begin
  forever begin
     duplicate = 0;
     assert(c1.randomize( ) with {
	           start_addr.size()==2;
	           user_define_all_rand_members==1;
	           start_addr = { 32'hFFFF, 32'h0000 };
	     } );//try to add a block of 2 ranges, you can define more
     //Start check of the random value
     foreach (c1.start_end_addr_hash [i]) begin
        foreach (c1.start_addr [j]) begin
            if ((c1.start_addr[j] <= c1.start_end_addr_hash [i]) && ((c1.start_addr[j] + c1.length[j] -1) >=i )) begin
                 duplicate = 1;
	         if (user_define_all_rand_members==1) begin
                    $fatal (0, "Randomization defined by user failed")   
                 end
                 break;
            end
            //ADD A NEW RANGE-ELEMENT START->END ADDRESS TO THE ASSOCIATIVE ARRAY
            if (!duplicate) begin
               c1.start_end_addr_hash [c1.start_addr[j]] = c1.start_addr[j] + c1.length[j] - 1;
            end
        end
        if (!duplicate) break;
    end//end for associative array
  end//end forever begin
end//end repeat number of blocks to add to the associative array

With this version, the user can still defines/direct the randomization with several ranges in one shot (using the with clause). These “with” constraints are checked by the forever loop without using the constraint solver, improving the performance.