A packed array is a mechanism for subdividing a vector into subfields which can be conveniently accessed as array elements. A packed array is guaranteed to be represented as a contiguous set of bits.
An unpacked array may or may not be so represented. A packed array differs from an unpacked array in that, when a packed array appears as a primary, it is treated as a single vector.
An unpacked array is declared as signed, then this applies to the individual elements of the array, since the whole array cannot be viewed as a single vector.
If a packed array is declared as signed, then the array viewed as a single vector shall be signed. The individual elements of the array are unsigned unless they are of a named type declared as signed. A part-select of a packed array shall be unsigned.
Here is the GOCHA:
If you declare:
logic signed [3:0] unpacked_signed_array [2:0]; // this is unpacked array, signed_array[#] is signed
logic signed [2:0][3:0] packed_signed_array; // this is packed array, signed_array itself is signed, signed_array[#] is unsigned
// This is enough to cause confusing when you deal with Verilog's context of signedness
logic signed sig_mult;
sig_mult = packed_signed_array[0] * packed_signed_array[0]; // give you unsigned multiplication
sig_mult = unpacked_signed_array[0] * unpacked_signed_array[0]; // give you signed multiplication
// to get signed multiplication by using packed array do the following:
sig_mult = $signed(packed_signed_array[0]) * $signed(packed_signed_array[0]);
Remember:
Reference:
An unpacked array may or may not be so represented. A packed array differs from an unpacked array in that, when a packed array appears as a primary, it is treated as a single vector.
An unpacked array is declared as signed, then this applies to the individual elements of the array, since the whole array cannot be viewed as a single vector.
If a packed array is declared as signed, then the array viewed as a single vector shall be signed. The individual elements of the array are unsigned unless they are of a named type declared as signed. A part-select of a packed array shall be unsigned.
Here is the GOCHA:
If you declare:
logic signed [3:0] unpacked_signed_array [2:0]; // this is unpacked array, signed_array[#] is signed
logic signed [2:0][3:0] packed_signed_array; // this is packed array, signed_array itself is signed, signed_array[#] is unsigned
// This is enough to cause confusing when you deal with Verilog's context of signedness
logic signed sig_mult;
sig_mult = packed_signed_array[0] * packed_signed_array[0]; // give you unsigned multiplication
sig_mult = unpacked_signed_array[0] * unpacked_signed_array[0]; // give you signed multiplication
// to get signed multiplication by using packed array do the following:
sig_mult = $signed(packed_signed_array[0]) * $signed(packed_signed_array[0]);
Remember:
- If a packed array is declared as signed, only the vector as whole is treated as signed. Individual elements of the array is still unsigned.
- Verilog operation context of signedness rule: treat the right hand side of an assignment, as long as there is one operand is unsigned, unsigned operation is in effect.
- context for size is both the right and left hand of an assignment.
- MentorGraphics QuestaSim, display hexadecimal string of packed array in Capital Letter, unpacked in Lower case.
Reference:
- Arrays and Queues in SystemVerilog, http://electrosofts.com/systemverilog/arrays.html
- Synopsys, Coding Guidelines for Datapath, Synthesis, https://www.synopsys.com/dw/dwtb/pipelining/coding_guidelines.pdf
- Standard Gotchas, Subtleties in the Verilog and SystemVerilog, http://www.sutherland-hdl.com/papers/2006-SNUG-Boston_standard_gotchas_presentation.pdf