鉴于前述 GCC 编译器的行为,本节将详述 Vitis HLS 如何使用 aligned
和 packed
属性来创建高效硬件。首先,您需要了解 Vitis HLS 中的 聚合 和 解聚 功能特性。代码中的结构或类对象(例如,内部变量和全局变量)默认情况下处于解聚 (disaggregated) 状态。解聚暗示此结构/类已分解为多个不同对象,针对每个结构体/类成员各一个对象。创建的元素数量和类型取决于结构体本身的内容。结构体阵列作为多个阵列来实现,每个结构体成员都具有独立的阵列。
但默认情况下,用作为顶层函数的实参的结构体则保持聚合状态。聚合暗示任一结构体的所有元素都集合到一个单宽矢量内。这样即可同时读写结构体的所有成员。结构体的成员元素按 C/C++ 代码中所示顺序置于该矢量内:结构体的第一个元素对齐矢量的 LSB,结构体的最后一个元素对齐矢量的 MSB。结构体中的任意阵列都分区到独立阵列元素中,并按从低到高的顺序置于矢量内。
无 AGGREGATE 编译指示时的行为
|
含 AGGREGATE 编译指示时的行为(compact=auto 或者未指定)
|
|||
---|---|---|---|---|
接口实参 | 内部变量 | 接口实参 | 内部变量 | |
AXI 协议接口 ( |
aggregate compact=none | 不适用 | compact=none | 不适用 |
包含 hls::stream 对象的结构体/类 |
自动解聚结构体/类 | 自动解聚结构体/类 | 不适用 | 不适用 |
其它接口协议 | aggregate compact=bit | 自动解聚 | compact=bit | compact=bit |
Vitis HLS 中的默认聚合目的是在硬件接口顶层使用 x86_64-gnu-linux 存储器布局,同时最优化内部硬件以提升结果质量 (QoR)。上表显示了 Vitis HLS 的默认行为。该表中显示了 2 种模式:用户不指定 AGGREGATE
编译指示(默认模式),和用户指定 AGGREGATE
编译指示的模式。
对于 AXI4 接口 (m_axi
/s_axilite
/axis
),默认根据结构体元素对该结构进行填充,如 数据结构填充 中所述。这样即可将结构大小聚合为最接近 2 的幂值,并且在此情况下可应用部分填充。这样即可有效推断 AGGREGATE 编译指示上的 compact=none
选项。
对于其它接口协议,按位级来对结构体进行封装,以便根据该结构体所含的各元素来调整聚合的矢量的大小。这样即可有效推断 AGGREGATE 编译指示上的 compact=bit
选项。
以上规则的唯一例外是在接口中以间接方式使用 hls::stream
时(即,在结构体/类内部使用 hls::stream
对象,随后将此结构体/类用作为接口端口的类型)。包含 hls::stream
对象的结构体将始终解聚为其各独立成员元素。