HLS高层次综合设计技巧--绕过任务对Dataflow的阻碍讨论

HLS高层次综合设计技巧--绕过任务对Dataflow的阻碍讨论

一、绕过任务架构

上图是绕过任务的架构,其中模块一将产生temp1和temp2样本,模块二只使用了temp1,但是没有使用temp2,模块三将需要使用temp2和temp3。

绕过任何核心代码架构:

void foo(int data_in[N], int scale, int data_out1[N], int data_out2[N]) {
int temp1[N], temp2[N]. temp3[N];
Loop1: for(int i = 0; i < N; i++) {
temp1[i] = data_in[i] * scale;
temp2[i] = data_in[i] >> scale;
}

Loop2: for(int j = 0; j < N; j++) {
temp3[j] = temp1[j] + 123;
}

Loop3: for(int k = 0; k < N; k++) {
data_out[k] = temp2[k] + temp3[k];
}
}

上述设计将会阻碍dataflow指令的优化和设计。

二、绕过任务造成dataflow被阻的原因分析

我们可以分析一下:
LOOP1循环产生temp1和temp2;但是,LOOP2只是消耗掉了temp1,并且产生了temp3;
LOOP3需要同事依赖temp2和temp3;
这里存在一个问题,就说LOOP3需要等待temp3和temp2的同步。
也就是说temp2必须移植保存再RAM或者FIFO中,需要等到LOOP2彻底完毕,才开始
读取temp3,因为LOOP2的不同处理,造成temp2的读取时机不一样,但是FPGA资源是静态
分配,所以综合工具会比较保守,设计会退化到当LOOP2全部完成才会读取temp2,
那么就需要又足够大的数组存储temp2,这个将会消耗很多资源,甚至会造成综合失败。

三、解决办法

修改架构为:

修改代码为:

void foo(int data_in[N], int scale, int data_out1[N], int data_out2[N]) {
int temp1[N], temp2[N]. temp3[N], temp4[N];
Loop1: for(int i = 0; i < N; i++) {
temp1[i] = data_in[i] * scale;
temp2[i] = data_in[i] >> scale;
}

Loop2: for(int j = 0; j < N; j++) {
temp3[j] = temp1[j] + 123;
temp4[j] = temp2[j];
}

Loop3: for(int k = 0; k < N; k++) {
data_out[k] = temp4[k] + temp3[k];
}
}