Difference between Packed and UnPacked Arrays

Hi All,

Can any body tell me the difference between

Packed and UnPacked Arrays.

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

1 Like

In reply to kurts:

Best explanation of packed/unpacked. Thank you

In reply to kurts:

Hi, Thanks really this is the best explanation of packed and unpacked I found on the internet after lot of search.

Thanks for best explanation.

In reply to kurts:

Best explanation i have seen so far. Thanks

Very good explanation, but I failed to understand:
“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; “

Why the first? Should be third instead?

In reply to yt:

Explanation is indeed very good, last example is mistaken though. It would be the third unpacked element. Also the endianing for the packed dimensions should be inverted as it is declared [2:0] and not [0:2]

2    1    0 <----Packed dimensions
0000 0000 0000      0   Unpacked dimension
0000 0000 0000      1       |
0000 1010 0000      2       |
0000 0000 0000      3       |
0000 0000 0000      4       |

See example below


module tb;
initial
  begin
    
    static bit [2:0][3:0]a[5] = '{default:$random};
    $display("a=%p",a);

    $display("a[4]   =12'h%h",a[4]);
    $display("a[0][2]=4'h%h",a[0][2]);
    $display("a[0][1]=4'h%h",a[0][1]);
    $display("a[0][0]=4'h%h",a[0][0]);
    $display("a[4][0]=4'h%h",a[4][0]);
  end
endmodule

a='{'h419, 'h3dd, 'h521, 'hd6d, 'hdc9}
a[4]   =12'hdc9
a[0][2]=4'h4
a[0][1]=4'h1
a[0][0]=4'h9
a[4][0]=4'h9

In reply to kiteloop:

Kurts → Lets be very careful on what packed data types are supported in a packed array.
int type is not supported

Below is the explanation from LRM:
Packed arrays can only be made of the single bit types (bit, logic, reg, wire, and the other net types) and recursively other packed arrays and packed structures.
Integer types with predefined widths cannot have packed array dimensions declared. These types are: byte, shortint, int, longint, and integer. An integer type with a predefined width can be treated as a single dimension packed array. The packed dimensions of these integer types shall be numbered down to 0, such that the right-most index is 0.

byte c2; // same as bit [7:0] c2;
integer i1; // same as logic signed [31:0] i1;