教程——基於HLS實現FIR濾波器
注:本博文所需工程下載連結:http://download.csdn.net/detail/lzy272942518/8863107
1.FIR濾波器簡介
FIR(Finite Impulse Response)濾波器:有限長單位衝激響應濾波器,又稱為非遞迴型濾波器,是數字訊號處理系統中最基本的元件,它可以在保證任意幅頻特性的同時具有嚴格的線性相頻特性,同時其單位抽樣響應是有限長的,因而濾波器是穩定的系統。因此,FIR濾波器在通訊、影象處理、模式識別等領域都有著廣泛的應用。
在進入FIR濾波器前,首先要將訊號通過A/D器件進行模數轉換,把模擬訊號轉化為數字訊號;濾波器輸出的資料是一串序列。FPGA有著規整的內部邏輯陣列和豐富的連線資源,特別適合於數字訊號處理任務,相對於序列運算為主導的通用DSP晶片來說,其
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
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視窗中會打印出下圖紅框內的資訊,證明測試通過: