pragma HLS interface - 2022.1 Chinese

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

Document ID
UG1399
Release Date
2022-06-07
Version
2022.1 简体中文

描述

在 C/C++ 代码中,通过正式的函数实参即可立即执行所有输入和输出操作。在 RTL 设计中,同样,这些输入和输出操作必须通过设计接口中的端口来执行,并且通常使用特定输入/输出 (I/O) 协议来进行操作。如需了解更多信息,请参阅 定义接口

INTERFACE 编译指示可指定在接口综合期间如何根据函数定义创建 RTL 端口。RTL 实现中的端口衍生自:

  • 块级 I/O 协议:提供信号以控制函数何时开始操作,并指示函数操作何时结束、空闲和准备就绪(可接受新输入)。块级协议的实现:
    • <mode>ap_ctrl_noneap_ctrl_hsap_ctrl_chain 来指定。默认采用 ap_ctrl_chain 块协议。
    • 与函数名称相关联。
  • 函数实参:每个函数实参均可指定为包含其自己的端口级 (I/O) 接口协议,例如,有效握手 (ap_vld),或确认握手 (ap_ack)。端口级协议是针对顶层函数和函数返回(如果函数返回值)中的每个实参创建的。创建的默认 I/O 协议取决于 C 语言实参的类型。使用块级协议启动块操作后,端口级 I/O 协议用于对进出块的数据进行排序。
    提示: 接口上必需的全局变量必须显式定义为顶层函数的实参,如 全局变量 中所述。如果访问全局变量,但所有读写操作均为设计的本地操作,则会在该设计中创建此资源。RTL 中无需 I/O 端口。
提示: Vitis HLS 工具会自动确定任何子函数使用的 I/O 协议。您无法为子函数指定 INTERFACE 编译指示或指令。

指定突发模式

使用 max_read_burst_length 选项或 max_write_burst_length 选项(如 语法 部分中所述)为接口指定突发模式时,存在一些衍生自 AXI 标准的限制和相关注意事项,如下所述:

  1. 每个传输事务的突发长度应小于或等于 256 个字,因为 ARLEN & AWLEN 均为 8 位;实际突发长度为 AxLEN+1。
  2. 每个突发传输事务总计传输量小于 4 KB。
  3. 请勿超过 4 KB 地址边界。
  4. 总线宽度指定为 2 的幂,介于 32 位到 512 位之间(即,32、64、128、256 或 512 位),或者以字节计算则为:4、8、16、32 或 64。

在 4 KB 限制下,总线宽度的最大突发长度为:

  • 4 个字节(32 位)对应于单次突发传输事务中传输 256 个字。在此情况下,每个传输事务中传输的总字节数为 1024。
  • 8 个字节(64 位)对应于单次突发传输事务中传输 256 个字。每个传输事务中传输的总字节数为 2048。
  • 16 个字节(128 位)对应于单次突发传输事务中传输 256 个字。每个传输事务中传输的总字节数为 4096。
  • 32 个字节(256 位)对应于单次突发传输事务中传输 128 个字。每个传输事务中传输的总字节数为 4096。
  • 64 个字节(512 位)对应于单次突发传输事务中传输 64 个字。每个传输事务中传输的总字节数为 4096。
提示: HLS 工具生成的 IP 可能实际并不能执行最大突发长度,因为最大突发长度取决于设计。如需了解更多信息,请参阅 AXI 突发传输

例如,如果 max_read_burst_lengthmax_write_burst_length 设为 128,那么来自含 100 次迭代的 for 循环的流水打拍访问将无法填满最大突发长度。

但如果设计的访问长度超过指定的最大突发长度,那么访问将被拆分为多次突发。例如,如果流水打拍 for 循环含 100 次访问,且 max_read_burst_lengthmax_write_burst_length 为 64,那么访问将被拆分为 2 个传输事务:其中一个大小为最大突发长度 (64),另一个则包含剩余数据(突发长度为 36 个字)。

语法

将编译指示布局在函数边界内。

#pragma HLS interface mode=<mode> port=<name> bundle=<string> \
register register_mode=<mode> depth=<int> offset=<string> latency=<value>\
clock=<string> name=<string> storage_type=<value>\
num_read_outstanding=<int> num_write_outstanding=<int> \
max_read_burst_length=<int> max_write_burst_length=<int>

其中:

