HLS-3for循环优化

一、对循环体的展开

C语言的循环体都是折叠起来的,当综合后会顺序执行,映射到RTL的话就相当于一套电路被分时复用;

进行展开的话就相当于是对电路的复制。

HLS   Directive Editor->Directive->UNROOL->factor=N(N就是要展开成几份)。

二、for循环合并

loop regin:{

add:

for(int i=0;i

c[i]=a[i]+b[i];

}

sub:

for(int i=0;i

d[i]=a[i]+b[i];

}

}

对于这种循环,我们所期望的是程序在执行加法的同时,也执行减法;但是默认情况下它是顺序执行的,也就是执行完加法,再执行减法,这时我们可以将其进行合并 (LOOP_MERGE)这样add和sub可以同时进行。

合并的一些规则:a)边界不同但都为常数的,合并和边界为较大的那个。

     b)边界一个为常数,另一个为变量时,此时无法进行合并。

             c)边界都为变量时,合并后为一个范围。

三、数据流(data_flow)

a) Loop_A:

for(i=0;i

    Loop_B:

for(i=0;i

    Loop_C:

for(i=0;i

数据流动过程:D->TaskA->TaskB->TaskC->out

b)dataflow for "For_loop"

LoopA->channel->LoopB->channel->LoopC channel中可以使用ping-pong,FIFO,register

正常流程:LoopA->LoopB->LoopC 使用dataflow之后:LoopA|LoopA|LoopA

LoopB|LoopB|LoopB

LoopC|LoopC|LoopC

b)data_flow的限制

I)

Loop1:

for(i=0;i

temp1[i]=din[i[*scale;

}

Loop2:

for(i=0;j

dout1[j]=temp1[j]*2;

}

Loop3:

for(k=0;k

dout2[k]=temp1[k]*4;

}

对这种Loop1中的结果在Loop2和Loop3中都被使用的情况(single-producer-consumer model)我们可以在Loop1下面加个Loop_copy将temp1复制一份及:

Loop1:

for(i=0;i

temp1[i]=din[i[*scale;

}

Loop_copy:

for(m=0;m

temp2[m]=temp1[m];

temp3[m]=temp1[m];

}

Loop2:

for(i=0;j

dout1[j]=temp2[j]*2;

}

Loop3:

for(k=0;k

dout2[k]=temp3[k]*4;

}

II)

Loop1:

for(i=0;i

temp1[i]=din[i[*scale;

temp2[i]=din[i]>>scale;

}

Loop2:

for(i=0;j

temp3[j]=temp1[j]*2;

}

Loop3:

for(k=0;k

dout[k]=temp2[k]+temp3[k];

}

对于这种,Loop1产生2个结果,其中一个经Loop2到Loop3,另一个直接被Loop3引用,可以在Loop2中添加一个temp4对temp2进行复制。

Loop1:

for(i=0;i

temp1[i]=din[i[*scale;

temp2[i]=din[i]>>scale;

}

Loop2:

for(i=0;j

temp3[j]=temp1[j]*2;

temp4[j]=temp2[j];

}

Loop3:

for(k=0;k

dout[k]=temp4[k]+temp3[k];

}

四、嵌套式的for循环

对于2层的嵌套,若对外部的for循环做流水,则其内部所有的for循环均会被打开;一般对最内层的做流水。

五、其它的补充

a)rewind可以消除2个周期之间的间隔;

b)当循环边界为变量的时候无法确定其latency,我们可以进行设定或者把值设定为任意精度的。

你可能感兴趣的:(HLS)