1

Is it possible to constraint an entire array in SystemVerilog to have the same value as another array?

I tried this:

class some_class;
   rand bit array1[10][10];
   rand bit array2[10][10];

   constraint arrays_c {
      array1 == array2;
   }
enclass

This isn't allowed in 2 of the Big3 simulators I've tried. One says it isn't currently supported and the other refers me to the constraint BNF, complaining that it isn't a valid integral expression.

Is there any other way of doing this, aside from setting a bit foreach constraint? What I ultimately want is to return an array from a function and use it to constrain another array that is a class field.

Tudor Timi
  • 7,453
  • 1
  • 24
  • 53
  • On packed arrays it works, but there are restrictions on the types I can use there. These restrictions apparently also vary from vendor to vendor. – Tudor Timi May 19 '14 at 08:13
  • you may try to only random array2 and then use post random to copy it to array1 – enchanter May 19 '14 at 09:09
  • While this would work, it's not compatible with what I want. I ultimately want to have a chain of constraints on arrays that lead to a particular result (something like "if array3 is this, what is array1 supposed to be? (given that I just know relations between array1 and array2 and array2 and array3". By assigning in post_randomize() I've effectively removed any information from the constraint solver about this relationship. – Tudor Timi May 19 '14 at 09:21

1 Answers1

2

Use a foreach, see IEEE Std 1800-2012 § 18.5.8.1 foreach iterative constraints

constraint arrays_c {
  foreach(array1[i,j]) {
    array1[i][j] == array2[i][j];
  }
}

If you want a copy of a random array, the better approach is to assign the copy in the post_randomize function. It is less CPU incentive.

class some_class;
   rand bit array1[10][10];
   bit array2[10][10];

   function void post_randomize();
     array2 = array1;
   endfuction : post_randomize
enclass

If foreach in a constraint block and post_randomize calculations are not viable solutions, then use is packed arrays.

class some_class;
   rand bit [9:0][9:0] array1; // double packed
   rand bit [9:0][9:0] array2;

   constraint arrays_c {
    array1 == array2;
   }
enclass

Or use pack arrays and bit-stream assignments to make the end result unpacked

class some_class;
   bit array1[10][10];
   bit array2[10][10];
   rand bit [$bits(array1)-1:0] flat_array1,flat_array2;

   constraint arrays_c {
    flat_array1 == flat_array2;
   }

   function void post_randomize();
     {>>{array1}} = flat_array1; // bit-stream assignment
     {>>{array2}} = flat_array2;
   endfuction : post_randomize
enclass
Greg
  • 18,111
  • 5
  • 46
  • 68
  • Be careful about foreach, it will unroll the constraints and you will see performance issue and quickly run out of memory when your array getting bigger. – enchanter May 20 '14 at 01:35
  • Thanks @Greg, but as I said I can't to use foreach, as the array on the right hand side will be a field of the class, but the return value of a function and I can't slice that. – Tudor Timi May 20 '14 at 21:14
  • @Tudor, then use packed arrays. I added two examples to my answer. – Greg May 21 '14 at 17:34
  • Cool idea @Greg. I'll look more into the stream operator. – Tudor Timi May 21 '14 at 18:19