Vitis HLS 允许在 RTL 中将阵列实参作为 FIFO 端口来实现。如果要使用 FIFO 端口,请务必确保往来该阵列的访问均为顺序访问。
注释: 如果在接口处访问并非顺序访问,则存在 RTL 仿真不匹配。
以下代码示例中显示了工具无法判定访问是否为顺序访问时的情况。在此示例中,d_i
和 d_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 通道不支持随机访问,因此必须在遵循先入先出语义的程序内使用该阵列。
如果阵列的数据类型为结构体并按顺序访问阵列(即,指定的阵列包含
axis
或 ap_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;
}
}