你的位置:EETOP 赛灵思(Xilinx) 社区 >> >> 全部 >> 详细内容

基于HLS实现FIR滤波器

发布者:jackzhang 时间:2015-09-06 13:47:24

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窗口中会打印出下图红框内的信息,证明测试通过:

最新课程

  • 深入浅出玩儿转FPGA

    本视频基于Xilinx公司的Artix-7FPGA器件以及各种丰富的入门和进阶外设,提供了一些典型的工程实例,帮助读者从FPGA基础知识、逻辑设计概念

  • 从零开始大战FPGA基础篇

    本课程为“从零开始大战FPGA”系列课程的基础篇。课程通俗易懂、逻辑性强、示例丰富,课程中尤其强调在设计过程中对“时序”和“逻辑”的把控,以及硬件描述语言与硬件电路相对应的“

  • Verilog基础及典型数字

    课程中首先会给大家讲解在企业中一般数字电路从算法到流片这整个过程中会涉及到哪些流程,都分别使用什么工具,以及其中每个流程都分别做了