mode=<mode>
指定函数所使用的函数实参的接口协议模式或者块级控制协议。可指定以下任一模式:
ap_none
无协议。此接口为数据端口。
ap_stable
无协议。此接口为数据端口。HLS 工具假定数据端口复位后始终处于稳定状态,这样即可支持内部最优化移除不必要的寄存器。
ap_vld
用于实现含关联 valid 端口的数据端口,以指示何时数据有效且可供读取或写入。
ap_ack
用于实现含关联 acknowledge 端口的数据端口,以确认数据已读取或写入。
ap_hs
用于实现含关联 valid 端口和 acknowledge 端口的数据端口,提供两路握手以指示数据有效且可供读取和写入,并确认数据已读取或写入。
ap_ovld
用于实现含关联 valid 端口的输出数据端口,以指示何时数据有效且可供读取或写入。
重要: HLS 工具通过 ap_none 模式来实现输入实参或任意读取/写入实参的输入部分。
ap_fifo
使用含关联低电平有效 FIFO empty 端口和 full 端口的数据输入和输出端口来实现含标准 FIFO 接口的端口。
注释: 仅限对读取实参和写入实参使用该接口。ap_fifo 模式不支持双向读写实参。
ap_memory
用于实现阵列实参(作为标准 RAM 接口)。如果在 Vivado IP integrator 中使用 RTL 设计,存储器接口会显示为离散端口。
bram
用于实现阵列实参(作为标准 RAM 接口)。如果在 IP integrator 中使用 RTL 设计,存储器接口会显示为单端口。
axis
用于实现所有端口(作为 AXI4-Stream 接口)。
s_axilite
用于实现所有端口(作为 AXI4-Lite 接口)。HLS 工具会在“Export RTL”(导出 RTL)进程期间生成一组关联的 C 语言驱动程序文件。
m_axi
用于实现所有端口(作为 AXI4 接口)。您可使用 config_interface 命令来指定 32 位(默认)地址端口或 64 位地址端口,并控制任何地址偏移。
ap_ctrl_chain
实现一组块级控制端口以启动 (start) 设计操作、继续执行 (continue) 操作,以及指示设计何时处于 idledoneready 状态,以便处理新输入数据。
注释: ap_ctrl_chain 接口模式类似于 ap_ctrl_hs,但可提供额外的 ap_continue 输入信号以应用反压。赛灵思建议使用 ap_ctrl_chain 块级 I/O 协议将 HLS 工具块链接在一起。
注释: ap_ctrl_chain 是默认块级 I/O 协议。
ap_ctrl_hs
实现一组块级控制端口以启动 (start) 设计操作,并指示设计何时处于 idledoneready 状态,以便处理新输入数据。
ap_ctrl_none
无块级 I/O 协议。
注释: 使用 ap_ctrl_none 模式可阻止使用 C/RTL 协同仿真功能来验证设计。
port=<name>
用于指定 INTERFACE 编译指示所应用到的函数实参或函数返回的名称。
提示: 块级 I/O 协议(ap_ctrl_noneap_ctrl_hsap_ctrl_chain)可分配到端口,以供函数 return 值使用。
bundle=<string>
默认情况下,HLS 工具会将函数实参与兼容选项组合或捆绑到 RTL 中的接口端口内。所有 AXI4-Lite (s_axilite) 接口都会尽可能捆绑到 AXI4-Lite 端口内。同样,默认指定为 AXI4 (m_axi) 接口的所有函数实参也都会捆绑到单一 AXI4 端口内。
含兼容选项(例如,modeoffsetbundle)的所有接口端口都组合到单一接口端口内。端口名称自动衍生自模式与捆绑的组合,或者可通过 -name 来指定名称。
重要: 指定 bundle 名称时,应使用全小写字符。
register
此可选关键字可用于寄存信号和任何相关协议信号,并导致保持直至至少完成函数执行的最后一个周期为止。该选项适用于以下接口模式:
  • s_axilite
  • ap_fifo
  • ap_none
  • ap_hs
  • ap_ack
  • ap_vld
  • ap_ovld
  • ap_stable
提示: config_interface 命令的 -register_io 选项用于全局控制在顶层函数上寄存所有输入/输出的操作。
register_mode=<forward|reverse|both|off>
该选项适用于 AXI4-Stream 接口,并用于指定寄存器布局到正向路径(TDATATVALID)、反向路径 (TREADY) 或同时布局到这两条路径(TDATATVALIDTREADY)上,或者不寄存任何端口信号 (off)。默认值为 bothAXI4-Stream 旁路信号被视为数据信号,随 TDATA 一起寄存。
depth=<int>
指定供测试激励文件处理的最大采样数。此设置用于指示 HLS 工具为 RTL 协同仿真所创建的验证适配器中所需 FIFO 的最大大小。
提示: 虽然 depth 选项通常为可选,但对于 m_axi 接口,它是必需选项,用于确定为适配器分配的资源量,如 AXI4 主接口 中所述。
offset=<string>
为指定端口控制 AXI4-Lite (s_axilite) 和 AXI4 存储器映射 (m_axi) 接口中的地址偏移。
  • s_axilite 接口中,<string> 用于指定寄存器映射中的地址。
  • m_axi 接口中,该选项会覆盖 config_interface -m_axi_offset 选项所指定的全局选项,并且 <string> 指定为:
    • off:不生成偏移端口。
    • direct:生成标量输入偏移端口。
    • slave:生成偏移端口并自动将其映射到 AXI4-Lite 从接口。这是默认偏移。
