接口中的结构体 - 2023.2 简体中文

Vitis 高层次综合用户指南 (UG1399)

Document ID
UG1399
Release Date
2023-12-18
Version
2023.2 简体中文

默认情况下,Vitis HLS 会使接口上的结构体保持处于聚合状态,将任一结构体的所有元素都组合到一个单宽矢量中。这样即可同时读写结构体的所有成员。您可使用 DISAGGREGATE 编译指示或指令对接口中的结构体进行解聚。当结构体包含一个或多个 hls::stream 对象时,Vitis HLS 将按下文接口中含 hls::stream 元素的结构体中所述,对结构体进行自动解聚。

重要:Vitis 内核流程中不支持对接口中的结构体进行解聚,因为 Vitis 工具无法将单个 C 语言实参映射到多个 RTL 端口。对接口中的结构体进行解聚时,Vitis HLS 将通过手动或自动方式来构建和导出 Vitis 内核输出 (.xo),但搭配 v++ 命令一起使用时,此输出将出错。要支持 Vitis 内核流程,您必须将此结构体手动拆分为其组成成分元素,并将任意 hls::stream 对象定义为使用 AXIS 接口

在聚合过程中,针对 Vitis 内核流程,结构体的所有元素都在 4 字节对齐位置对齐,对于 Vivado IP 流程,则在 1 字节对齐位置对齐。此对齐可能需要添加位填充,以对齐各元素或者使各元素保持对齐,如 结构体填充与对齐 中所述。默认情况下,聚合的结构体将进行填充而不是打包,但在 Vivado IP 流程中,您可使用 AGGREGATE 编译指示或指令的 compact=bit 选项将其打包。但定义为 AXI4 接口的任意端口(m_axis_axiliteaxis)都无法使用 compact=bit

该结构体的成员元素按 C/C++ 语言代码中所示顺序置于该矢量内:结构体的第一个元素对齐矢量的 LSB,结构体的最后一个元素对齐矢量的 MSB。这样即可在单一时钟周期内访问更多数据。结构体中的任意阵列都分区到独立阵列元素中,并按从低到高的顺序置于矢量内。

在以下示例中所示头文件内定义 struct data_t。此结构体包含 2 个数据成员:

  • 无符号的矢量 varA,类型为 short(16 位)。
  • 阵列 varB,含 4 种 unsigned char 类型(8 位)。
    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);
    

在接口上聚合结构体会生成单个 48 位端口,其中包含 16 位 varA 和 4x8 位 varB

提示: 由数据打包创建的任意端口或总线的最大位宽为 8192 位,或者针对 axis 串流接口则为 4096 位。

对于 Vitis HLS 可综合的结构体的大小或复杂性并无限制。结构体中可包含所需的任意数量的阵列维度和成员。仅当阵列作为串流(例如,FIFO 接口)来实现时,才会出现结构体实现的唯一限制。在此情况下,请遵循适用于接口(FIFO 接口)上的阵列的常规规则进行操作。

接口上含 hls::stream 元素的结构体

包含 hls::stream 元素的接口上的用户定义的结构体将由 Vitis HLS 自动进行解聚。在 Vivado IP 流程中,支持解聚的结构体,并且导出的 IP 将能够按期望的方式工作。但 Vitis 内核流程则不支持此解聚的结构体,并且导出的内核 (.xo) 搭配 v++ --link 命令一起使用时,将导致出错。要支持 Vitis 内核流程,您必须将此结构体手动拆分为其组成成分元素,并将 hls::stream 对象定义为使用 AXIS 接口。

如有结构体已自动解聚,Vitis HLS 会将任意 INTERFACE 编译指示应用于已解聚的结构体的各个元素。如果针对此结构体仅指定一条 INTERFACE 编译指示,那么它将应用于该结构体的每个元素。如果您为已解聚的结构体的每个元素都提供一个 INTERFACE 编译指示,则会按期望方式来应用编译指示。