2
\$\begingroup\$

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.

\$\endgroup\$
8
\$\begingroup\$

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];
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.