Search code examples
system-verilogsynopsys-vcs

How to properly declare an N-dimensional queue inline in SystemVerilog?


If I have 2D queue of ints, I would expect to be able to declare it inline like so:

int my_queue[$][$] = {{1, 2}, {3, 4}};

I have also seen

typedef int int_queue[$];
int_queue my_queue[$] = {{1, 2}, {3, 4}};

Instead, when I compile, VCS provides me with an Incompatible Complex Type error:

  Type of source expression is incompatible with type of target expression. 
  Mismatching types cannot be used in assignments, initializations and 
  instantiations. The type of the target is 'int$[$][$]', while the type of 
  the source is 'bit[63:0]'.

Which implies to me that VCS expects the right hand side of the equation to be cast properly. The way around this that I have been using is:

typedef int int_queue[$];
typedef int_queue int_queue_of_queues[$];
int_queue_of_queues my_queue = int_queue_of_queues'{{1, 2}, {3, 4}};

But this adds N extra typedefs and lines for N dimensions, and I would rather do this in one line. If I had a way to cast the right hand side of the declaration without a typedef, then this would be simple, but I don't know if that is possible.


Solution

  • The array concatenation syntax only works on a single dimension. You cannot nest the {}'s because of cases where there is ambiguity between array {} and integral {} concatenation. You need to use array assignment pattern in the outer, or both dimensions. I prefer using assignment patterns for both dimensions making it clearer that these are array elements, not integral concatenations.

    int my_queue[$][$] = '{'{1, 2}, '{3, 4}};
    

    See section 10.10 Unpacked array concatenation in the IEEE 1800-2017 LRM.