基于FPGA的多級(jí)CIC濾波器實(shí)現(xiàn)四倍插值
掃描二維碼
隨時(shí)隨地手機(jī)看文章
基于FPGA的多級(jí)CIC濾波器實(shí)現(xiàn)四倍插值
在《基于FPGA的多級(jí)CIC濾波器實(shí)現(xiàn)四倍抽取一》和《基于FPGA的多級(jí)CIC濾波器實(shí)現(xiàn)四倍抽取二》中我們先來(lái)了解滑動(dòng)平均濾波器、微分器、積分器以及梳狀濾波器原理以及它們的幅頻響應(yīng)。此篇我們將用verilog實(shí)現(xiàn)基于FPGA的多級(jí)CIC濾波器實(shí)現(xiàn)四倍插值。
1 CIC濾波器的基本概述
??CIC(積分梳狀)濾波器是無(wú)線通信中的常用模塊,一般用于數(shù)字下變頻(DDC)和數(shù)字上變頻(DUC)系統(tǒng)。CIC濾波器結(jié)構(gòu)簡(jiǎn)單,只有加法器、積分器和寄存器,適合于工作在搞采樣率條件下,而且CIC濾波器是一種基于零點(diǎn)相消的FIR濾波器,已經(jīng)被證明是在高速抽取或插值系統(tǒng)中非常有效的單元。
??整數(shù)倍內(nèi)插是先在已知抽樣序列的相鄰兩個(gè)抽樣點(diǎn)之間等間隔地插入(I-1)個(gè)零值點(diǎn),然后進(jìn)行低通濾波器,即可求得I倍內(nèi)插的結(jié)果。
??此篇我們采用多級(jí)CIC濾波器實(shí)現(xiàn)整數(shù)倍內(nèi)插提升采樣率。
2 matlab實(shí)現(xiàn)CIC濾波器的四倍插值
??設(shè)計(jì)目標(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('時(shí)間(t)','fontsize',8);
ylabel('幅度(dB)','fontsize',8);
title('sc','fontsize',8);
subplot(212),stem(t(1:128),sf(1:128));
xlabel('時(shí)間(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('原始信號(hào)信號(hào)頻譜圖','fontsize',8);legend('sc');
subplot(212),plot(ft2,f_o);
xlabel('頻率(Hz)','fontsize',8); ylabel('功率(dBW)','fontsize',8);
title('濾波后信號(hào)頻譜圖','fontsize',8);legend('sf');
?

?
3 FPGA實(shí)現(xiàn)CIC濾波器的四倍插值
FPGA設(shè)計(jì):FPGA由i2s輸入44.1khz的1khz sine(當(dāng)然也可以是歌曲44.1khz采樣率),經(jīng)過(guò)i2s串轉(zhuǎn)并后經(jīng)過(guò)mult_cic模塊進(jìn)行采樣率提升處理(變成176.4khz 1khz sine或者歌曲),再通過(guò)i2s_tx_master并轉(zhuǎn)串送到DAC 。
?

多級(jí)CIC濾波器的結(jié)構(gòu)主要由梳狀濾波器+插值+積分器構(gòu)成。
?
?
FPGA代碼:
`timescale 1ps/1psmodule mult_cicinput mclk,//45.1584MHZinput reset_n,input signed[31:0] pcm_in,//44.1khzoutput 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};combU_comb(.mclk(mclk),.reset_n(reset_n),.din(temp),.dout(comb_temp));interpolationU_interpolation(.mclk(mclk),.reset_n(reset_n),.din(comb_temp),.dout(interpolation_temp));integratorU_integrator(.mclk(mclk),.reset_n(reset_n),.din(interpolation_temp),.dout(integrator_temp));//divideassign 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== 1'b0)i <= 0;else= i+1;endalways @(posedge mclk or negedge reset_n) begin //The first level integrator== 1'b0)temp_xin1 <= 0;else if(i == (LAST_CYCLE-1))temp_xin1 <= i1_temp;endassign i1_temp = (reset_n == 1'b0)?38'b0:( din + temp_xin1);always @(posedge mclk or negedge reset_n) begin //The second level integrator== 1'b0)temp_xin2 <= 0;else if(i == (LAST_CYCLE-1))temp_xin2 <= i2_temp;endassign i2_temp = (reset_n == 1'b0)?38'b0:( i1_temp + temp_xin2);always @(posedge mclk or negedge reset_n) begin //The third level integrator== 1'b0)temp_xin3 <= 0;else if(i == (LAST_CYCLE-1))temp_xin3 <= i3_temp;endassign 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) beginif(reset_n == 1'b0) begini <= 0;dout_pcm<=0;endelse begini<= i+1;if(i == (LAST_CYCLE-1)) dout_pcm<=din; //upsample(x,n)--n--4if(i == (LAST_CYCLE*2-1)) dout_pcm<=32'b0; //upsample(x,n)--n--4if(i == (LAST_CYCLE*3-1)) dout_pcm<=32'b0; //upsample(x,n)--n--4if(i == (LAST_CYCLE*4-1)) dout_pcm<=32'b0; //upsample(x,n)--n--4endendendmodule
?
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.2reg signed [DW-1:0] d1,d2,d3,d4;wire signed [DW-1:0] c1,c2;always @(posedge mclk or negedge reset_n) begin== 1'b0) begini <= 0;d1 <=0;d2 <=0;d3 <=0;d4 <=0;endelse begin= i+1;== (LAST_CYCLE-1)) begin=din;=d1;=c1;=c2;endendendassign c1 = (reset_n ==1'b0)?38'b0:(d1-d2);//comb1assign c2 = (reset_n ==1'b0)?38'b0:(c1-d3);//comb2assign dout =(reset_n ==1'b0)?38'b0:(c2-d4);//comb3endmodule
FPGA仿真:
仿真輸入1khz sine輸出依然為1khz sine,設(shè)計(jì)成功。
?

?
至此我們可以去完成3倍抽取5倍插值等采樣率轉(zhuǎn)化算法。





