Search code examples
arrayssystem-verilogsynthesis

Are SystemVerilog packed arrays row or column major for literal assignment?


I want to use multi-dimensional arrays for some SystemVerilog code that I intend to synthesize. My understanding is that packed arrays are essentially a big vector that can be indexed slice or element-wise in the code.

So, is the following allowed?

logic [4:0] [2][2] my_array;

assign my_array = '{ 4'd1, 4'd2, 4'd3, 4'd4 };

And if it is, is the literal interpreted as row or column major? I know I can manually separate the literals into a hierarchy that matches the 2x2 array, but these modules will be instantiated in auto-generated code from a high level language. I'd like to orient my arrays so it matches the column major orientation of the high level language.


Solution

  • There are a couple of problems with your code. The use of the single number range [2] is not allowed and the 1800-2023 LRM will be more explicit about why this is not allowed. Some tools have allowed it but implemented the range in the reverse endianness of what most people expect for packed ranges.

    If you wanted a 3-dimensional packed array of 2 rows by 3 columns by 5 bits, you would use

    logic [0:1][0:2][4:0] my_array;
    

    And finally, there is no type safety with packed arrays. When writing a literal concatenation, if you get the number of elements wrong or have the wrong size of an element, you get silent truncation or padding of bits. If you had the following

    logic [0:1][0:2][4:0] my_array;
    
    my_array = {4'd1,4'd2,4'd3,  4'd4,4'd5,4'd6};
    
    # my_array is '{'{5'h00, 5'h01, 5'h04}, '{5'h0d, 5'h02, 5'h16}}
    

    You need to write it as

    my_array = {5'd1,5'd2,5'd3,  5'd4,5'd5,5'd6};