多采样速率的数字信号处理系统常常会用到采样速率的转换,如内插和抽取。由傅里叶变换性质可知,信号时域内的抽取会导致频谱周期性平移拓宽,当信号中有高频分量时,可能出现频谱混叠的现象。因此在抗频谱混叠中需要滤波操作,将高频分量滤除。梳状滤波器(CIC,Cascaded integrator–comb filter)结构简单,仅有乘、加单元,可以实现多倍速率下抽变换,并且能够滤除高频成分。为了使过渡带陡峭,抑制旁瓣,滤波器的带内容差不宜过大。当扫频的带宽一定时,CIC滤波器常用在采样率下抽的第一级,以满足较大的采样率和较小的下抽因子来降低带内容差。梳状滤波器传递函数的表达式和实现结构如下:
D为采样率下抽的倍数,N表示滤波器级联数,Z-1表示延迟一拍。由于梳状滤波器的零极点可以相互抵消,滤波器仍是稳定的因果系统。在MATLAB环境中绘制其幅频响应曲线和相频响应曲线如下:
可以看出,单级情况下旁瓣衰减约为13.46dB;级联之后,CIC滤波器旁瓣衰减与级联数成正比为N*13.46dB,即每增加一级级联旁瓣抑制将增加13.46dB;并且CIC滤波器的相位呈线性。另外的参考书本:
- 杜勇. 数字调制解调技术的MATLAB与FPGA实现:Altera/Verilog版[M]. 北京:电子工业出版社, 2015.
--------------------------------------------------------假装我是分割线--------------------------------------------------------
%%%%%%%%%%%%%%%%%%%%%%%%%
% 绘制M阶CIC的频谱特性
%%%%%%%%%%%%%%%%%%%%%%%%%
clc
clear
close all
Len = 1024*300;%绘制数据点数
fs = 2*1e5;
D = 16;%下抽倍数
N = [1,3,5]; %CIC级联数
w = 0.01:1/fs:(Len-1)/fs;
H_abs = zeros(length(N),length(w))';
for ii = 1:length(N)
for jj = 1:length(w)
%H(jj,ii) = (abs(sin(w(jj)*D/2)/sin(w(jj)/2)))^N(ii);%幅度相应表达式
H(jj,ii)=((1-exp(-1j*w(jj)*D))/(1-exp(-1j*w(jj))))^N(ii);
H_abs(jj,ii)=abs(H(jj,ii));
H_ang(jj,ii)=angle(H(jj,ii));
end
end
%绘制幅频特性曲线
figure
plot(w'/max(w),20*log10(H_abs(:,1) / max(H_abs(:,1)) ),'k','Linewidth',2);
grid on
title('幅频特性');xlabel('归一化频率');ylabel('幅度(dB)');
legend('N=1','N=3','N=5','Location','best');
hold on
plot(w'/max(w),20*log10(H_abs(:,2) / max(H_abs(:,2)) ),'k--','Linewidth',2);
plot(w'/max(w),20*log10(H_abs(:,3) / max(H_abs(:,3)) ),'k','Linewidth',3);
hold off;
grid on;
title('幅频特性');xlabel('归一化频率');ylabel('幅度(dB)');
legend('N=1','N=3','N=5','Location','best');
axis([0 1 -200 0]);%绘制相频特性曲线
figure
plot(w'/max(w),H_ang(:,1),'k','Linewidth',2);grid on;
title('相频特性');xlabel('归一化频率');ylabel('相位(rad)');
legend('N=1','Location','best');
axis([0 1 -pi pi]);
-------------------------------------------------------cic的m文件------------------------------------------------
以下抽时举例
function signal_cic = cic_filter(signal,div)
%------------------------------------------------------------------------
% 功能: 函数实现3级级联的梳状滤波器,下抽倍数为div
% 输入输出:
% signal : 待滤波及下抽的信号
% div : 下抽的倍数
%------------------------------------------------------------------------
%CIC filter and downsample div
x = zeros(length(signal),1);
x(1) = signal(1);
%积分过程
for ii = 1:length(signal)-1
x(ii+1) = x(ii) + signal(ii+1);
end
y = zeros(length(signal),1);
y(1) = x(1);
for ii = 1:length(signal)-1
y(ii+1) = y(ii) + x(ii+1);
end
z = zeros(length(signal),1);
z(1) = y(1);
for ii = 1:length(signal)-1
z(ii+1) = z(ii) + y(ii+1);
end
data = z(1:div:div*floor(length(signal)/div));%downsample
%差分过程
x = zeros(length(data),1);
x(1) = data(1);
for ii = 1:length(data)-1
x(ii+1) = data(ii+1) - data(ii);
end
y = zeros(length(data),1);
y(1) = x(1);
for ii = 1:length(data)-1
y(ii+1) = x(ii+1) - x(ii);
end
z = zeros(length(data),1);
z(1) = y(1);
for ii = 1:length(data)-1
z(ii+1) = y(ii+1) - y(ii);
end
signal_cic = (z/div^3);
--------------------------------------------------------CIC的FPGA设计------------------------------------------------
以Xilinx官网给的cic IP核手册为例,需要关注每一级的位宽增加。
如:梳状滤波器CIC下抽R=5倍,N=3级级联,延迟拍数M=1,输入数据Bit_in=16,输出Bit_out=Bit_in+N*log2(R),向上取整,输出全精度为23位定点数=floor(16+3*log2(5))+1。(有次面试官问了CIC中间数据位宽的计算,当时一脸懵逼,都是IP核搞定,谁管这些。后来…………哎)