pragma HLS dependence - 2023.2 简体中文

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

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

描述

Vitis HLS 会检测循环内的依赖关系:循环的相同迭代内的依赖关系为独立于循环的依赖关系,循环的不同迭代之间的依赖关系则为循环进位依赖关系。DEPENDENCE 编译指示允许您提供额外信息用于定义、抵消循环依赖关系,并允许循环以更低的时间间隔来进行流水打拍。

独立于循环的依赖关系
在单个循环迭代内访问相同元素。
for (i=1;i<N;i++) {
 A[i]=x;
 y=A[i];
}
循环进位依赖关系
从不同循环迭代内访问相同元素。
for (i=1;i<N;i++) {
 A[i]=A[i-1]*2;
}

这些依赖关系会影响运算的调度时间,尤其是在函数和循环流水打拍期间。

在诸如建立变量相关阵列索引或需强制实施外部要求(例如,2 项输入从不采用相同索引)之类的情况下,依赖关系分析可能过于保守,无法滤除假性依赖关系。DEPENDENCE 编译指示允许您显式定义依赖关系并消除假性依赖关系。

重要: 如果实际上依赖关系并非假性 (false) 关系,那么指定假性依赖关系可能导致硬件错误。指定依赖关系前,请确认它是否正确(true 或 false)。

语法

将编译指示置于函数边界内定义依赖关系的位置。

#pragma HLS dependence variable=<variable> <class> \
<type> <direction> distance=<int> <dependent>

其中:

variable=<variable>
(可选)指定为了确认依赖关系而需要考量的变量。
重要: 对于与 m_axi 接口内其他实参捆绑的函数实参,不能指定 dependence。这是函数上的 m_axi 接口的默认配置。并且除非结构体已解聚,否则也不能为结构体的元素指定依赖关系。
class=[array | pointer]
(可选)指定需要澄清其中所含依赖关系的变量的类。有效值包括 arraypointer
提示: <class>variable= 不应一起指定,因为您可以在函数内为某一个变量或者某一类变量指定依赖关系。
type=[inter | intra]
有效值包括 intrainter。指定依赖关系:
intra
相同循环迭代内的依赖关系。当依赖关系 <type> 指定为 intra 并且 <dependent> 为 false 时,HLS 工具可在循环内自由移动操作,从而增大其可移动性并潜在改善性能或面积。当 <dependent> 指定为 true 时,必须按指定顺序执行操作。
inter
不同循环迭代间的依赖关系。这是默认 <type>。如果依赖关系 <type> 指定为 inter,并且 <dependent> 为 false,那么它允许 HLS 工具并行执行多项操作,前提是函数或循环采用流水打拍或者循环已展开或部分展开,当 <dependent> 指定为 true 时,则阻止此类并发操作。
direction=[RAW | WAR | WAW]
仅与循环进位依赖关系有关,用于指定依赖关系的方向:
RAW(先写后读 - 真性依赖关系)
写指令使用的值供读指令使用。
WAR(先读后写 - 反依赖关系)
读指令获取的值被写指令覆盖。
WAW(先写后写 - 输出依赖关系)
2 条写指令按顺序写入相同位置。
distance=<int>
指定阵列访问的迭代间距离。仅与循环进位依赖关系有关,其中依赖关系设为 true
<dependent>
指定 <dependent> 实参可用于指示依赖关系如为 true 则需要强制实施,如为 false 则应移除。但如果不指定该实参,则工具将返回警告,称未指定该值,并且假定值为 false。接受的值为 truefalse

示例 1

在以下示例中,HLS 工具不知晓 cols 的值,并且保守假定在写入 buff_A[1][col] 与读取 buff_A[1][col] 之间始终存在依赖关系。在诸如此类的算法中,cols 几乎不可能为 0,但 HLS 工具无法就数据依赖关系做出任何判断。为了克服这一缺陷,您可使用 DEPENDENCE 编译指示来声明在循环迭代之间(在此示例中,针对 buff_Abuff_B)没有依赖关系。

void foo(int rows, int cols, ...){
  for (row = 0; row < rows + 1; row++) {
    for (col = 0; col < cols + 1; col++) {
    #pragma HLS PIPELINE II=1
    #pragma HLS dependence variable=buff_A type=inter false
    #pragma HLS dependence variable=buff_B type=inter false
      if (col < cols) {
         buff_A[2][col] = buff_A[1][col]; // read from buff_A[1][col]
         buff_A[1][col] = buff_A[0][col]; // write to buff_A[1][col]
         buff_B[1][col] = buff_B[0][col];
      }
    }
  }
}

示例 2

移除 func 函数的 loop_1 的相同迭代中的 Var1 之间的依赖关系。

#pragma HLS dependence variable=Var1 type=intra false

示例 3

func 函数的 loop_2 中的所有阵列上定义依赖关系,以便告知 HLS 工具,在相同循环迭代内,所有读操作都必须发生在写操作之后 (RAW)。

#pragma HLS dependence class=array type=intra direction=RAW true