clock=<name>
(可选)仅限针对接口模式 s_axilite 才会指定该选项。它可定义要用于该接口的时钟信号。默认情况下,AXI4-Lite 接口时钟与系统时钟为相同时钟。该选项用于为 AXI4-Lite (s_axilite) 接口指定独立时钟。
提示: 如果使用 bundle 选项将多个顶层函数实参组合到单一 AXI4-Lite 接口中,那么只需在其中一个捆绑成员上指定时钟选项即可。
name=<string>
指定将在生成的 RTL 中使用的端口的名称。
latency=<value>
mode 设为 m_axi 时,该选项指定期望的 AXI4 接口的时延,允许设计发起总线请求的时间比执行期望的读取或写入操作早数个周期(时延)。如果该值太低,设计将过早达成就绪状态,可能停滞并等待总线;如果该值太高,则可能授予总线访问权时,总线仍处于停滞状态并等待设计发起访问。
storage_impl=<impl>
仅限搭配 s_axilite 一起使用。该选项可定义要分配给接口的存储实现。
受支持的实现值包括 autobramuram。默认值为 auto
提示: uram 是同步存储器,对于两个端口仅含单个时钟。因此,针对含第二个时钟的 s_axilite 适配器不能指定 uram
storage_type=<value>
仅限搭配 ap_memorybram 接口一起使用。该选项用于指定要分配给变量的存储类型(即,RAM_T2P)。
受支持的类型包括:ram_1pram_1wnrram_2pram_s2pram_t2prom_1prom_2prom_np
提示: 对于不在接口上的对象,也可以使用 BIND_STORAGE 编译指示或指令来指定该选项。
num_read_outstanding=<int>
对于 AXI4 (m_axi) 接口,该选项用于指定在设计停滞前可对 AXI4 总线发起的读取请求数量(无响应)。此操作暗示设计中的内部存储空间,即 FIFO 大小为:num_read_outstanding*max_read_burst_length*word_size
num_write_outstanding=<int>
对于 AXI4 (m_axi) 接口,该选项用于指定在设计停滞前可对 AXI4 总线发起的写入请求数量(无响应)。此操作暗示设计中的内部存储空间,即 FIFO 大小为:num_write_outstanding*max_write_burst_length*word_size
max_read_burst_length=<int>
  • 对于 AXI4 (m_axi) 接口,该选项用于指定突发传输期间读取的数据值的最大数量。
max_write_burst_length=<int>
  • 对于 AXI4 (m_axi) 接口,该选项用于指定突发传输期间写入的数据值的最大数量。
    提示: 如果此端口为只读端口,则请设置 num_write_outstanding=1max_write_burst_length=2 以节省存储器资源。对于仅限写入的端口,请设置 num_read_outstanding=1max_read_burst_length=2
-max_widen_bitwidth <int>
自动拓宽接口时,请指定接口可用的最大位宽。此设置将覆盖由 config_interface -m_axi_max_bitwidth 命令指定的全局值。

示例 1

在此示例中,两个函数实参都是使用 AXI4-Stream 接口来实现的:

void example(int A[50], int B[50]) {
  //Set the HLS native interface types
  #pragma HLS INTERFACE mode=axis port=A
  #pragma HLS INTERFACE mode=axis port=B
  int i;
  for(i = 0; i < 50; i++){
    B[i] = A[i] + 5;
  }
}

示例 2

以下设置会关闭块级 I/O 协议,并分配至函数返回值:

#pragma HLS interface mode=ap_ctrl_none port=return

指定函数实参 InData 以使用 ap_vld 接口,并指示应寄存输入:

#pragma HLS interface mode=ap_vld register port=InData

示例 3

此示例定义了顶层 transpose 函数的端口的 INTERFACE 标准。请注意,其中使用了 bundle= 选项来对信号进行分组。

// TOP LEVEL - TRANSPOSE
void transpose(int* input, int* output) {
	#pragma HLS INTERFACE mode=m_axi port=input offset=slave bundle=gmem0
	#pragma HLS INTERFACE mode=m_axi port=output offset=slave bundle=gmem1

	#pragma HLS INTERFACE mode=s_axilite port=input bundle=control
	#pragma HLS INTERFACE mode=s_axilite port=output bundle=control
	#pragma HLS INTERFACE mode=s_axilite port=return bundle=control

	#pragma HLS dataflow