pragma HLS data_pack
Description
Packs the data fields of astruct
into a single scalar with a wider word width.
TheDATA_PACK
pragma is used for packing all the elements of astruct
into a single wide vector to reduce the memory required for the variable, while allowing all members of thestruct
to be read and written to simultaneously. The bit alignment of the resulting new wide-word can be inferred from the declaration order of thestruct
fields. The first field takes the LSB of the vector, and the final element of thestruct
is aligned with the MSB of the vector.
If thestruct
contains arrays, theDATA_PACK
directive performs a similar operation as theARRAY_RESHAPE
pragma and combines the reshaped array with the other elements in thestruct
. Any arrays declared inside thestruct
are completely partitioned and reshaped into a wide scalar and packed with other scalar fields. However, astruct
cannot be optimized withDATA_PACK
andARRAY_PARTITION
orARRAY_RESHAPE
, as those pragmas are mutually exclusive.
DATA_PACK
optimization on
struct
objects with large arrays. If an array has 4096 elements of type int, this will result in a vector (and port) of width 4096*32=131072 bits. Vivado HLS can create this RTL design, however it is very unlikely logic synthesis will be able to route this during the FPGA implementation.
In general, Xilinx recommends that you use arbitrary precision (or bit-accurate) data types. Standard C types are based on 8-bit boundaries (8-bit, 16-bit, 32-bit, 64-bit), however, using arbitrary precision data types in a design lets you specify the exact bit-sizes in the C code prior to synthesis. The bit-accurate widths result in hardware operators that are smaller and faster. This allows more logic to be placed in the FPGA and for the logic to execute at higher clock frequencies. However, theDATA_PACK
pragma also lets you align data in the packedstruct
along 8-bit boundaries if needed.
If astruct
port is to be implemented with an AXI4 interface you should consider using theDATA_PACK
option to automatically align member elements of thestruct
to 8-bit boundaries. The AXI4-Stream protocol requires thatTDATA
ports of the IP have a width in multiples of 8. It is a specification violation to define an AXI4-Stream IP with aTDATA
port width that is not a multiple of 8, therefore, it is a requirement to round upTDATA
widths to byte multiples. Refer to "Interface Synthesis and Structs" inVivado Design Suite User Guide: High-Level Synthesis(UG902) for more information.
Syntax
Place the pragma near the definition of thestruct
variable to pack:
#pragma HLS data_pack variable= \ instance=
Where:
variable=
: is the variable to be packed.instance=
: Specifies the name of resultant variable after packing. If nois specified, the input is used.
: Optionally specifies whether to pack data on an 8-bit boundary (8-bit, 16-bit, 24-bit...). The two supported values for this option are:struct_level
: Pack the wholestruct
first, then pad it upward to the next 8-bit boundary.field_level
: First pad each individual element (field) of thestruct
on an 8-bit boundary, then pack thestruct
.
Tip:Deciding whether multiple fields of data should be concatenated together before (field_level
) or after (struct_level
) alignment to byte boundaries is generally determined by considering how atomic the data is. Atomic information is data that can be interpreted on its own, whereas non-atomic information is incomplete for the purpose of interpreting the data. For example, atomic data can consist of all the bits of information in a floating point number. However, the exponent bits in the floating point number alone would not be atomic. When packing information intoTDATA
, generally non-atomic bits of data are concatenated together (regardless of bit width) until they form atomic units. The atomic units are then aligned to byte boundaries using pad bits where necessary.
Example 1
Packsstruct
array AB[17] with three 8-bit field fields (R, G, B) into a new 17 element array of 24 bits.
typedef struct{ unsigned char R, G, B; } pixel; pixel AB[17]; #pragma HLS data_pack variable=AB
Example 2
Packs struct pointer AB with three 8-bit fields (typedef struct {unsigned char R, G, B;} pixel) in functionfoo
, into a new 24-bit pointer.
typedef struct{ unsigned char R, G, B; } pixel; pixel AB; #pragma HLS data_pack variable=AB
Example 3
In this example theDATA_PACK
pragma is specified forin
andout
arguments torgb_to_hsv
function to instruct the compiler to do pack the structure on an 8-bit boundary to improve the memory access:
void rgb_to_hsv(RGBcolor* in, // Access global memory as RGBcolor struct-wise HSVcolor* out, // Access Global Memory as HSVcolor struct-wise int size) { #pragma HLS data_pack variable=in struct_level #pragma HLS data_pack variable=out struct_level ... }
See Also
- pragma HLS array_partition
- pragma HLS array_reshape
- Vivado Design Suite User Guide: High-Level Synthesis(UG902)