CIC滤波器
1、单级CIC滤波器:
CIC滤波器的冲激响应为:
h(n)=1,[0,M-1]
h(n)=0,其他
可见CIC滤波器在时域上是一个矩形窗,是一个累加器(积分器)。
用MATLAB仿真不同长度的CIC滤波器:
M=5;
b=ones(1,M);
[Hz,f]=freqz(b,1,1000,1024);
Plot(f*2/1000,20*log10(abs(Hz)));
由上图可知,CIC滤波器的频率响应的包络是sin(x)/x类型,长度越长,通带衰减越大,但旁辨的衰减几乎固定为13.46dB(矩形窗的频谱第一个旁辨的衰减最大为13.46dB)。阻带这么小是不能满足设计要求的,所以要多级CIC级联。
CIC滤波器在0Hz的增益为
abs(sin(0)/sin(0))
对上式使用洛必达法则,得
cos(wD/2)(D/2) / (cos(w/2)*1/2)=cos(0)*(D/2)/cos(0)/2=D
所以一个CIC滤波器的DC(0Hz)增益等于梳状滤波器的延迟D。
2、多级CIC:
用Matlab仿真不同长度的5级CIC滤波器的频谱特性。
M=2; %滤波器长度
b=ones(1,M);
delta=[1,zeros(1,1023)];
s1=filter(b,1,delta); %求取滤波器冲激响应
s2=filter(b,1,s1); %求取滤波器冲激响应
s3=filter(b,1,s2); %求取滤波器冲激响应
s4=filter(b,1,s3); %求取滤波器冲激响应
s=filter(b,1,s4); %求取滤波器冲激响应
Spec=20*log10(abs(fft(s)));%求取滤波器频谱特性
Spec2=Spec-max(Spec);
f=0:length(Spec)-1;
f=2*f/(length(Spec)-1); %对频率轴进行归一化处理
5级CIC级联,旁辨的衰减达到13.46*5=67.3dB,但同时主辨的电平值下降也比单级快得多,在通带内,通带衰减明显增加。所以CIC滤波器适合在多速率系统的前端(第一、二级),CIC滤波器的波纹较大,因为通带与采样频率的比率相对较小,随着通带与采样频率的比率的增加,就必须采用畸变较小的滤波器。
对于多级滤波器来说,各级的误差容限和系统的总误差容限的关系为:
ap=ap1+ap2+ap3+…..+apn
as=as1*as2*as3*…..*asn
通带容限增加时,通带衰减也增大;阻带误差容限减小(阻带衰减增大)。
可以总结出,多级CIC滤波器要求有用信号的频带相对于数据速率足够小,即用作窄带低通滤波器,才能满足通带容限的要求,否则CIC只能用在前端,后面要用性能较好的滤波器。在要求较高的场合,通常是CIC滤波器,半带滤波器和其它类型的FIR滤波器级联起来一起使用。
实际上,CIC滤波器最广泛的用处是实现抽取前端作为去假频滤波器,或内插后端作为去镜像谱滤波器,倍数小于等于7倍(3倍、5倍、7倍)。
为了提高在FPGA实现的运算速度并减少资源消耗,可根据Noble等式调整CIC滤波器的结构。
调换线性系统的抽取系统的处理顺序,即首先进行抽取,然后进行线性滤波,这样就可以将滤波器的长度降低M倍,即滤波器的长度抽头为原来的1/M倍。滤波器的时钟降低到1/M倍。
在内插时将滤波前置,就可以得到阶数降低为了L倍的滤波器。滤波器的时钟频率降低到1/L倍。
1、 Hogenauer滤波器:
采用Nobel恒等式原理,变换多级CIC滤波器结构需要采用IIR滤波器结构。
通常直接在单位圆上有一个滤波器极点是危险的,但这里不一定会给我们带来麻烦,因为在传递函数H(z)中没有量化误差。CIC滤波器的系数都为1,因而可以用非常高的精度皇家马德里定点数格式表示。
多级CIC滤波器级联,抽取因子R对CIC级联系统的频率响应的影响并不大,当R大于16时,滤波器的形状变化都可以忽略,这使我们在变抽取速率系统中可以用相同的补偿FIR滤波器。
注意,Hogenauer抽取滤波器的梳状部分的延迟长度(差分延迟)为N=D/R。因为按R抽取后N个样值的延迟等于按R抽取前的D个样值延迟。延迟值D的典型值为1或2。为了补偿CIC滤波器所造成的恶化,通常需要在多级CIC抽取后添加一个FIR滤波器(补偿器)补偿CIC滤波器不平的通带。
MATLAB仿真:
f1=1000; %信号频率为1KHz
f2=30000; %信号频率为40KHz
Fs=200*f1; %采样频率为200KHz
M=5; %CIC滤波器阶数
D=M; %抽取因子
C=3; %滤波器级数
N=10; %量化位数
%产生信号
t=0:1/Fs:0.02;
c1=2*pi*f1*t;
c2=2*pi*f2*t;
si=sin(c1)+sin(c2);%产生正弦波
%%%%%%%%%%%%%%%%%%%%%%%%%%
%3级积分器
a=[1 -1];
g1=filter(1,a,si);
g2=filter(1,a,g1);
g=filter(1,a,g2);
%D倍抽取
Cg=g(1:D:length(t));
%3级梳状滤波
b=[1 -1];
Cg1=filter(b,1,Cg);
Cg2=filter(b,1,Cg1);
Cgh=filter(b,1,Cg2);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%绘出Matlab对正弦合成信号滤波前后的时域波形
figure(1);
subplot(211);stem(si(1:300));title('Matlab仿真滤波前信号波形');
x=x(1:D:length(x));
subplot(212);stem(Cgh(1:100));title('Matlab仿真滤波后信号波形');
下面给出3级CIC滤波器的在FPGA实现的Verilog代码,实现时采用了Hogenauer“剪除”理论,具体内容见《数字信号处理的FPGA实现(第三版)》Page241,作者U.Meyer-Baese先生同时给出了剪除理论的程序。
经过比较,使用Hogenauer“剪除”理论后,使用的LE减少了近大半,而且fmax提高了不少。
顶层模块:
module CIC_3_STEP(
input CLK,
input RST_N,
input signed[15:0] X_IN,
output signed[15:0] Y_OUT,
output RDY,
output signed[19:0] INT_OUT,
output signed[19:0] DE_OUT
);
//wire RDY;
//wire signed[36:0]INT_OUT;
//wire signed[36:0]DE_OUT;
INTEGRATED U1(
.CLK(CLK),
.RST_N(RST_N),
.X_IN(X_IN),
.INT_OUT(INT_OUT)
);
DECIMATE U2(
.CLK(CLK),
.RST_N(RST_N),
.IIN(INT_OUT),
.DE_OUT(DE_OUT),
.RDY(RDY)
);
COMB U3(
.CLK(CLK),
.RST_N(RST_N),
.RDY(RDY),
.DE_OUT(DE_OUT),
.Y_OUT(Y_OUT)
);
Endmodule
梳状模块:
module COMB(
input CLK,
input RST_N,
input RDY,
input signed[19:0] DE_OUT,
output signed[15:0] Y_OUT
);
reg signed[19:0]buf1;
reg signed[18:0]buf2;
reg signed[17:0]buf3;
reg signed[19:0]y1;
reg signed[18:0]y2;
reg signed[17:0]y3;
always @ (posedgeCLK or negedge RST_N)
if(RST_N == 1'B0)
begin
buf1 <= 0;
buf2 <= 0;
buf3 <= 0;
end
else if(RDY == 1'B1)
begin
buf1 <= DE_OUT;
buf2 <= y1[19:1];
buf3 <= y2[18:1];
end
always @ (posedgeCLK or negedge RST_N)
if(RST_N == 1'B0)
y1 <= 0;
else if(RDY == 1'b1)
y1 <= DE_OUT - buf1;
always @ (posedgeCLK or negedge RST_N)
if(RST_N == 1'B0)
y2 <= 0;
else if(RDY == 1'b1)
y2 <= y1[19:1] - buf2 ;
always @ (posedgeCLK or negedge RST_N)
if(RST_N == 1'B0)
y3 <= 0;
else if(RDY == 1'b1)
y3<= y2[18:1] - buf3;
assignY_OUT = y3[17:2];
endmodule
抽取模块:
odule DECIMATE(
input CLK,
input RST_N,
input signed[19:0] IIN,
output signed[19:0] DE_OUT,
output RDY
);
reg[2:0] cnt;
reg rdy;
reg[19:0] iin_buf;
always @ (posedgeCLK or negedge RST_N)
if(RST_N == 1'B0)
begin
cnt <= 0;
rdy <= 0;
iin_buf <= 0;
end
else if(cnt == 3'd4)
begin
cnt <= 0;
rdy <= 1'b1;
iin_buf <= IIN;
end
else
begin
cnt <= cnt + 1'b1;
rdy <= 1'b0;
end
assign RDY = rdy;
assign DE_OUT =iin_buf;
endmodule
积分模块:
module INTEGRATED(
input CLK,
input RST_N,
input signed[15:0]X_IN,
output signed[19:0]INT_OUT
);
regsigned[22:0] int1;
regsigned[20:0] int2;
regsigned[19:0] int3;
//第一阶积分器
always@ (posedge CLK or negedge RST_N)
if(RST_N == 1'B0)
int1 <= 0;
else
int1 <= int1 + X_IN;
//第二阶积分器
always@ (posedge CLK or negedge RST_N)
if(RST_N == 1'B0)
int2 <= 0;
else
int2 <= int1[22:2] + int2;
//第三阶积分器
always@ (posedge CLK or negedge RST_N)
if(RST_N == 1'B0)
int3 <= 0;
else
int3 <= int2[20:1] + int3;
assign INT_OUT =int3;
endmodule