Randc in an variable within an array of objects

I tried to generate an array with different values each items (random value, not the index)

my array declared as a randc, but it doesn’t work for me:

class fs_array;
  randc int unsigned array1[6];
  
  constraint c{
    foreach(array1[i])
      array1[i] < 7;
  }
  
  function void display();
    $display("");
    $display("array1 = %p",array1);
    $display("");
  endfunction
endclass

module fixedsize_array_randomization;
  fs_array pkt;

  initial begin
    pkt = new();
    pkt.randomize();
    pkt.display();   
  end
  
endmodule

simulator outputs:

array1 = '{'h2, 'h6, 'h0, 'h6, 'h0, 'h2}

In reply to AL_verif:

When we have an unpacked array as randc , its not the values in the whole array that would be unique . Rather the value for a particular index would be unique till all iterations are reached .

array1[0] is 'h2 , so if you randomize pkt() you would see unique values ( non 'h2 ) for index 0 for next 6 iterations ( i.e till you call randomize() 7 times ) .

During 8th call to randomize() is the earliest you would see array1[0] as 'h2 again !!

In reply to ABD_91:

That answer is not correct.

First of all, randc only works multiple calls to randomize() on the same object; It does not have any effect on the first or only call to randomize().

And second. randc looks at the total solution space for that variable. It just needs to produce a different solution for call to randomize(). So the following solutions meet that criteria

array1 = '{'h0, 'h0, 'h0, 'h0, 'h0, 'h0}
array1 = '{'h0, 'h0, 'h0, 'h0, 'h0, 'h1}
array1 = '{'h0, 'h0, 'h0, 'h0, 'h1, 'h0}
array1 = '{'h0, 'h0, 'h0, 'h0, 'h0, 'h2}
... ~50,000 more possible solutions

If you are just looking for each array element to be unique, use the unique constraint and not randc.

constraint c { unique {array1}; }

In reply to dave_59:

Hi Dave ,

While answering I had assumed same object is being randomized() repeatedly .

Also it was based on previous observations across simulators . Since I randomize it 10 times I never used to see the other combination of output

I tried changing code to ::


  int unsigned array2[6];
  int count ;
  constraint VAL {    
                     foreach(array1[i])
		     if ( count < 4 ) 
	            array1[i] == array2[i] ;

                 }
 
  
  function void pre_randomize();
     if ( count == 0 ) 
	 array2 = '{ 0 , 0  , 0 , 0 , 0 , 0} ;
     if ( count == 1 ) 
	 array2 = '{ 0 , 0  , 0 , 0 , 0 , 1} ;
     if ( count == 2 ) 
	 array2 = '{  0 , 0  , 0 , 0 , 1 , 0} ;
     if ( count == 3 ) 
	 array2 = '{ 0 , 0  , 0 , 0 , 0 , 2 } ;

  endfunction

  function void post_randomize();
     count ++ ;
  endfunction


I see same output as you explained is also possible . ( Had my theory been true the simulators would have given randomization failure )

Thanks for the info Dave ! .

In reply to dave_59:

Thank you all !
I missed the ‘unique’ constraint.
I added it and this is working well.

Thanks!

In reply to dave_59:

In reply to ABD_91:
That answer is not correct.
First of all, randc only works multiple calls to randomize() on the same object; It does not have any effect on the first or only call to randomize().
And second. randc looks at the total solution space for that variable. It just needs to produce a

different

solution for call to randomize(). So the following solutions meet that criteria

array1 = '{'h0, 'h0, 'h0, 'h0, 'h0, 'h0}
array1 = '{'h0, 'h0, 'h0, 'h0, 'h0, 'h1}
array1 = '{'h0, 'h0, 'h0, 'h0, 'h1, 'h0}
array1 = '{'h0, 'h0, 'h0, 'h0, 'h0, 'h2}
... ~50,000 more possible solutions

If you are just looking for each array element to be unique, use the unique constraint and not randc.

constraint c { unique {array1}; }

Hi Dave, please see the following example:

