FIFO 接口 - 2022.1 Chinese

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

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

Vitis HLS 允许在 RTL 中将阵列实参作为 FIFO 端口来实现。如果要使用 FIFO 端口,请务必确保往来该阵列的访问均为顺序访问。

注释: 如果在接口处访问并非顺序访问,则存在 RTL 仿真不匹配。

以下代码示例中显示了工具无法判定访问是否为顺序访问时的情况。在此示例中,d_id_o 均已指定为在综合期间作为 FIFO 接口来实现。在此情况下,您必须确保访问为顺序访问,否则将导致系统中出现错误。

#include "array_FIFO.h"

void array_FIFO (dout_t d_o[4], din_t d_i[4], didx_t idx[4]) {
 int i;
#pragma HLS INTERFACE mode=ap_fifo port=d_i
#pragma HLS INTERFACE mode=ap_fifo port=d_o
 For_Loop: for (i=0;i<4;i++) {
 d_o[i] = d_i[idx[i]];
 }
}

在此情况下,idx 变量的值将判定是否能为 d_i[] 实参成功创建 FIFO 接口。

  • 如果 idx 的元素值为顺序值,则可创建 FIFO 接口
  • 如果 idx 使用随机值,那么在 RTL 中实现时,协同仿真中的 FIFO 接口将失败,运行时期间同样可能失败
但由于在编译时无法确认这些条件,Vitis HLS 会在综合期间发出一条消息并创建 FIFO 接口:
@W [XFORM-124] Array 'd_i': may have improper streaming access(es).

此外,永不读取 idx 阵列,原因是假定由于存在 ap_fifo INTERFACE 编译指示,阵列元素包含从 0 开始的顺序值。

注释: 针对要在同一循环或函数内执行读取和写入的阵列,FIFO 端口无法进行综合。必须创建独立的输入阵列和输出阵列(如上示例所示)。

以下通用规则适用于使用 FIFO 接口实现的阵列:

  • 在循环或函数中,阵列必须仅限于读取或者仅限于写入。这可变换为匹配 FIFO 链接特征的点对点连接。
  • 阵列读取与阵列写入的顺序必须相同。由于针对 FIFO 通道不支持随机访问,因此必须在遵循先入先出语义的程序内使用该阵列。
如果阵列的数据类型为结构体并按顺序访问阵列(即,指定的阵列包含 axisap_fifo 接口,或者以 STREAM 编译指示或指令来标记),则适用以下条件:
  • 无法从适用阵列到串流或者包含在串流接口内的 I/O 实参直接访问结构体成员。可生成结构体的本地副本以读/写成员元素。
  • 您必须确保顺序访问,如下所示
struct A {
  short foo;
  int bar;
};
 
void dut(A in[N], A out[out], bool flag) {
  #pragma HLS interface ap_fifo port=in,out
  for (unsigned i=0; i<N; i++) {
    A tmp = in[i];
    if (flag)
      tmp.bar += 5;
    out[i] = tmp;
  }
}

Bad example 1:
void dut(A in[N], A out[out], bool flag) {
  #pragma HLS interface ap_fifo port=in,out
  for (unsigned i=0; i<N; i++) {
    out[i] = in[i];
    if (flag)
      out[i].bar += 5;
  }
}

Bad example 2:
void dut(A in[N], A out[out], bool flag) {
  #pragma HLS interface ap_fifo port=in,out
  for (unsigned i=0; i<N; i++) {
    out[i].foo = in[i].foo;
    if (flag)
      out[i].bar = in[i].bar + 5;
    else
      out[i].bar = in[i].bar;
  }
}