1. 程式人生 > >教程——基於HLS實現FIR濾波器

教程——基於HLS實現FIR濾波器

注:本博文所需工程下載連結: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視窗中會打印出下圖紅框內的資訊,證明測試通過: