Structs in the code, for instance internal and global variables, are disaggregated by default. They are decomposed into separate objects for each of their member elements. The number and type of elements created are determined by the contents of the struct itself. Arrays of structs are implemented as multiple arrays, with a separate array for each member of the struct.
Alternatively, you can use the AGGREGATE pragma or directive to collect all the elements of a struct into a single wide vector. This allows all members of the struct to be read and written to simultaneously. The aggregated struct will be padded as needed to align the elements on a 4-byte boundary, as discussed in Struct Padding and Alignment. The member elements of the struct are placed into the vector in the order they appear in the C/C++ code: the first element of the struct is aligned on the LSB of the vector and the final element of the struct is aligned with the MSB of the vector. Any arrays in the struct are partitioned into individual array elements and placed in the vector from lowest to highest, in order.
int
, this will result in a vector (and port) of
width 4096 * 32 = 131072 bits. While Vitis HLS can create
this RTL design, it is unlikely that the Vivado tool
will be able to route this during implementation.The single wide-vector created by using the AGGREGATE directive allows more
data to be accessed in a single clock cycle. When data can be accessed in a single clock
cycle, Vitis HLS automatically unrolls any loops consuming
this data, if doing so improves the throughput. The loop can be fully or partially unrolled
to create enough hardware to consume the additional data in a single clock cycle. This
feature is controlled using the config_unroll
command and
the option tripcount_threshold
. In the following example,
any loops with a tripcount of less than 16 will be automatically unrolled if doing so
improves the throughput.
config_unroll -tripcount_threshold 16
If a struct contains arrays, the AGGREGATE directive performs a similar operation as ARRAY_RESHAPE and combines the reshaped array with the other elements in the struct. However, a struct cannot be optimized with AGGREGATE and then partitioned or reshaped. The AGGREGATE, ARRAY_PARTITION, and ARRAY_RESHAPE directives are mutually exclusive.