Verilog and SystemVerilog Arrays: Packed and Unpacked

In this tutorial, we'll explore the difference between packed and unpacked arrays in Verilog and SystemVerilog. Packed arrays are dimensions that appear before the variable name and can have multiple dimensions, while unpacked arrays can be fixed-size arrays, dynamic arrays, associative arrays, or queues.

Packed Arrays in Verilog and SystemVerilog

Packed arrays are contiguous sets of bits, primarily used for vector operations and treated as a single vector. They are made of single-bit data types (bit, logic, reg), enumerators, or other packed arrays/structures.

Examples of Packed Arrays

Here are some examples of packed arrays:

bit   [7:0]      data;    // 8-bit packed array
logic [3:0][7:0] matrix;  // 4x8-bit packed array

typedef enum bit [1:0] {
  IDLE,
  READ,
  WRITE
} state_t;
state_t [3:0] state_array; // 4-element packed array of state_t

Unpacked Arrays in Verilog and SystemVerilog

Unpacked arrays can be made of any data type and can be represented in various ways:

  • Fixed-size arrays, represented by an address range (e.g., array[1:100]) or similar to C-style arrays (e.g., array[Size])
  • Dynamic arrays
  • Associative arrays
  • Queues

Example of Unpacked Array

int array[0:7][0:31]; // This is equivalent to int array[8][32]

Operations on Verilog and SystemVerilog Arrays

These operations can be performed on all types of arrays, including both packed and unpacked arrays:

  • Reading and writing the entire array: arrayA = arrayB
  • Reading and writing an element of the array: arrayA[i] = arrayB[i]. If an out-of-bounds index is accessed, the default value of the data type is read (e.g., X for a 4-state array)
  • Reading and writing a slice of the array: arrayA[i:j] = arrayB[i:j]. A slice of a packed array is a packed array, while a slice of an unpacked array is an unpacked array
  • Reading and writing a variable slice of the array: arrayA[x+:c] = arrayB[y+:c]. The value of c must be constant
  • Equality operations on the array or slice of the array: arrayA == arrayB, arrayA[i:j] != arrayB[i:j]

Multi-Dimensional Arrays in Verilog and SystemVerilog

Multi-dimensional arrays can be a combination of both packed and unpacked arrays. For example:

bit [3:0][7:0] foo [8][24];

To access an element in the multi-dimensional array, follow the order of unpacked dimensions (right to the variable name) then packed dimensions (left to the variable name), from left to right:

foo[7][23][3][7]; // Accesses the element in the following order:
                  // [8] -> [24] -> [3:0] -> [7:0]

Both packed and unpacked arrays can be used with typedef.

Conclusion

In summary, packed and unpacked arrays are essential components in Verilog and SystemVerilog for effective hardware design and verification. Packed arrays are best suited for contiguous bits and vector operations, while unpacked arrays provide more flexibility in terms of data types and structure. Understanding their differences and how to use them efficiently will enable you to create better and more maintainable code in your projects.