Generate unique elements in an array

In reply to dave_59:

Hi Dave, i have a new question that is related but it is a little different. I haven’t found any solution in the forum so maybe you can help.
What i want is to generate an array with unique ranges. This is typically useful for addressing ranges that are not overlapping. What is the best and efficient way to do that?
In a paper of the DVCon from Mentor i have seen: http://proceedings.dvcon-europe.org/2014/presentations_and_papers/T5_1_paper.pdf

There is the following code:



rand bit [31:0] start_addr;
 rand bit [5:0] length;
 bit [31:0] start_end_addr_hash [bit[31:0]];
 constraint c { //Generate Non-Overlapping address ranges
    if (start_end_addr_hash.num()) {
       foreach (start_end_addr_hash *) {
             if (i >= length ) {
                !(start_addr inside {[i-length+1 : start_end_addr_hash [i]]});
             } else {
                 !(start_addr inside {[0 : start_end_addr_hash [i]]});
             }
       }
    }
  length == 6'h10;
 }
 ...
 start_end_addr_hash [start_addr] = start_addr + length - 1;


Is that the best way? Besides, it is not clear for me where i have to put the code.


 ...
 start_end_addr_hash [start_addr] = start_addr + length - 1;

Is it in post_randomization?

Another option is using only random variables. The advantage is that the user can define the start and length by himself for each non overlapping part ([i]notice that it uses a dynamic array and not only one value for start_address and lengt*h). I think the previous example doesn’t allow you to do that because is all coded in the hash iteratively.
Besides, if you do constraint “length[j]==1” then this code generates a vector with unique values in the start_address. That means, this somehow supersedes the codes above at cost of efficiency and memory.


rand bit [31:0] start_address[]; //notice that it is a dynamic array
rand bit [5:0] length[]; //dynamic array, to specify many different ranges

constraint c { 
start_address.size()==length.size();
if (start_address.size()) {
  foreach (start_address[j])  {//j is the chosen start address  
           // end_address [j] == start_address[j] + length[j] - 1;
    foreach (start_address[i])  {//i is the chosen start address 
       if (i!=j) {
            
            ///Constraint start_address (first byte of the buffer)
         if (start_address [j]  >=  length[i] ) {
           !(start_address[i] inside {[start_address [j] - length[i]+1 : start_address [j]+length[j]-1  ]}) ;
         } else {
           !(start_address[i] inside {[0 : start_address [j]+length[j]-1 ]});
         }
       } //end if i!=j
        
     } //end foreach i
   } //end foreach j
 }  //end if

} //end contraint c

What do you think about the implementations?

Thanks in advance