本文将详细介绍使用Verilog HDL设计单级CIC滤波器的方法。
CIC滤波器多速率信号处理系统中最主要的还是滤波器的设计:抽取和内插后不能产生频谱混叠、占用资源少、运算速度快。上一篇介绍了多速率FIR滤波器,与其相比,CIC(Cascaded Integrator Comb,积分梳状)滤波器运算速度快、占用资源少、工作频率高(因为CIC只使用加法器、减法器和寄存器),在多速率信号处理系统中应用更广泛。 ●频谱特性CIC本质上其实就是一种特殊的FIR滤波器(系数都为1)。本文不用理论推导的方式,从频谱图出发更直观地观察体会CIC滤波器的特点。我们使用matlab的FDATOOL工具观察CIC滤波器的频谱。
点击最左边的小按钮,中间选择CIC滤波器,右边级数(Number Of Sections)设置为1,表示单级CIC滤波器。这里设置为对25MHz的Fs进行25倍抽取。可以看到第一旁瓣的衰减为13.46dB(事实上这是一个固定的值,与CIC滤波器阶数无关),这个阻带衰减远远不能满足通常的设计要求,通过级联的方式可以提高阻带衰减,在下一篇介绍多级CIC滤波器时再详细说明。 ●阶数与倍数的关系CIC滤波器通常用于抗混叠抽取/内插滤波器(抽取与内插结构见本文开头的链接)。考虑抽取/内插的过程、CIC滤波器的特性(系数为1的特殊FIR滤波器)以及FIR滤波器的实现结构,就会发现,当CIC滤波器的阶数与内插/抽取的倍数相同时,其结构更利于FPGA实现。比如抽取时,只需要将D个数据组成一组,相加作为一个输出即可(即同时完成了滤波与抽取)。 结合下面的实例理解(设CIC滤波器阶数与抽取倍数都为5):
完整的抽取过程为:CIC作为抗混叠滤波,由于系数为1,y1=x1+x2+…+x5,y2=x2+x3+…+x6,等等;得到滤波输出后,再每隔4个点(即D-1个)取一个值输出,完成5倍抽取。而这个过程恰好等效于将原始数据每5个分为一组,每组的数据分别相加作为一个输出。由此可见:当CIC滤波器与抽取倍数相同时,可以大大节省资源、减小运算量。 同理,当使用CIC完成内插滤波时,设CIC滤波器阶数与内插倍数都为5:
完整的内插过程为:每两个数据之间插入4个零值(I-1个),完成5倍内插,之后使用CIC做低通滤波,由于CIC滤波器的系数为1,滤波后的插值0变为前一个原始数据值。这个过程恰好等效于直接在两个数据之间插入前一个数据值。由此可见:当CIC滤波器与内插倍数相同时,也可以节省资源和运算。 CIC抽取滤波器的FPGA设计与仿真使用50MHz采样率对0.25MHz的信号进行采样,由五阶CIC滤波器进行5倍抽取,将采样率降至10MHz。根据上文的介绍,设计的Verilog HDL代码如下: `timescale 1ns / 1ps
//-------------------------------------------------------------
// 单级CIC抽取滤波器,滤波器阶数与抽取倍数相同
//-------------------------------------------------------------
module SingleCIC_Decimation
(
input clk, //50MHz系统时钟
input rst, //复位信号
input signed [9:0] din, //采样数据,速率为50MHz
output tvalid, //输出数据有效信号
output signed [12:0] dout //5倍抽取后数据,速率为10MHz
);
reg tvalid_reg;
reg [2:0] cnt; //抽取控制计数器
reg signed [12:0] sum, dout_reg;
always @ (posedge clk or posedge rst)
if (rst) begin
cnt <= 'd0; tvalid_reg <= 1'b0;
sum <= 'd0; dout_reg <= 'd0;
end
else begin
if (cnt == 4) begin //每隔4个数据
tvalid_reg <= 1'b1;
dout_reg <= sum + din; //得到输出结果
cnt <= 'd0;
sum <= 'd0;
end
else begin
tvalid_reg <= 1'b0;
sum <= sum + din; //累加
cnt <= cnt + 1'b1;
end
end
assign dout = dout_reg;
assign tvalid = tvalid_reg;
endmodule
使用MATLAB生成一个0.25MHz的单频信号,写入txt文件。编写testbench读取txt文件对信号抽取滤波
Vivado中仿真结果如下图所示:
可以看到输出数据速率为输入数据速率的1/5,每当有新数据输出时,tvalid信号会置高1个时钟周期。将信号设置为Analog显示方式:
可以看到经过抽取滤波后,数据速率降低,但信号频率没有改变。 CIC内插滤波器的FPGA设计与仿真使用10MHz采样率对0.25MHz的信号进行采样,由五阶CIC滤波器进行5倍内插,将采样率提高至50MHz。根据上文的介绍,内***抽取甚至更容易理解,设计起来也非常简单,设计的Verilog HDL代码如下: `timescale 1ns / 1ps
//-------------------------------------------------------------
// 单级CIC内插滤波器,滤波器阶数与抽取倍数相同
//-------------------------------------------------------------
module SingleCIC_Interpolation
(
input clk, //50MHz系统时钟
input rst, //复位信号
input signed [9:0] din, //采样数据,速率为10MHz
output signed [9:0] dout //5倍内插后数据,速率为50MHz
);
reg signed [9:0] dout_reg;
always @ (posedge clk or posedge rst)
if (rst) dout_reg <= 'd0;
else dout_reg <= din;
assign dout = dout_reg;
endmodule
Vivado中仿真结果如下图所示:
从结果看输入与输出是完全一样的,但实际意义不同,输入数据的速率为10MHz(每5个时钟周期输入一个数据),输出数据的速率为50MHz(每个时钟周期都输出一个数据)。
|