前言
本文根據FIR濾波器相關原理進行設計構建工程,利用前文的工程構建的混頻功能的工程,將高頻分量進行濾除,保留低頻分量。
有限沖擊響應濾波器概述
FIR濾波器廣泛應用于數字信號處理中,主要功能就是將不感興趣的信號濾除,留下有用信號。FIR濾波器是全零點結構,系統永遠穩定;并且具有線性相位的特征,在有效頻率范圍內所有信號相位上不失真。相比IIR濾波器,FIR濾波器更容易用數字域進行實現。
在數字濾波的應用中, 絕大部分接觸的都是使用 FIR Filter,其相對于 IIR Filter 要簡單的多。FIR Filter 的核心思想就是卷積運算,然后了解一下卷積的時域卷積定理,就可以想象出 FIR 濾波器的原理。
卷積類比FIR卷積
在離散數字信號領域, 卷積的定義如下
而 FIR Filter 中的卷積是有限長序列的卷積, 定義為
其中?(????)是濾波器序列, M 是濾波器系數的長度, k 的取值為 0~M-1。在實際的應用中,一般都會認為????(????)的也是從零開始。下面舉一個例子,設置一個序列和一個濾波器系數,然后觀察卷積效果。
xn=[5,11,15,234,34,67,88,46,66,12];%定義x(n)序列
m=size(xn,2);
t1=0:m-1;%定義時間
hn=[0.2,0.2,0.2,0.2,0.2];%定義h(n)序列
n=size(hn,2);
t2=0:n-1;
yn=conv(xn,hn);
t3=0:(n+m-1)-1;%卷積計算后序列的長度定義為n+m-1
figure;
subplot(3,1,1);stem(t1,xn,'r','filled');title('x(n)序列');%畫x(n)序列
subplot(3,1,2);stem(t2,hn,'g','filled');title('h(n)序列');%畫h(n)序列
subplot(3,1,3);stem(t3,yn,'b','filled');title('y(n)序列');%畫y(n)序列
經過卷積運算后的信號序列更加平滑,觀察hn序列中的系數均為0.2,該設計類似一個平滑濾波器的功能,相當于做了平均濾波。
利用MATLAB或filter_solution設計濾波器
DDS的混頻工程,混頻之后的信號是 1Mhz 和 7Mhz,保留低頻分量的話就要濾除 7Mhz 保留 1Mhz。 因為IP中設置的信號動態范圍是 45dB, 那么1Mhz 和 7Mhz 的動態范圍各自是22.5dB,要想把7Mhz 抑制掉,需要至少濾波器要抑制信號 22.5dB。 所以設計的濾波器,在 9Mhz位置需要是有至少-22.5dB 的衰減, 且在1Mhz 位置通帶盡量平滑, 并接近于 0dB,也就是沒有增益沒有衰減。
在這里可以利用MATLAB的濾波器設計工具或者Filter_solution進行構建。
MATLAB的FDA設計
下圖為濾波器設計的界面,通過界面可以設計所需要的濾波器,為了濾除設計中的高頻分量,這里使用了低通濾波,并根據實際的應用需求將參數進行設置。
-
濾波類型(Filter Type)= Lowpass
-
采樣率(Fs) = 50MHZ
-
濾波階數(order) = 63(階數越大,濾波品質越好,但相對滯后越大)
-
密度因子( Density Factor)= 20
-
Fpass(通頻帶)= 2MHZ
-
Fstop(截止帶)= 4MHZ
-
Apass(通頻帶寬增益期望)= 1dB
-
Astop(截止帶寬增益期望)= -80dB
完成濾波器的參數配置后,進行生成濾波器的系數,點擊下圖指示可生成coe文件或者c的頭文件,可根據具體需要進行輸出設置。
filter_solution設計濾波器
該軟件效果和MATLAB的濾波器的效果相當,都是根據需求調整相應的濾波器參數,然后進行生成相關的濾波器系數。
點擊頻率響應可觀察到該濾波器的頻率響應圖。
如下圖所示:
點擊分析濾波器可獲得相關濾波器的權值。可根據具體需求選擇輸出向量模式或者生成相關測試C代碼。
使用FIR IP進行工程設計
將DDS應用實例的工程進行復制備份,然后添加FIR IP。打開設置相關參數。
FIR濾波器IP設置
可先在第一個界面配置濾波器的基本參數,如果濾波器系數選擇向量格式,可將剛剛在濾波器設計軟件中的系數進行復制,并粘貼到vector的輸入框中。這里將之前生成的系數進行復制。
8.05e-04, 8.416e-04, 8.681e-04, 8.624e-04, 7.882e-04, 6.001e-04, 2.496e-04, -3.048e-04, -1.089e-03, -2.101e-03, -3.306e-03, -4.628e-03, -5.95e-03, -7.117e-03, -7.941e-03, -8.217e-03, -7.735e-03, -6.301e-03, -3.758e-03, 0, 5.008e-03, 1.122e-02, 1.85e-02, 2.664e-02, 3.533e-02, 4.421e-02, 5.289e-02, 6.095e-02, 6.798e-02, 7.361e-02, 7.754e-02, 7.956e-02, 7.956e-02, 7.754e-02, 7.361e-02, 6.798e-02, 6.095e-02, 5.289e-02, 4.421e-02, 3.533e-02, 2.664e-02, 1.85e-02, 1.122e-02, 5.008e-03, 0, -3.758e-03, -6.301e-03, -7.735e-03, -8.217e-03, -7.941e-03, -7.117e-03, -5.95e-03, -4.628e-03, -3.306e-03, -2.101e-03, -1.089e-03, -3.048e-04, 2.496e-04, 6.001e-04, 7.882e-04, 8.624e-04, 8.681e-04, 8.416e-04, 8.05e-04
然后可以對通道相關參數進行設置。
在第三個界面中可設置濾波器系數的相關數據格式,以及輸入輸出的數據格式。需要注意的是,這里輸入的信號是DDS產生的數據,這個數據僅有整數部分,所以要調整輸入數據的小數位為0。
詳細實現界面主要對濾波器的硬件實現的架構進行選擇,包括對架構的優化方式,存儲以及DSP資源的使用設置。
接口界面主要對相關的指示信號進行設置,這里可暫時保持默認,實際應用時可根據需要進行使能相關信號。
總結界面對前面的相關設置進行了小結展示,方便用戶進行檢查核對并修改錯誤設置的參數。
同時在左側欄中可以看到濾波器的頻率響應,以及該IP設置的相關資源使用情況,以便于在實際工程應用中對數據鏈路的信號進行操作處理,以及對資源的合理分配。
修改DDS IP
之前進行混頻設計時,使用了DDS的IP輸出三路信號分別為10MHz,3MHz和4MHz。這里為了減少一路輸出,設置兩路的信號輸出,匹配FIR的ip采樣頻率的50MHz。或者這里采用頻率直接修改為33.33MHz也可以。
修改頂層文件
修改了DDS ip后,要對邏輯進行調整使得可根據m_axis_data_tuser信號輸出3M和4M的信號。并在頂層模塊中調用例化FIR的IP,將混頻后的數據接入到FIR的輸入數據端,將DDS的data_tvalid接到FIR ip的tvalid端口,tready可懸空。因為仿真設計的是100MHz時鐘,而FIR ip需要的是50MHz所以用寄存器生成一個二分頻時鐘接入到FIR ip的時鐘端口。
module top(
input clk
);
// wire m_axis_data_tvalid_ch1;
// wire [7:0] m_axis_data_tdata_ch1;
// //單通道測試
// dds_compiler_0 ch1_dds(
// .aclk(clk), // input wire aclk
// .m_axis_data_tvalid(m_axis_data_tvalid_ch1), // output wire m_axis_data_tvalid
// .m_axis_data_tdata(m_axis_data_tdata_ch1) // output wire [7 : 0] m_axis_data_tdata
// );
wire m_axis_data_tvalid_ch3;
wire [7 : 0] m_axis_data_tdata_ch3;
wire [0 : 0] m_axis_data_tuser_ch3;
// wire m_axis_phase_tvalid_ch3;
// wire [31 : 0] m_axis_phase_tdata_ch3;
// wire [1 : 0] m_axis_phase_tuser_ch3;
//多通道測試
dds_compiler_1 multi_ch_dds(
.aclk(clk), // input wire aclk
.m_axis_data_tvalid (m_axis_data_tvalid_ch3), // output wire m_axis_data_tvalid
.m_axis_data_tdata (m_axis_data_tdata_ch3), // output wire [7 : 0] m_axis_data_tdata
.m_axis_data_tuser (m_axis_data_tuser_ch3), // output wire [1 : 0] m_axis_data_tuser
.m_axis_phase_tvalid(), // output wire m_axis_phase_tvalid
.m_axis_phase_tdata (), // output wire [31 : 0] m_axis_phase_tdata
.m_axis_phase_tuser () // output wire [1 : 0] m_axis_phase_tuser
);
reg [7 : 0] data10MHz;
reg [7 : 0] data3MHz;
reg [7 : 0] data4MHz;
always @(posedge clk) begin
case(m_axis_data_tuser_ch3)
0:data3MHz<=m_axis_data_tdata_ch3;
1:data4MHz<=m_axis_data_tdata_ch3;
endcase
end
//混頻測試
wire [15 : 0] mixer_singal;
mult_gen_0 mult_mixer (
.CLK(clk), // input wire CLK
.A(data3MHz), // input wire [7 : 0] A
.B(data4MHz), // input wire [7 : 0] B
.P(mixer_singal) // output wire [15 : 0] P
);
wire [39:0] after_fir_singal;
reg div_clk=0;
always @(posedge clk ) begin
div_clk<=!div_clk;
end
fir_compiler_0 uut_fir(
.aclk(div_clk), // input wire aclk
.s_axis_data_tvalid(m_axis_data_tvalid_ch3), // input wire s_axis_data_tvalid
.s_axis_data_tready(s_axis_data_tready), // output wire s_axis_data_tready
.s_axis_data_tdata(mixer_singal), // input wire [15 : 0] s_axis_data_tdata
.m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata(after_fir_singal) // output wire [39 : 0] m_axis_data_tdata
);
endmodule
運行仿真測試
點擊運行行為級仿真,添加信號波形,并修改信號的進制(進制可選擇有符號十進制)和類型(選擇模擬類型),可觀察到下面的情況。
從截圖中可看出,混頻后的信號經過了濾波處理消除了高頻分量,添加游標可觀察濾波后的信號的頻率。添加游標后觀察發現濾波后的信號為混頻信號的1Mhz的信號。因此,工程設計中的低通濾波很好地濾除掉了7MHz的高頻分量。
小結思考
在使用FIR濾波器中的實際設計的數字濾波器效果可能會因設置的不同而效果不同。因此,在實際使用時要關注一下方面確保濾波器的效果能達到預期。
- 在濾波器工具使用時應考慮不同類型的濾波器的實際效果,可經過對比選擇性能較優異,階數少,且濾波效果能達到使用預期的類型,例如在使用FIR濾波器時,同樣階數的不同類型窗的濾波效果可能對特定信號的濾波效果不同。
- 該工程僅僅驗證了FIR濾波器的基本功能,在實際使用時特別是遇到實時處理的情況需謹慎考慮濾波器的并行度,確保在規定的處理時間內能完成相關信號處理操作,且要關注數據鏈路的數據位寬,確保在實際應用做切片處理時不會損失精度,或造成數據溢出。