引入指针算术会限制 RTL 中可综合的接口。以下代码示例显示了相同的代码,但在此实例中使用简单的指针算术来累加数据值(从第 2 个值开始)。
#include "pointer_arith.h"
void pointer_arith (dio_t *d) {
static int acc = 0;
int i;
for (i=0;i<4;i++) {
acc += *(d+i+1);
*(d+i) = acc;
}
}
以下代码示例显示了支持此示例的测试激励文件。由于执行累加的循环当前位于 pointer_arith
函数内部,测试激励文件会填充含相应值的 d[5]
阵列所指定的地址空间。
#include "pointer_arith.h"
int main () {
dio_t d[5], ref[5];
int i, retval=0;
FILE *fp;
// Create input data
for (i=0;i<5;i++) {
d[i] = i;
ref[i] = i;
}
// Call the function to operate on the data
pointer_arith(d);
// Save the results to a file
fp=fopen(result.dat,w);
printf( Din Dout\n, i, d);
for (i=0;i<4;i++) {
fprintf(fp, %d \n, d[i]);
printf( %d %d\n, ref[i], d[i]);
}
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;
}
仿真后,会生成如下输出:
Din Dout
0 1
1 3
2 6
3 10
Test passed!
指针算术能无序访问指针数据。另一方面,连线、握手或 FIFO 接口只能按顺序访问数据:
- 当设计准备好使用数据或写入数据(当数据就绪后)时,连线接口会读取数据。
- 当控制信号允许继续操作时,握手和 FIFO 接口会执行读写操作。
在上述 2 种情况下,数据都必须按顺序到达(并写入),从元素 0 开始。在“含指针算术的接口”示例中,代码从索引 1 开始读取(i
从 0 开始,0+1=1)。这是来自测试激励文件中的 d[5]
阵列的第 2 个元素。
在硬件中实现此示例后,需要某种形式的数据索引。Vitis HLS 不支持对连线、握手或 FIFO 接口建立数据索引。
或者,必须修改此代码,在接口上使用阵列代替指针,如以下示例所示。在综合中可通过 RAM (ap_memory
) 接口来实现此代码。此接口可使用地址来建立数据索引,并执行乱序或无序访问。
连线、握手或 FIFO 接口只能用于串流数据。除非它从 0 位数据开始建立数据索引,然后按顺序进行操作,否则不能搭配指针算术使用。
#include "array_arith.h"
void array_arith (dio_t d[5]) {
static int acc = 0;
int i;
for (i=0;i<4;i++) {
acc += d[i+1];
d[i] = acc;
}
}