内核接口 - 2022.1 简体中文

Vitis 统一软件平台文档 应用加速开发 (UG1393)

Document ID
UG1393
Release Date
2022-05-25
Version
2022.1 简体中文
void cnn( int *pixel, // Input pixel
  int *weights, // Input Weight Matrix
  int *out, // Output pixel
  ... // Other input or Output ports

在以上示例中,内核函数具有 3 个指针参数:pixelweightsout。默认情况下,Vitis 编译器将把这 3 个参数映射到同一个 AXI4 接口 (m_axi)。

编译器推断的默认接口映射等同于以下 INTERFACE 编译指示:

#pragma HLS INTERFACE m_axi port=pixel   offset=slave bundle=gmem
#pragma HLS INTERFACE m_axi port=weights offset=slave bundle=gmem
#pragma HLS INTERFACE m_axi port=out     offset=slave bundle=gmem
提示: 该工具不会将推断的编译指示添加到代码中,此处显示此编译指示用于演示分配给接口端口的默认设置。

INTERFACE 编译指示上的 bundle 关键字用于定义端口的名称。Vitis 编译器将为每个独立的捆绑包 (bundle) 名称创建一个端口,从而生成已编译的内核对象 (XO) 文件,此文件中包含单一 AXI 接口 m_axi_gmem。当针对不同接口使用相同 bundle 名称时,会导致将这些接口映射到同一个端口。

提示: gmem 名称表示全局存储器,但它并非关键字,仅用于保持一致性。您可以为捆绑包分配自己的名称。

共享端口有助于通过消除 AXI 接口来节省 FPGA 资源,但它可能限制内核性能,因为所有存储器传输都必须经过同一个端口。m_axi 端口具有独立的 READ 通道和 WRITE 通道,因此通过单一 m_axi 端口即可同时执行读写操作。但通过创建多个端口、使用不同捆绑包名称连接到多个存储体,可能导致内核带宽和吞吐量增加。有许多选项可用于配置 INTERFACE,如 pragma HLS interface 中所述。在代码中手动定义 INTERFACE 编译指示的原因包括但不限于:

  • 为 INTERFACE 编译指示指定捆绑包,用于将 AXI 信号拆分为多个独立的捆绑包。
  • 指定接口宽度不同于默认 int = 64 字节(512 位)。
  • 为突发传输事务指定 AXI 属性。
void cnn( int *pixel, // Input pixel
  int *weights, // Input Weight Matrix
  int *out, // Output pixel
  ... // Other input or Output ports
		   
#pragma HLS INTERFACE m_axi port=pixel   offset=slave bundle=gmem
#pragma HLS INTERFACE m_axi port=weights offset=slave bundle=gmem1
#pragma HLS INTERFACE m_axi port=out     offset=slave bundle=gmem

在以上示例中,2 个 bundle 名称会创建 2 个不同端口:gmemgmem1。内核将通过 gmem 端口访问 pixelout 数据,而 weights 数据则将通过 gmem1 端口来访问。因此,内核将能够并行访问 pixelweights,从而提升内核吞吐量。

重要: 使用全小写字符来指定 bundle= 名称,以便您使用 connectivity.sp 选项将其分配给特定存储体。

v++ 编译期间使用 INTERFACE 编译指示可生成编译后的内核对象 (XO) 文件,其中包含 2 个独立的 AXI 接口:m_axi_gmemm_axi_gmem1,这 2 个接口可按需连接到全局存储器。链接期间,可在配置文件中使用 connectivity.sp 选项将不同接口映射到不同的全局存储体,如 将内核端口映射到存储器 中所述。