作者:OpenSLee
在《基于FPGA的多級CIC濾波器實現(xiàn)四倍抽取一》和《基于FPGA的多級CIC濾波器實現(xiàn)四倍抽取二》中我們先來了解滑動平均濾波器、微分器、積分器以及梳狀濾波器原理以及它們的幅頻響應(yīng)。此篇我們將用verilog實現(xiàn)基于FPGA的多級CIC濾波器實現(xiàn)四倍插值。
1 CIC濾波器的基本概述
CIC(積分梳狀)濾波器是無線通信中的常用模塊,一般用于數(shù)字下變頻(DDC)和數(shù)字上變頻(DUC)系統(tǒng)。CIC濾波器結(jié)構(gòu)簡單,只有加法器、積分器和寄存器,適合于工作在搞采樣率條件下,而且CIC濾波器是一種基于零點相消的FIR濾波器,已經(jīng)被證明是在高速抽取或插值系統(tǒng)中非常有效的單元。
整數(shù)倍內(nèi)插是先在已知抽樣序列的相鄰兩個抽樣點之間等間隔地插入(I-1)個零值點,然后進行低通濾波器,即可求得I倍內(nèi)插的結(jié)果。
此篇我們采用多級CIC濾波器實現(xiàn)整數(shù)倍內(nèi)插提升采樣率。
2 matlab實現(xiàn)CIC濾波器的四倍插值
設(shè)計目標(biāo):將載波頻率44.1khz的1khz sine升采樣率到176.4khz。
close all clear all clc %set system parameter fs = 1000; %The frequency of the local oscillator signal Fs = 44100; %sampling frequency Fs1 = 176400; N = 24; %Quantitative bits L = 81920; %Generating an input signal t =0:1/Fs:(1/Fs)*(L-1); %Generating the time series of sampling frequencies sc =sin(2*pi*fs*t); %a sinusoidal input signal that produces a random starting phase b =[1,-1];%comb a =[1,-1];%integerator %comb c1=filter(b,1,sc); c2=filter(b,1,c1); c3=filter(b,1,c2); y = upsample(c3,4); %integerater i1 =filter(1,a,y); i2 =filter(1,a,i1); i3 =filter(1,a,i2); sf = i3./16; f_osc =fft(sc,L); f_osc=20*log(abs(f_osc))/log(10); %換算成dBW單位 ft1=[0:(Fs/L):Fs/2]; %轉(zhuǎn)換橫坐標(biāo)以Hz為單位 f_osc=f_osc(1:length(ft1)); f_o =fft(sf,L); f_o=20*log(abs(f_o))/log(10); %換算成dBW單位 ft2=[0:(Fs1/L):Fs1/8]; %轉(zhuǎn)換橫坐標(biāo)以Hz為單位 f_o=f_o(1:length(ft2)); figure(1), subplot(211),stem(t(1:32),sc(1:32)); xlabel('時間(t)','fontsize',8); ylabel('幅度(dB)','fontsize',8); title('sc','fontsize',8); subplot(212),stem(t(1:128),sf(1:128)); xlabel('時間(t)','fontsize',8); ylabel('幅度(dB)','fontsize',8); title('sf','fontsize',8); figure(2), subplot(211),plot(ft1,f_osc); xlabel('頻率(Hz)','fontsize',8); ylabel('功率(dBW)','fontsize',8); title('原始信號信號頻譜圖','fontsize',8);legend('sc'); subplot(212),plot(ft2,f_o); xlabel('頻率(Hz)','fontsize',8); ylabel('功率(dBW)','fontsize',8); title('濾波后信號頻譜圖','fontsize',8);legend('sf');
3 FPGA實現(xiàn)CIC濾波器的四倍插值
FPGA設(shè)計:FPGA由i2s輸入44.1khz的1khz sine(當(dāng)然也可以是歌曲44.1khz采樣率),經(jīng)過i2s串轉(zhuǎn)并后經(jīng)過mult_cic模塊進行采樣率提升處理(變成176.4khz 1khz sine或者歌曲),再通過i2s_tx_master并轉(zhuǎn)串送到DAC 。
多級CIC濾波器的結(jié)構(gòu)主要由梳狀濾波器+插值+積分器構(gòu)成。
FPGA代碼:
`timescale 1ps/1ps module mult_cic#(parameter DW = 38)( input mclk,//45.1584MHZ input reset_n, input signed[31:0] pcm_in,//44.1khz output signed[31:0] pcm_out //176.4khz ); wire signed [DW-1:0] temp; wire signed [DW-1:0]integrator_temp; wire signed [DW-1:0] interpolation_temp; wire signed [DW-1:0] comb_temp; assign temp = {{(DW-32){pcm_in[31]}},pcm_in}; comb#(.DW(DW)) U_comb( .mclk(mclk), .reset_n(reset_n), .din(temp), .dout(comb_temp) ); interpolation#(.DW(DW)) U_interpolation( .mclk(mclk), .reset_n(reset_n), .din(comb_temp), .dout(interpolation_temp) ); integrator#(.DW(DW)) U_integrator( .mclk(mclk), .reset_n(reset_n), .din(interpolation_temp), .dout(integrator_temp) ); //divide assign pcm_out = integrator_temp[35:4]; endmodule
module integrator#(parameter DW = 38)( input mclk, input reset_n, input signed [DW-1:0] din, output signed [DW-1:0] dout ); localparam LAST_CYCLE = 256; reg [7:0] i; reg signed [DW-1:0] temp_xin1,temp_xin2,temp_xin3; wire signed [DW-1:0] i1_temp,i2_temp,i3_temp; always @(posedge mclk or negedge reset_n) begin if(reset_n == 1'b0) i <= 0; else i < = i+1; end always @(posedge mclk or negedge reset_n) begin //The first level integrator if(reset_n == 1'b0) temp_xin1 <= 0; else if(i == (LAST_CYCLE-1)) temp_xin1 <= i1_temp; end assign i1_temp = (reset_n == 1'b0)?38'b0:( din + temp_xin1); always @(posedge mclk or negedge reset_n) begin //The second level integrator if(reset_n == 1'b0) temp_xin2 <= 0; else if(i == (LAST_CYCLE-1)) temp_xin2 <= i2_temp; end assign i2_temp = (reset_n == 1'b0)?38'b0:( i1_temp + temp_xin2); always @(posedge mclk or negedge reset_n) begin //The third level integrator if(reset_n == 1'b0) temp_xin3 <= 0; else if(i == (LAST_CYCLE-1)) temp_xin3 <= i3_temp; end assign i3_temp = (reset_n == 1'b0)?38'b0:( i2_temp + temp_xin3); assign dout = i3_temp; endmodule
module interpolation#(parameter DW = 38)( input mclk, input reset_n, input signed [DW-1:0] din, output signed [DW-1:0] dout ); localparam LAST_CYCLE = 256; reg [9:0] i; reg signed [DW-1:0] dout_pcm; assign dout = dout_pcm; always @(posedge mclk or negedge reset_n) begin if(reset_n == 1'b0) begin i <= 0; dout_pcm<=0; end else begin i <= i+1; if(i == (LAST_CYCLE-1)) dout_pcm<=din; //upsample(x,n)--n--4 if(i == (LAST_CYCLE*2-1)) dout_pcm<=32'b0; //upsample(x,n)--n--4 if(i == (LAST_CYCLE*3-1)) dout_pcm<=32'b0; //upsample(x,n)--n--4 if(i == (LAST_CYCLE*4-1)) dout_pcm<=32'b0; //upsample(x,n)--n--4 end end endmodule
module comb#(parameter DW = 38)( input mclk, input reset_n, input signed [DW-1:0] din, output signed [DW-1:0] dout ); localparam LAST_CYCLE = 1024; reg [9:0] i;//88.2 reg signed [DW-1:0] d1,d2,d3,d4; wire signed [DW-1:0] c1,c2; always @(posedge mclk or negedge reset_n) begin if(reset_n == 1'b0) begin i <= 0; d1 <=0; d2 <=0; d3 <=0; d4 <=0; end else begin i <= i+1; if(i == (LAST_CYCLE-1)) begin d1<=din; d2<=d1; d3<=c1; d4<=c2; end end end assign c1 = (reset_n ==1'b0)?38'b0:(d1-d2);//comb1 assign c2 = (reset_n ==1'b0)?38'b0:(c1-d3);//comb2 assign dout =(reset_n ==1'b0)?38'b0:(c2-d4);//comb3 endmodule
FPGA仿真:
仿真輸入1khz sine輸出依然為1khz sine,設(shè)計成功。
-
matlab
+關(guān)注
關(guān)注
182文章
2963瀏覽量
230176 -
CIC濾波器
+關(guān)注
關(guān)注
0文章
15瀏覽量
10537
發(fā)布評論請先 登錄
相關(guān)推薦
評論