基于Quartues ii和Modelsim的FIR滤波器仿真
生活随笔
收集整理的這篇文章主要介紹了
基于Quartues ii和Modelsim的FIR滤波器仿真
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
基于Quartues ii和Modelsim的FIR濾波器仿真
- 基于Quartues ii和Modelsim的FIR濾波器仿真
- 設(shè)計需求
- 設(shè)計思路
- 設(shè)計過程
- MATLAB生成測試數(shù)據(jù)
- 利用filterdesigner工具設(shè)計FIR濾波器
- 在Quartues ii中編寫FIR濾波器模塊
基于Quartues ii和Modelsim的FIR濾波器仿真
設(shè)計需求
本設(shè)計需要實現(xiàn)基于FPGA的FIR低通濾波,采樣頻率5MHz,截止頻率100kHz,利用Matlab設(shè)計FIR濾波器系數(shù),并生成測試數(shù)據(jù)保存至txt文件。在Quartues ii中編寫FIR濾波器模塊,聯(lián)合Modelsim進行功能仿真,觀察濾波效果。
設(shè)計思路
本設(shè)計分為兩個部分,一個是MATLAB中測試數(shù)據(jù)的產(chǎn)生和FIR濾波器的設(shè)計及驗證;另一部分是Quartues ii中基于Verilog的FIR濾波器模塊及testbench編寫。
設(shè)計過程
MATLAB生成測試數(shù)據(jù)
用MATLAB產(chǎn)生5kHz和800kHz的混頻信號,代碼如下:
Fs = 5000000; %采樣頻率決定了兩個正弦波點之間的間隔 N = 8192; %采樣點數(shù) N1 = 0 : 1/Fs : N/Fs-1/Fs; %以頻率Fs采8192個點的數(shù)據(jù) s = sin(5000*2*pi*N1) + sin(800000*2*pi*N1)+3;figure(1); plot(N1,s)得到的波形如圖1所示
利用filterdesigner工具設(shè)計FIR濾波器
在MATLAB中用filterdesigner命令調(diào)出濾波器設(shè)計工具,界面如圖2
選擇低通FIR濾波器,選擇Hamming窗,設(shè)定階數(shù)10階,采樣頻率5MHz,截止頻率100kHz,點擊設(shè)計濾波器可以看到濾波器的幅頻特性曲線。選擇文件->導(dǎo)出,將濾波器系數(shù)導(dǎo)出到工作區(qū)。設(shè)計完成后生成的MATLAB代碼,如下: function Hd = test_filter_kaiser %TEST_FILTER_KAISER 返回離散時間濾波器對象。% MATLAB Code % Generated by MATLAB(R) 9.9 and Signal Processing Toolbox 8.5. % Generated on: 16-Sep-2022 11:01:37% FIR Window Lowpass filter designed using the FIR1 function.% All frequency values are in kHz. Fs = 5000; % Sampling FrequencyN = 10; % Order Fc = 100; % Cutoff Frequency flag = 'scale'; % Sampling Flag Beta = 0.5; % Window Parameter% Create the window vector for the design algorithm. win = kaiser(N+1, Beta);% Calculate the coefficients using the FIR1 function. b = fir1(N, Fc/(Fs/2), 'low', win, flag); Hd = dfilt.dffir(b);% [EOF]
調(diào)用生成的濾波器函數(shù)對前文生成的混頻信號進行濾波,
H=test_filter1; d=filter(H,s);figure(2); plot(N1,d)得到結(jié)果如圖3所示,對比圖1和圖3,可以看到高頻成分衰減了很多。
將設(shè)計的FIR濾波器抽頭系數(shù)導(dǎo)出來。如下:
導(dǎo)出的FIR濾波器抽頭系數(shù)為
0.0138133379804440 ,
0.0296928583924488 ,
0.0717059583915281 ,
0.124585240157610 ,
0.167915751691329 ,
0.184573706773281 ,
0.167915751691329 ,
0.124585240157610 ,
0.0717059583915281 ,
0.0296928583924488 ,
0.0138133379804440,
對其進行量化處理,乘以2^10后取整,得到抽頭系數(shù)
14,30,73,128,172,189,172,128,73,30,14
在Quartues ii中編寫FIR濾波器模塊
代碼如下:
module FIR_test1(input CLK,input RSTn,input [11:0]FIR_IN,output reg [23:0]FIR_OUT );reg[11:0] delay_pipeline1; reg[11:0] delay_pipeline2; reg[11:0] delay_pipeline3; reg[11:0] delay_pipeline4; reg[11:0] delay_pipeline5; reg[11:0] delay_pipeline6; reg[11:0] delay_pipeline7; reg[11:0] delay_pipeline8; reg[11:0] delay_pipeline9; reg[11:0] delay_pipeline10; reg[11:0] delay_pipeline11;wire[7:0] coeff1 = 8'd14; //抽頭系數(shù) wire[7:0] coeff2 = 8'd30; wire[7:0] coeff3 = 8'd73; wire[7:0] coeff4 = 8'd128; wire[8:0] coeff5 = 9'd172; wire[7:0] coeff6 = 8'd189; wire[7:0] coeff7 = 8'd172; wire[7:0] coeff8 = 8'd128; wire[7:0] coeff9 = 8'd73; wire[7:0] coeff10 = 8'd30; wire[7:0] coeff11 = 8'd14;reg signed [23:0] multi_data1 ;//乘積結(jié)果 reg signed [23:0] multi_data2 ; reg signed [23:0] multi_data3 ; reg signed [23:0] multi_data4 ; reg signed [23:0] multi_data5 ; reg signed [23:0] multi_data6 ; reg signed [23:0] multi_data7 ; reg signed [23:0] multi_data8 ; reg signed [23:0] multi_data9 ; reg signed [23:0] multi_data10 ; reg signed [23:0] multi_data11 ;//每到來一個時鐘信號,讀入一個數(shù)據(jù),更新一次delay_pipeline。 always@(posedge CLK or negedge RSTn) if(!RSTn) begindelay_pipeline1 <= 12'b0 ;delay_pipeline2 <= 12'b0 ;delay_pipeline3 <= 12'b0 ;delay_pipeline4 <= 12'b0 ;delay_pipeline5 <= 12'b0 ;delay_pipeline6 <= 12'b0 ;delay_pipeline7 <= 12'b0 ;delay_pipeline8 <= 12'b0 ;delay_pipeline9 <= 12'b0 ;delay_pipeline10<= 12'b0 ;delay_pipeline11<= 12'b0 ; end else begindelay_pipeline1 <= FIR_IN;delay_pipeline2 <= delay_pipeline1 ;delay_pipeline3 <= delay_pipeline2 ;delay_pipeline4 <= delay_pipeline3 ;delay_pipeline5 <= delay_pipeline4 ;delay_pipeline6 <= delay_pipeline5 ;delay_pipeline7 <= delay_pipeline6 ;delay_pipeline8 <= delay_pipeline7 ;delay_pipeline9 <= delay_pipeline8 ;delay_pipeline10 <= delay_pipeline9 ;delay_pipeline11 <= delay_pipeline10 ; end//將輸入經(jīng)過延時的信號和濾波器系數(shù)相乘,每到來一個時鐘便將一個新的乘積結(jié)果更新到multi_data中。這里直接使用“*”,編譯后Quartues ii會自動調(diào)用乘法器IP核 always@(posedge CLK or negedge RSTn) beginif(!RSTn)multi_data1 <= 23'b0 ;elsemulti_data1 <= delay_pipeline1*coeff1 ; endalways@(posedge CLK or negedge RSTn) beginif(!RSTn)multi_data2 <= 23'b0 ;elsemulti_data2 <= delay_pipeline2*coeff2 ; endalways@(posedge CLK or negedge RSTn) beginif(!RSTn)multi_data3 <= 23'b0 ;elsemulti_data3 <= delay_pipeline3*coeff3 ; endalways@(posedge CLK or negedge RSTn) beginif(!RSTn)multi_data4 <= 23'b0 ;elsemulti_data4 <= delay_pipeline4*coeff4 ; endalways@(posedge CLK or negedge RSTn) beginif(!RSTn)multi_data5 <= 23'b0 ;elsemulti_data5 <= delay_pipeline5*coeff5 ; endalways@(posedge CLK or negedge RSTn) beginif(!RSTn)multi_data6 <= 23'b0 ;elsemulti_data6 <= delay_pipeline6*coeff6 ; endalways@(posedge CLK or negedge RSTn) beginif(!RSTn)multi_data7 <= 23'b0 ;elsemulti_data7 <= delay_pipeline7*coeff7 ; endalways@(posedge CLK or negedge RSTn) beginif(!RSTn)multi_data8 <= 23'b0 ;elsemulti_data8 <= delay_pipeline8*coeff8 ; endalways@(posedge CLK or negedge RSTn) beginif(!RSTn)multi_data9 <= 23'b0 ;elsemulti_data9 <= delay_pipeline9*coeff9 ; endalways@(posedge CLK or negedge RSTn) beginif(!RSTn)multi_data10 <= 23'b0 ;elsemulti_data10 <= delay_pipeline10*coeff10 ; endalways@(posedge CLK or negedge RSTn) beginif(!RSTn)multi_data11 <= 23'b0 ;elsemulti_data11 <= delay_pipeline11*coeff11 ; end//將乘積累加,累加的結(jié)果就是濾波后的信號。 always@(posedge CLK or negedge RSTn) beginif(!RSTn)FIR_OUT <= 23'b0 ;elseFIR_OUT <= (multi_data1 + multi_data2 + multi_data3 + multi_data4 +multi_data5 + multi_data6 + multi_data7 + multi_data8 + multi_data9 + multi_data10 + multi_data11)>>10 ; endendmodule接下來編寫testbench,代碼如下:
`timescale 1 ns/ 1 ps module FIR_test1_tb(); // constants // general purpose registers //reg eachvec; // test vector input registers reg CLK; reg [11:0] FIR_IN; reg RSTn; reg [11:0] mem[1:8192];//用來存放讀入的8192個數(shù)據(jù)// wires wire [23:0] FIR_OUT; reg [13:0] i;// assign statements (if any) FIR_test1 i1 ( // port map - connection between master ports and signals/registers .CLK(CLK),.FIR_IN(FIR_IN),.FIR_OUT(FIR_OUT),.RSTn(RSTn) ); initial begin // code that executes only once // insert code here --> begin $readmemh("E:/fault_detection_code/FIR_test1/mem.txt",mem);//讀入3.1中產(chǎn)生的波形數(shù)據(jù)文件mem.txt,文件路徑注意不要搞錯RSTn = 0;CLK = 0;#50 RSTn = 1;#1000000 $stop;// --> end $display("Running testbench"); end always #100 CLK=~CLK;always@(posedge CLK or negedge RSTn) //每次時鐘到達,給FIR_IN一個輸入數(shù)據(jù) beginif(!RSTn) FIR_IN <= 12'b0 ;elseFIR_IN <= mem2[i]; endalways@(posedge CLK or negedge RSTn) beginif(!RSTn)i <= 12'd0;elsei <= i + 1'd1; end//always // optional sensitivity list // @(event1 or event2 or .... eventn) //begin // code executes for every event on sensitivity list // insert code here --> begin //@eachvec; // --> end //end endmoduleFIR濾波器模塊和testbench編譯完成后,進行RTL仿真,可以得到濾波后的波形,如圖4所示,
總結(jié)
以上是生活随笔為你收集整理的基于Quartues ii和Modelsim的FIR滤波器仿真的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PTA L2-016 愿天下有情人都是失
- 下一篇: C#发布程序:应用程序验证未成功,无法继