Structs on the interface are aggregated by Vitis HLS by default; combining all of the elements of a struct into a single wide vector. This allows all members of the struct to be read and written-to simultaneously.
axis
) cannot be
disaggregated, and must be manually coded as separate elements if necessary. Structs on the
interface also prevent Automatic Port Width Resizing and must be coded as
separate elements to enable that feature.As part of aggregation, the elements of the struct are also aligned on a 4
byte alignment for the Vitis kernel flow, and on 1 byte
alignment for the Vivado IP flow. This alignment might
require the addition of bit padding to keep or make things aligned, as discussed in Struct Padding and Alignment. By default the aggregated struct is padded
rather than packed, but you can pack it using the compact=bit
option of the AGGREGATE pragma or
directive.
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. This allows more data to be accessed in a single clock cycle. Any arrays in the struct are partitioned into individual array elements and placed in the vector from lowest to highest, in order.
In the following example, struct data_t
is
defined in the header file shown. The struct has two data members:
- An unsigned vector
varA
of typeshort
(16-bit). - An array
varB
of fourunsigned char
types (8-bit).typedef struct { unsigned short varA; unsigned char varB[4]; } data_t; data_t struct_port(data_t i_val, data_t *i_pt, data_t *o_pt);
Aggregating the struct on the interface results in a single 48-bit port
containing 16 bits of varA
, and 4x8 bits of varB
.
axis
streaming interfaces.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.
There are no limitations in the size or complexity of structs that can be synthesized by Vitis HLS. There can be as many array dimensions and as many members in a struct as required. The only limitation with the implementation of structs occurs when arrays are to be implemented as streaming (such as a FIFO interface). In this case, follow the same general rules that apply to arrays on the interface (FIFO Interfaces).