class cyclic_arr ;
   randc int arr [2] ;
   constraint c_range {
      foreach (arr[i])
         arr[i] inside {[1:3]} ;
   }
   constraint c_sorted {
      foreach (arr[i])
         if (i>0)
            arr [i] > arr[i-1] ;
   }
endclass
module my_tb ;
   
   cyclic_arr my_cyclic_arr ;

   initial begin
      my_cyclic_arr = new() ;
      for (int i=0; i<10; i++) begin
         void'(my_cyclic_arr.randomize()) ;
         $display("%p", my_cyclic_arr.arr) ;
      end
   end
endmodule

The possible solutions are only these three:
{'{1,2}, '{1,3}, '{2,3}}
So according to what you have written i would expect the first three runs of the loop to get all these results, but the results are:

'{1, 3}
'{2, 3}
'{2, 3}
'{1, 2}
'{2, 3}
'{1, 2}
'{2, 3}
'{1, 2}
'{2, 3}
'{1, 2}

Have any idea why?

THanks,
Mihael

In reply to Mihaelf:

My simulator reports the following error:
randomize() failed due to conflicts between the following constraints:

cyclic_array.sv(5): c_range { (arr[1] inside { [1:3] }); }

cyclic_array.sv(10): c_sorted { if ((1 > 0)) {(arr[1] > arr[(1 - 1)]);} }

I changed to last constraint to

   constraint c_sorted {
      foreach (arr[i])
         if (i>0)
            arr [i] != arr[i-1] ;
   }

The simulation output is

'{3, 1}

'{1, 3}

'{2, 1}

'{2, 3}

'{3, 1}

'{1, 3}

'{3, 1}

'{1, 3}

'{2, 1}

'{1, 3}

In reply to Mihaelf:

The LRM says arrays declared randc are treated as if their member elements are each rand or randc.

But it appears that handling randc variables with constraints containing dependencies has some issues. If you treat one of the randc variables as a state variable, you effectively have a new constraint on the the remaining randc variables, and that can break the cyclic nature of the randc variable.

In reply to chr_sue:

I know, but the last constraint was intentionally done with “<”, but even now it is not cyclic

In reply to dave_59:

In reply to Mihaelf:
The LRM says arrays declared randc are treated as if their member elements are each rand or randc.
But it appears that handling randc variables with constraints containing dependencies has some issues. If you treat one of the randc variables as a state variable, you effectively have a new constraint on the the remaining randc variables, and that can break the cyclic nature of the randc variable.

So, practically i can not use randc to get unique and cyclic array permutations, if i want to apply extra constraints on array members. Correct?
Thanks!

In reply to Mihaelf:

You can do this as a packed array

class cyclic_arr ;
  randc bit [0:1][3:0] arr ;
   constraint c_range {
      foreach (arr[i])
         arr[i] inside {[1:3]} ;
   }
   constraint c_sorted {
      foreach (arr[i])
         if (i>0)
            arr [i] > arr[i-1] ;
   }
endclass

module my_tb ;
 
   cyclic_arr my_cyclic_arr ;
 
   initial begin
      my_cyclic_arr = new() ;
      for (int i=0; i<10; i++) begin
         void'(my_cyclic_arr.randomize()) ;
        $display("%h", my_cyclic_arr.arr) ;
      end
   end
endmodule

In reply to dave_59:

In reply to Mihaelf:
You can do this as a packed array

class cyclic_arr ;
randc bit [0:1][3:0] arr ;
constraint c_range {
foreach (arr[i])
arr[i] inside {[1:3]} ;
}
constraint c_sorted {
foreach (arr[i])
if (i>0)
arr [i] > arr[i-1] ;
}
endclass
module my_tb ;
cyclic_arr my_cyclic_arr ;
initial begin
my_cyclic_arr = new() ;
for (int i=0; i<10; i++) begin
void'(my_cyclic_arr.randomize()) ;
$display("%h", my_cyclic_arr.arr) ;
end
end
endmodule

The problem with this solution, is that randc variable is limited to 32 bit. so a larger array, with bigger values’ range won’t work.
I’ll post my solution later which i think should work.