When you declare an array, there are two types of dimensions: packed and unpacked.
For example, imagine you have a variable that is 12 bits wide:
bit[11:0] avar;
Now, say that you want to treat these 12 bits as 3 groups of 4 bits:
bit[2:0][3:0] a_packed_array;
The array index that is next to the type is called the “packed” dimensions. In memory, the bits are all “packed” together as 12 bits, but you can now address them as if they are 3 groups of 4 bits:
a_packed_array[1] = 4’b1010; // Second set of 4 bits
Now, say that you want to have 5 groups of the previous array. You could either add another packed dimension (e.g. [4:0][2:0][3:0]), or you could add an “unpacked” dimension:
bit [2:0][3:0] a_unpacked_array[5];
Unpacked array elements are stored in memory using regular addressing, rather than being “packed” together in a single address. As shown above, the unpacked dimensions are declared after the variable name.
The benefits of an unpacked array is that you can store any type of data (e.g. strings, object handles, etc). Packed dimensions can only be used with “packable” type (e.g. bits, logic, reg, int, byte, etc.)
When you have a mixture of packed and unpacked dimensions, as above, you can follow a simple rule to understand how to address the elements:
“Left to right, starting with the right”
This means that you always go left to right through the dimensions, but you start with the unpacked dimensions first. So, if you want to store a value in the second set of 4 bits that is in the first unpacked group, you would write:
a_unpacked_array[2][1] = 4’b1010;
The 2 index is the unpacked dimension, and the 1 is the second group in the group of 3.
0 1 2 <----Packed dimensions
0000 0000 0000 0 Unpacked dimension
0000 0000 0000 1 |
0000 1010 0000 2 |
0000 0000 0000 3 |
0000 0000 0000 4 |
Regards,
-Kurt