注:本博文所需工程下载链接:http://download.csdn.net/detail/lzy272942518/8863107
1.FIR滤波器简介
FIR(Finite Impulse Response)滤波器:有限长单位冲激响应滤波器,又称为非递归型滤波器,是数字信号处理系统中最基本的元件,它可以在保证任意幅频特性的同时具有严格的线性相频特性,同时其单位抽样响应是有限长的,因而滤波器是稳定的系统。因此,FIR滤波器在通信、图像处理、模式识别等领域都有着广泛的应用。
在进入FIR滤波器前,首先要将信号通过A/D器件进行模数转换,把模拟信号转化为数字信号;滤波器输出的数据是一串序列。FPGA有着规整的内部逻辑阵列和丰富的连线资源,特别适合于数字信号处理任务,相对于串行运算为主导的通用DSP芯片来说,其并行性和可扩展性更好,利用FPGA乘累加的快速算法,可以设计出高速的FIR数字滤波器。本章借助Xilinx HLS工具,实现了一个硬件FIR滤波器。
2.基于HLS的FIR滤波器实现流程
1)打开vivado HLS 2014.4,点击“Create New Project”图标,如下图所示:
2)输入工程名和路径,点击Next:
3)接下来是指定顶层函数名,以及添加所需源文件。可以在工程建立后再进行这些操作,所以直接点击Next:
4)然后是指定测试文件,同样跳过,点击Next:
5)在接下来的界面中,设置时钟周期为默认的10(单位:ns),点击Part Selection右侧的按钮:
6)在search栏输入xc7k160tfbg484-2,然后在Device中选择xc7k160tfbg484-2器件,点击ok。
7)回到Solution Configuration界面,点击Finish,完成新建工程。
8)右击工程界面左侧Explorer栏的Source,选择New File,新建两个文件:fir.h和fir.c。在fir.h中添加如下代码:
#ifndef FIR_H_
#define FIR_H_
#define N 11
typedef int coef_t;
typedef int data_t;
typedef int acc_t;
void fir (
data_t*y,
coef_tc[N+1],
data_tx
);
#endif
保存文件,再在fir.c中添加如下代码:
#include "fir.h"
void fir (
data_t *y,
coef_t c[N],
data_t x
) {
#pragma HLS INTERFACE ap_vld port=x
#pragma HLS RESOURCE variable=c core=RAM_1P_BRAM
static data_tshift_reg[N];
acc_t acc;
data_t data;
inti;
acc=0;
Shift_Accum_Loop: for (i=N-1;i>=0;i--) {
if (i==0) {
shift_reg[0]=x;
data = x;
} else{
shift_reg[i]=shift_reg[i-1];
data= shift_reg[i];
}
acc+=data*c[i];;
}
*y=acc;
}
注意到,优化指令#pragma HLS RESOURCE variable=c core=RAM_1P_BRAM的功能是将c口设置成与外部ram相连的接口。使得c口可以直接从ram中读取数据。可以通过综合完毕后的报告,查看最终生成的端口类型。
保存文件,此时工程界面如下所示:
9)设置顶层函数名。点击project->projectsettings,然后选择synthesis,在SynthesisSettings界面中设置Top Function为fir,如下图所示。然后点击ok:
10)综合工程。点击工程界面上方的综合按钮,如下图红框内所示:
11)综合结束,工程界面会出现一个report文件,可以查看延时以及等待时间、资源占用、接口类型等信息。
12)接下来是测试。右击Explore栏的Test Bench,新建一个fir_test.c的测试文件。添加以下代码,并保存:
#include <stdio.h>
#include <math.h>
#include "fir.h"
int main () {
constint SAMPLES=600;
FILE *fp;
data_tsignal, output;
coef_ttaps[N] ={0,-10,-9,23,56,63,56,23,-9,-10,0,};
inti, ramp_up;
signal = 0;
ramp_up = 1;
fp=fopen("out.dat","w");
for(i=0;i<=SAMPLES;i++) {
if (ramp_up == 1)
signal = signal + 1;
else
signal = signal - 1;
// Execute the function with latest input
fir(&output,taps,signal);
if((ramp_up == 1) && (signal >= 75))
ramp_up = 0;
elseif((ramp_up == 0) && (signal <= -75))
ramp_up = 1;
// Save the results.
fprintf(fp,"%i %d %d\n",i,signal,output);
}
fclose(fp);
printf("Comparing against output data\n");
if(system("diff -w out.datout.gold.dat")) {
fprintf(stdout, "*******************************************\n");
fprintf(stdout, "FAIL: Output DOES NOT match the goldenoutput\n");
fprintf(stdout, "*******************************************\n");
return1;
} else{
fprintf(stdout, "*******************************************\n");
fprintf(stdout, "PASS: The output matches the golden output!\n");
fprintf(stdout, "*******************************************\n");
return0;
}
}
13)添加测试数据文件。将out.gold.dat文件复制到工程根文件夹下,然后在Test Bench中添加这个文件。
14)点击RunC Simulation按钮,然后在新弹出的C Simulation Dialog窗口中点击OK,进行测试:
15)测试结束后,Console窗口中会打印出下图红框内的信息,证明测试通过: