Electronic – Instantiating multidimensional array in system verilog


I want to create an array in systemverilog which has n entries of m bits.

logic [n-1:0] arr [m-1:0]; (a)

Is this the right way to do it? What if I change the order of placement of the range?

Eg. logic arr [n-1:0] [m-1:0]; (b)

Does it represent the same array as (a)?

I also want to create an array of state machines having n entries each entry representing
a a state out of 4 states.

typedef enum logic [n-1:0][1:0]{S0,S1,S2,S3} statetype;
statetype state,nextstate;

Is the above correct way to do it? If it is, how exactly I will access the elements
of this array.

Best Answer

First off, it is a common practice that parameters are upper case. When reading code this helps identify constants from variables. For arrays, refer to IEEE Std 1800-2012 § 7.4 Packed and unpacked arrays.

  • Packed means all the bits can be accessed at once or sliced
  • Unpacked means each index must be individually selected.

The following have the same dimensions:

  • logic [N-1:0] arr_up [M-1:0]; is M unpacked arrays, each with N packed bits
  • logic arr_uu [M-1:0] [N-1:0]; is M unpacked arrays, each with N unpacked single bits arrays
  • logic [M-1:0] [N-1:0] arr_pp; is M-by-N packed array, a slice of N-bits can be read out of the M index

Unpacked arrays can be initialized with a single digit: logic [N-1:0] arr_up [M]; is equivalent to logic [N-1:0] arr_up [0:M-1];. Do note that the [M] is [0:M-1] not [M-1:0].

The differences is in the access. All can access a single bit, but only packed bits can access a slice.

arr_up[M-2] = {{N{1'b0}}}; // legal
arr_uu[M-2] = {{N{1'b0}}}; // illegal, assigning packed to unpacked
arr_pp[M-2] = {{N{1'b0}}}; //legal`

arr_up[M-1:M-4] = {{3*N{1'b1}}}; // illegal, unpacked cannot use sliced array
arr_uu[M-1:M-4] = {{3*N{1'b1}}}; // illegal, unpacked cannot use sliced array
arr_pp[M-1:M-4] = {{3*N{1'b1}}}; // legal

arr_up[M-2][N-5] = 1'b0; // legal
arr_uu[M-2][N-5] = 1'b0; // legal
arr_pp[M-2][N-5] = 1'b0; // legal

arr_up[M-2][N-5:4] = {{N-9{1'b1}}}; // legal
arr_uu[M-2][N-5:4] = {{N-9{1'b1}}}; // illegal, unpacked cannot use sliced array
arr_pp[M-2][N-5:4] = {{N-9{1'b1}}}; // legal

If the simulator is only accessing a single bit or index, unpacked arrays will give better performance. This is because packed arrays are accessed as a whole even if only one bit is being used. There is a balance between the simulators lookup overhead and number of lookup operations. Generally 2-D arrays are unpacked arrays of packed arrays. Adding dimensions is normal on the unpacked side. bytes, integers, words, and data buses are packed.

With typedef enum logic [N-1:0][1:0]{S0,S1,S2,S3} statetype;, be aware this is creating the definition of the state type. It is create a 2*N-bit array but only allows 4 values.

For an array of 4-state state machines, I would recommend:

typedef enum logic [1:0]{S0,S1,S2,S3} state_et;
state_et state[N], nextstate[N];
Related Topic