FIR(Finite Impulse Response)濾波器是一種有限長單位沖激響應(yīng)濾波器,又稱為非遞歸型濾波器。 FIR 濾波器具有嚴(yán)格的線性相頻特性,同時其單位響應(yīng)是有限長的,因而是穩(wěn)定的系統(tǒng),在數(shù)字通信、圖像處理等領(lǐng)域都有著廣泛的應(yīng)用。
FIR 濾波器原理
FIR 濾波器是有限長單位沖擊響應(yīng)濾波器。 直接型結(jié)構(gòu)如下:
FIR 濾波器本質(zhì)上就是輸入信號與單位沖擊響應(yīng)函數(shù)的卷積,表達(dá)式如下:
FIR 濾波器有如下幾個特性:
(1) 響應(yīng)是有限長序列。
(2) 系統(tǒng)函數(shù)在 |z| > 0 處收斂,極點全部在 z=0 處,屬于因果系統(tǒng)。
(3) 結(jié)構(gòu)上是非遞歸的,沒有輸出到輸入的反饋。
(4) 輸入信號相位響應(yīng)是線性的,因為響應(yīng)函數(shù) h(n) 系數(shù)是對稱的。
(5) 輸入信號的各頻率之間,相對相位差也是固定不變的。
(6) 時域卷積等于頻域相乘,因此該卷積相當(dāng)于篩選頻譜中各頻率分量的增益倍數(shù)。 某些頻率分量保留,某些頻率分量衰減,從而實現(xiàn)濾波的效果。
并行 FIR 濾波器設(shè)計
設(shè)計說明
輸入頻率為 7.5 MHz 和 250 KHz 的正弦波混合信號,經(jīng)過 FIR 濾波器后,高頻信號 7.5MHz 被濾除,只保留 250KHz 的信號。 設(shè)計參數(shù)如下:
輸入頻率: 7.5MHz 和 250KHz
采樣頻率: 50MHz
阻帶: 1MHz ~ 6MHz
階數(shù): 15(N-1=15)
由 FIR 濾波器結(jié)構(gòu)可知,階數(shù)為 15 時,F(xiàn)IR 的實現(xiàn)需要 16 個乘法器,15 個加法器和 15 組延時寄存器。 為了穩(wěn)定第一拍的數(shù)據(jù),可以再多用一組延時寄存器,即共用 16 組延時寄存器。 由于 FIR 濾波器系數(shù)的對稱性,乘法器可以少用一半,即共使用 8 個乘法器。
并行設(shè)計,就是在一個時鐘周期內(nèi)對 16 個延時數(shù)據(jù)同時進(jìn)行乘法、加法運算,然后在時鐘驅(qū)動下輸出濾波值。 這種方法的優(yōu)點是濾波延時短,但是對時序要求比較高。
并行設(shè)計
設(shè)計中使用到的乘法器模塊代碼,可參考之前流水線式設(shè)計的乘法器。
為方便快速仿真,也可以直接使用乘號 “*” 完成乘法運算,設(shè)計中加入宏定義 SAFE_DESIGN 來選擇使用哪種乘法器。
FIR 濾波器系數(shù)可由 matlab 生成,具體見附錄。
/***********************************************************
>> V201001 : Fs:50Mhz, fstop:1Mhz-6Mhz, order: 15
************************************************************/
`define SAFE_DESIGN
module fir_guide (
input rstn, //復(fù)位,低有效
input clk, //工作頻率,即采樣頻率
input en, //輸入數(shù)據(jù)有效信號
input [11:0] xin, //輸入混合頻率的信號數(shù)據(jù)
output valid, //輸出數(shù)據(jù)有效信號
output [28:0] yout //輸出數(shù)據(jù),低頻信號,即250KHz
);
//data en delay
reg [3:0] en_r ;
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
en_r[3:0] <= 'b0 ;
end
else begin
en_r[3:0] <= {en_r[2:0], en} ;
end
end
//(1) 16 組移位寄存器
reg [11:0] xin_reg[15:0];
reg [3:0] i, j ;
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
for (i=0; i<15; i=i+1) begin
xin_reg[i] <= 12'b0;
end
end
else if (en) begin
xin_reg[0] <= xin ;
for (j=0; j<15; j=j+1) begin
xin_reg[j+1] <= xin_reg[j] ; //周期性移位操作
end
end
end
//Only 8 multipliers needed because of the symmetry of FIR filter coefficient
//(2) 系數(shù)對稱,16個移位寄存器數(shù)據(jù)進(jìn)行首位相加
reg [12:0] add_reg[7:0];
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
for (i=0; i<8; i=i+1) begin
add_reg[i] <= 13'd0 ;
end
end
else if (en_r[0]) begin
for (i=0; i<8; i=i+1) begin
add_reg[i] <= xin_reg[i] + xin_reg[15-i] ;
end
end
end
//(3) 8個乘法器
// 濾波器系數(shù),已經(jīng)過一定倍數(shù)的放大
wire [11:0] coe[7:0] ;
assign coe[0] = 12'd11 ;
assign coe[1] = 12'd31 ;
assign coe[2] = 12'd63 ;
assign coe[3] = 12'd104 ;
assign coe[4] = 12'd152 ;
assign coe[5] = 12'd198 ;
assign coe[6] = 12'd235 ;
assign coe[7] = 12'd255 ;
wire [24:0] mout[7:0];
`ifdef SAFE_DESIGN
//流水線式乘法器
wire [7:0] valid_mult ;
genvar k ;
generate
for (k=0; k<8; k=k+1) begin
mult_man #(13, 12)
u_mult_paral (
.clk (clk),
.rstn (rstn),
.data_rdy (en_r[1]),
.mult1 (add_reg[k]),
.mult2 (coe[k]),
.res_rdy (valid_mult[k]), //所有輸出使能完全一致
.res (mout[k])
);
end
endgenerate
wire valid_mult7 = valid_mult[7] ;
`else
//如果對時序要求不高,可以直接用乘號
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
for (i=0 ; i<8; i=i+1) begin
mout[i] <= 25'b0 ;
end
end
else if (en_r[1]) begin
for (i=0 ; i<8; i=i+1) begin
mout[i] <= coe[i] * add_reg[i] ;
end
end
end
wire valid_mult7 = en_r[2];
`endif
//(4) 積分累加,8組25bit數(shù)據(jù) -> 1組 29bit 數(shù)據(jù)
//數(shù)據(jù)有效延時
reg [3:0] valid_mult_r ;
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
valid_mult_r[3:0] <= 'b0 ;
end
else begin
valid_mult_r[3:0] <= {valid_mult_r[2:0], valid_mult7} ;
end
end
`ifdef SAFE_DESIGN
//加法運算時,分多個周期進(jìn)行流水,優(yōu)化時序
reg [28:0] sum1 ;
reg [28:0] sum2 ;
reg [28:0] yout_t ;
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
sum1 <= 29'd0 ;
sum2 <= 29'd0 ;
yout_t <= 29'd0 ;
end
else if(valid_mult7) begin
sum1 <= mout[0] + mout[1] + mout[2] + mout[3] ;
sum2 <= mout[4] + mout[5] + mout[6] + mout[7] ;
yout_t <= sum1 + sum2 ;
end
end
`else
//一步計算累加結(jié)果,但是實際中時序非常危險
reg signed [28:0] sum ;
reg signed [28:0] yout_t ;
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
sum <= 29'd0 ;
yout_t <= 29'd0 ;
end
else if (valid_mult7) begin
sum <= mout[0] + mout[1] + mout[2] + mout[3] + mout[4] + mout[5] + mout[6] + mout[7];
yout_t <= sum ;
end
end
`endif
assign yout = yout_t ;
assign valid = valid_mult_r[0];
endmodule
測試平臺
testbench 編寫如下,主要功能就是不間斷連續(xù)的輸入 250KHz 與 7.5MHz 的正弦波混合信號數(shù)據(jù)。 輸入的混合信號數(shù)據(jù)也可由 matlab 生成,具體見附錄。
`timescale 1ps/1ps
module test ;
//input
reg clk ;
reg rst_n ;
reg en ;
reg [11:0] xin ;
//output
wire valid ;
wire [28:0] yout ;
parameter SIMU_CYCLE = 64'd2000 ; //50MHz 采樣頻率
parameter SIN_DATA_NUM = 200 ; //仿真周期
//=====================================
// 50MHz clk generating
localparam TCLK_HALF = 10_000;
initial begin
clk = 1'b0 ;
forever begin
# TCLK_HALF ;
clk = ~clk ;
end
end
//============================
// reset and finish
initial begin
rst_n = 1'b0 ;
# 30 rst_n = 1'b1 ;
# (TCLK_HALF * 2 * SIMU_CYCLE) ;
$finish ;
end
//=======================================
// read signal data into register
reg [11:0] stimulus [0: SIN_DATA_NUM-1] ;
integer i ;
initial begin
$readmemh("../tb/cosx0p25m7p5m12bit.txt", stimulus) ;
i = 0 ;
en = 0 ;
xin = 0 ;
# 200 ;
forever begin
@(negedge clk) begin
en = 1'b1 ;
xin = stimulus[i] ;
if (i == SIN_DATA_NUM-1) begin //周期送入數(shù)據(jù)控制
i = 0 ;
end
else begin
i = i + 1 ;
end
end
end
end
fir_guide u_fir_paral (
.xin (xin),
.clk (clk),
.en (en),
.rstn (rst_n),
.valid (valid),
.yout (yout));
endmodule
仿真結(jié)果
由下圖仿真結(jié)果可知,經(jīng)過 FIR 濾波器后的信號只有一種低頻率信號(250KHz),高頻信號(7.5MHz)被濾除了。 而且輸出波形是連續(xù)的,能夠持續(xù)輸出。
但是,如紅圈所示,波形起始部分呈不規(guī)則狀態(tài),對此進(jìn)行放大。
波形起始端放大后如下圖所示,可見不規(guī)則波形的時間段,即兩根豎線之間的時間間隔是16 個時鐘周期。
因為數(shù)據(jù)是串行輸入,設(shè)計中使用了 16 組延時寄存器,所以濾波后的第一個正常點應(yīng)該較第一個濾波數(shù)據(jù)輸出時刻延遲 16 個時鐘周期。 即數(shù)據(jù)輸出有效信號 valid 應(yīng)該再延遲 16 個時鐘周期,則會使輸出波形更加完美。
附錄:matlab 使用
生成 FIR 濾波器系數(shù)
打開 matlab,在命令窗口輸入命令: fdatool。
然后會打開如下窗口,按照 FIR 濾波器參數(shù)進(jìn)行設(shè)置。
這里選擇的 FIR 實現(xiàn)方法是最小二乘法(Least-squares),不同的實現(xiàn)方式濾波效果也不同。
點擊 File -> Export
將濾波器參數(shù)輸出,存到變量 coef 中,如下圖所示。
此時 coef 變量應(yīng)該是浮點型數(shù)據(jù)。 對其進(jìn)行一定倍數(shù)的相乘擴(kuò)大,然后取其近似的定點型數(shù)據(jù)作為設(shè)計中的 FIR 濾波器參數(shù)。 這里取擴(kuò)大倍數(shù)為 2048,結(jié)果如下所示。
生成輸入的混合信號
利用 matlab 生成混合的輸入信號參考代碼如下。
信號為無符號定點型數(shù)據(jù),位寬寬度為 12bit,存于文件 'cosx0p25m7p5m12bit.txt' 。
clear all;close all;clc;
%=======================================================
% generating a cos wave data with txt hex format
%=======================================================
fc = 0.25e6 ; % 中心頻率
fn = 7.5e6 ; % 雜波頻率
Fs = 50e6 ; % 采樣頻率
T = 1/fc ; % 信號周期
Num = Fs * T ; % 周期內(nèi)信號采樣點數(shù)
t = (0:Num-1)/Fs ; % 離散時間
cosx = cos(2*pi*fc*t) ; % 中心頻率正弦信號
cosn = cos(2*pi*fn*t) ; % 雜波信號
cosy = mapminmax(cosx + cosn) ; %幅值擴(kuò)展到(-1,1) 之間
cosy_dig = floor((2^11-1) * cosy + 2^11) ; %幅值擴(kuò)展到 0~4095
fid = fopen('cosx0p25m7p5m12bit.txt', 'wt') ; %寫數(shù)據(jù)文件
fprintf(fid, '%x\\n', cosy_dig) ;
fclose(fid) ;
%時域波形
figure(1);
subplot(121);plot(t,cosx);hold on ;
plot(t,cosn) ;
subplot(122);plot(t,cosy_dig) ;
%頻域波形
fft_cosy = fftshift(fft(cosy, Num)) ;
f_axis = (-Num/2 : Num/2 - 1) * (Fs/Num) ;
figure(5) ;
plot(f_axis, abs(fft_cosy)) ;
-
濾波器
+關(guān)注
關(guān)注
161文章
7868瀏覽量
178997 -
寄存器
+關(guān)注
關(guān)注
31文章
5367瀏覽量
121222 -
FIR
+關(guān)注
關(guān)注
4文章
148瀏覽量
33306 -
Verilog
+關(guān)注
關(guān)注
28文章
1352瀏覽量
110425 -
反饋
+關(guān)注
關(guān)注
3文章
43瀏覽量
4902
發(fā)布評論請先 登錄
相關(guān)推薦
DSP in FPGA:FIR濾波器(一)
matlab與FPGA數(shù)字信號處理系列 Verilog 實現(xiàn)并行 FIR 濾波器
并行FIR濾波器Verilog設(shè)計
FIR并行濾波器設(shè)計
基于流水線技術(shù)的并行高效FIR濾波器設(shè)計
![基于流水線技術(shù)的<b class='flag-5'>并行</b>高效<b class='flag-5'>FIR</b><b class='flag-5'>濾波器</b>設(shè)計](https://file1.elecfans.com//web2/M00/A4/AA/wKgZomUMNTKAJaozAACGBBsGBp4408.gif)
基于流水線的并行FIR濾波器設(shè)計
![基于流水線的<b class='flag-5'>并行</b><b class='flag-5'>FIR</b><b class='flag-5'>濾波器</b>設(shè)計](https://file.elecfans.com/web2/M00/49/0A/pYYBAGKhtDWAWRxSAAAOOIQJllY193.jpg)
基于FPGA的橫向FIR濾波器設(shè)計詳解
如何使用FPGA實現(xiàn)實現(xiàn)高速并行FIR濾波器
![如何使用FPGA實現(xiàn)實現(xiàn)高速<b class='flag-5'>并行</b><b class='flag-5'>FIR</b><b class='flag-5'>濾波器</b>](https://file.elecfans.com/web1/M00/DD/77/pIYBAGAShOKAMzz3AACLBTKkX7Q256.png)
如何使用FPGA實現(xiàn)實現(xiàn)高速并行FIR濾波器
![如何使用FPGA實現(xiàn)實現(xiàn)高速<b class='flag-5'>并行</b><b class='flag-5'>FIR</b><b class='flag-5'>濾波器</b>](https://file.elecfans.com/web1/M00/DD/77/pIYBAGAShOKAMzz3AACLBTKkX7Q256.png)
Verilog串行FIR濾波器設(shè)計
![<b class='flag-5'>Verilog</b>串行<b class='flag-5'>FIR</b><b class='flag-5'>濾波器</b>設(shè)計](https://file1.elecfans.com/web2/M00/81/EA/wKgaomQhDviAZZYaAAFvYT4ggMw211.png)
并行FIR濾波器MATLAB與FPGA實現(xiàn)
![<b class='flag-5'>并行</b><b class='flag-5'>FIR</b><b class='flag-5'>濾波器</b>MATLAB與FPGA實現(xiàn)](https://file1.elecfans.com/web2/M00/88/9C/wKgZomRtfPiAVWznAAGB6Yma-y0740.jpg)
Verilog串行FIR濾波器設(shè)計
![<b class='flag-5'>Verilog</b>串行<b class='flag-5'>FIR</b><b class='flag-5'>濾波器</b>設(shè)計](https://file1.elecfans.com/web2/M00/81/EA/wKgZomQhDrGAKTDlAADuSvdVc2c029.jpg)
評論