fir.cpp
#include "fir.h"
void fir(data_t *y,data_t x){
coef_t C[N] = {53,0,-91,0,313,500,313,0,-91,0,53};
static
data_t shift_reg[N];
acc_t acc;
int i;
acc = 0;
Shift_Accum_Loop:
for(i = N - 1;i >= 0;i--){
if(i == 0){
acc += x * C[0];
shift_reg[0] = x;
}
else
{shift_reg[i] = shift_reg[i - 1];
acc += shift_reg[i] * C[i];
}
}
*y = acc;
}
fir.h
#define N 11
#include "ap_int.h"
typedef int coef_t;
typedef int data_t;
typedef int acc_t;
void fir(data_t *y,data_t x);
得出fir.cpp综合之后
优化一
将条件语句删除,对for循环进行优化:
for(i = N - 1;i >0;i--){
shift_reg[i] = shift_reg[i - 1];
acc += shift_reg[i] * C[i];
}
acc += x * C[0];
shift_reg[0] = x;
得到有效加速
由此可知,for里面的if/else语句的效率特别低。
优化二
循环内部分开
TDL:
for(i = N - 1;i > 0;i--)
{
shift_reg[i] = shift_reg[i - 1];
}
shift_reg[0] = x;
acc = 0;
MAC:
for(i = N-1;i >= 0;i--)
{
acc += shift_reg[i] * C[i];
}
综合之后得下图,减少了资源,但是,延长了执行时间。
综上所述:for里面的语句都是并行得到。而外面的语句都是顺序执行滴。
优化三:
循环拆分TDL:
TDL:
for(i = N - 1;i > 1;i = i - 2){
shift_reg[i] = shift_reg[i - 1];
shift_reg[i - 1] = shift_reg[i - 2];
}
if(i == 1){
shift_reg[1] = shift_reg[0];
}
shift_reg[0] = x;
MAC:
for(i = N-1;i >= 0;i--)
{
acc += shift_reg[i] * C[i];
}
综合得出下图:
一次需要并行读取两个数据,因此BRAM=2
优化四:
循环展开
pipline流水线 unroll 。。。
手动展开:
TDL:
for(i = N - 1;i > 1;i = i - 2){
shift_reg[i] = shift_reg[i - 1];
shift_reg[i - 1] = shift_reg[i - 2];
}
if(i == 1){
shift_reg[1] = shift_reg[0];
}
shift_reg[0] = x;
acc = 0;
MAC:
for(i = N - 1;i >= 3;i -= 4){
acc += shift_reg[i] * C[i] +
shift_reg[i - 1] * C[i - 1] +
shift_reg[i - 2] * C[i - 2] +
shift_reg[i - 2] * C[i - 2] +
shift_reg[i - 3] * C[i - 3];
}
for(;i >= 0; i--){
acc += shift_reg[i] * C[i];
}
资源用度:
优化五:
流水线:对于for循环的操作进行重叠优化。
任何for都可进行流水线优化
原始的MAC包括四个步骤:
1.读(2个周期)
2.读
3.*
4.+=
优化六:
位宽优化
无