接口上的多重访问指针 - 2023.2 简体中文

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

Document ID
UG1399
Release Date
2023-12-18
Version
2023.2 简体中文
重要: 虽然在指针上支持多重访问指针,但强烈建议您使用 hls::stream 类替代多重访问指针来实现所需的行为,以避免下述部分困难。如需了解 hls::stream 类的详细信息,请参阅 HLS 串流库

如果设计使用接口上的顶层函数的实参列表中的指针,那么在使用指针执行多重访问时需考量一些特殊注意事项。当任一指针以相同方式多次执行读取写入时,就会发生多重访问。

使用多次访问的指针可能会在综合后引发意外行为。在以下错误示例中,对指针 d_i 执行了 4 次读取,对指针 d_o 执行了 2 次写入:指针执行了多次访问。

#include "pointer_stream_bad.h"

void pointer_stream_bad ( dout_t *d_o,  din_t *d_i) {
 din_t acc = 0;

 acc += *d_i;
 acc += *d_i;
 *d_o = acc;
 acc += *d_i;
 acc += *d_i;
 *d_o = acc;
}

综合后,此代码产生的 RTL 设计将读取 1 次输入端口,写入 1 次输出端口。与任何标准 C/C++ 语言编译器一样,Vitis HLS 将优化掉多余的指针访问。用于验证此设计的测试激励文件如下代码示例所示:

#include "pointer_stream_bad.h"
int main () {
din_t d_i;
dout_t d_o;
int retval=0;
FILE *fp;

// Open a file for the output results
fp=fopen(result.dat,w);

// Call the function to operate on the data
for (d_i=0;d_i<4;d_i++) {
   pointer_stream_bad(&d_o,&d_i);
   fprintf(fp, %d %d\n, d_i, d_o);
}
fclose(fp);

// Compare the results file with the golden results
retval = system(diff --brief -w result.dat result.golden.dat);
if (retval != 0) {
   printf(Test failed !!!\n);
   retval=1;
} else {
   printf(Test passed !\n);
}

// Return 0 if the test
return retval;
}

要实现上述代码,即对 d_i 读取 4 次,对 d_o 写入 2 次,必须将指针指定为 volatile,如以下“pointer_stream_better”示例所示。

#include "pointer_stream_better.h"

void pointer_stream_better ( volatile dout_t *d_o,  volatile din_t *d_i) {
 din_t acc = 0;

 acc += *d_i;
 acc += *d_i;
 *d_o = acc;
 acc += *d_i;
 acc += *d_i;
 *d_o = acc;
}

为支持接口上的多重访问指针,应执行以下步骤:

  • 执行综合前,确认 C/C++ 语言代码的意图以及 C/C++ 模型是否正确。
  • 如果在 Vitis HLS 中使用协同仿真来验证 RTL,则指针实参所含数值必须与端口接口上指定的访问次数相同。