1.3 11.3 积分梳状滤波器(CIC)设计 下面介绍FPGA在数字通信中的一个应用实例:用FPGA实现级联积分梳状滤波器(CascadeIntegrator Comb,CIC)。CIC滤波器在数字通信、数字电视中有广泛的应用,特别是广泛应用在全数字接收机中。首先了解一下其应用背景。 1.3.1 11.3.1 应用背景 20世纪80年代中后期,全数字接收机以一种新的概念被提出,它把以前通信接收机的模拟处理部分改为数字处理。最基本的全数字接收机是在接收机的解调前进行A/D转换,用全新的数字方式实现调制信号的解调。 全数字接收机中最重要的组成部分是数字下变频单元。在通信系统中,发射机采用上变频,将已调制的中频信号频谱搬移到射频段;而接收机则使用下变频,将接收到的射频信号频谱搬移到中频,或者零中频。设接收到的射频信号为a(t)cosωct,本地振荡信号为AcosωLt,则将二者相乘可得: (11-4) 用滤波器滤除去和频(ωc+ωL)保留差频(ωc-ωL)即可实现下变频。 数字下变频原理框图如图11-20所示。 其中,x(n)为已数字化后的中频信号;NCO为数控振荡器,用以产生数字正、余弦信号;CIC为积分梳妆滤波器,降低信号速率;HB为半带滤波器,也用来降低速率,按2M次降低速率;FIR为有限长脉冲回应滤波器,主要实现低通滤波,提取信号、滤除噪声。 从图11-20中可以看到,CIC滤波器与HB滤波器共同实现了数字抽取滤波器,从输入的宽带高数据流的数字信号中提取所需的窄带信号,并在低通滤波器的作用下,下变频为数字基带信号。 CIC滤波器是由Hogenauer引入的,已被证明是在高速抽取或插值系统中非常有效的单元。在下变频中,CIC滤波器可以将中频采样的信号按需要变换到基带。 1.3.2 11.3.2 理论算法 CIC滤波器由积分器(Integrator)和梳状(Comb)滤波器级联而成,根据其结构的不同,可分别实现抽取(Decimation)功能和插值(Interpolation)功能。CIC滤波器与半带(halfband)滤波器相结合,可以实现大动态范围、高倍数的信道抽取。一个CIC滤波器由IIR滤波器和FIR滤波器两部分组成。 CIC滤波器的冲激回应具有如下形式: (11-5) 式中,M即为CIC滤波器的阶数(或者抽取因子)。由离散时间信号的傅里叶变换可得频率响应H(w)为: (11-6) 对式(11-6)进行Z变换,可得CIC滤波器的传递函数: (11-7) 其中: (11-8) (11-9) 它们的实现框图如图11-21所示。 (a)积分器的实现框图 (b)梳状器的实现框图 图11-21 CIC滤波器及积分器、梳状器的实现框图 从框图可以看到,CIC滤波器的积分器HI(z)是一类IIR滤波器,但是它没有前馈,而只有回馈部分。梳状滤波器HC(z)又称为简单整系数FIR滤波器,这种滤波器由于每个抽头系数非“0”即“1”,所以仅需延时器和加法器就可以实现。由HC(z)传递函数可得频率响应为: (11-10) 其幅频特性为: (11-11) 如图11-22所示为梳状滤波器的幅频特性(其中M=4)。 图11-22 梳状滤波器的幅频特性 同样,可求积分器HI(z)的频率响应为: HI (11-12) 所以,CIC滤波器的频率总响应为: (11-13) 式中,sinc(x)=sin(x)/x为抽样函数,且sinc(0)=1,所以CIC滤波器在w=0处的幅值为M。CIC滤波器的幅频特性如图11-23所示,随着频率的增大,旁瓣电平不断减少。为了降低旁瓣电平,可以采用多级CIC滤波器级联的办法,例如,采用S级CIC实现的频率响应为: (11-14) 图11-23 CIC滤波器的幅频特性 由于多级CIC滤波器的旁瓣抑制好,因此实际应用都采用多级CIC级联。所以,下节就以三级CIC抽取滤波器为实例进行讲解。 1.3.3 11.3.3 三级CIC抽取滤波器建模 在介绍完CIC滤波器的理论知识后,本节以三级CIC抽取器为例,讨论如何用VerilogHDL语言来实现。设抽取因子为R,滤波器延迟数值为D(典型值是1、2),N为滤波器的级数,则CIC抽取滤波器的传递函数为: (11-15) 由式(11-15)可得典型CIC抽取滤波器的实现框图,如图11-24所示。 如果N=3,则为三级CIC,根据前面的讨论可得本例的实现框图,如图11-25所示。 用FPGA实现CIC抽取滤波器时,还有一个很重要的参数需要确定,那就是寄存器的宽度(或者位数)。只有精心计算寄存器的宽度,才能在运算不溢出的情况下,最大限度地节省FPGA的硬件资源。对于CIC抽取器,最终的梳状器输出增益G等于: (11-16) 在式(11-16)中,R为抽取因子,D为延迟数值,N为滤波器级数。假定我们采用二进制补码,设输入数据宽度为Bin,则内部数据处理的宽度Bout为: Bout (11-17) 本例中,我们采用输入数据宽度为8,N=3,R=32,D=2(也即抽取因子为32,延迟为2的三级CIC),则输出字宽W=8+3log264 =26位,保证不会产生运行时间溢出。因此,我们就可以进一步细化图11-25,如图11-26所示。 在介绍完CIC抽取滤波器的相关细节后,下面给出VerilogHDL的源码。该代码实现了输入数据宽度为8,抽取因子为32,延迟为2的三级CIC,并且输出字宽为26位。 //三级CIC抽取器实例:cic3_decimator.V module cic3_decimator(clk, x_in, y_out); parameter STATE_HOLD = 1'b0, STATE_SAMPLE = 1'b1; input clk; //输入时钟 input [7:0] x_in; //输入8位数据 output [25:0]y_out; //输出26位数据 reg state,derived_clk; reg [4:0] counter; //有限状态机,用于实现下采样 always @(negedge clk) begin: FSM_DECIMATOR case(state) STATE_HOLD: begin if(counter ==31) state <= STATE_SAMPLE; end STATE_SAMPLE: begin ComReg0[0] <= IntReg[2]; state <= STATE_HOLD; end default: state <= STATE_HOLD; endcase if((counter>8)&&(counter<16)) //生成下采样后的时钟 derived_clk <= 1; else derived_clk <= 0; counter <= counter + 1; end wire [25:0]sxtx; //Signextended input assign sxtx ={{18{x[7]}},x}; //符号扩展 reg [7:0] x; //Registeredinput reg [25:0] IntReg[2:0]; //I section0,1 and 2 //积分器实现模块 always @(posedge clk) begin: INTEGRATOR x <= x_in; IntReg[0] <= IntReg[0] + sxtx; IntReg[1] <= IntReg[1] +IntReg[0]; IntReg[2] <= IntReg[2] +IntReg[1]; end reg [25:0]ComReg0[2:0],ComReg1[2:0],ComReg2[2:0],ComReg3; //梳状器实现模块 always @(posedge derived_clk)begin:COMB ComReg0[1] <= ComReg0[0]; ComReg0[2] <= ComReg0[1]; ComReg1[0] <= ComReg0[0] -ComReg0[2]; ComReg1[1] <= ComReg1[0]; ComReg1[2] <= ComReg1[1]; ComReg2[0] <= ComReg1[0] -ComReg1[2]; ComReg2[1] <= ComReg2[0]; ComReg2[2] <= ComReg2[1]; ComReg3 <= ComReg2[0] - ComReg2[2]; end assign y_out = ComReg3; //输出 endmodule 1.3.4 11.3.4 程序说明 在上面的三级CIC抽取器的程序代码中,由下面几个模块组成。 有限状态机模块(FSM):实现下采样功能。设积分器的采样频率为 ,则经过抽取后,梳状器的采样频率降为。本例中R=32。 符号扩展:由于输入是8位数据,而内部数据是26位字宽,所以必须进行符号扩展。 积分器:实现了3个积分器。 梳状器:实现了3个梳状器。 对于上面的实例,其实输出字宽可以取小于26位,这取决于精度要求。例如,如果取9位,则最后一条连续赋值语句作如下修改即可。 assign y_out = ComReg3[25:17]; //输出 接下来,我们对上面的VerilogHDL代码进行验证。首先,我们在MATLAB中输入以下程序。该程序输入一个幅值为100的阶跃信号x(n),经过11.3.3节描述的一个CIC抽取器,输出序列y(m)。如图11-27所示,图(a)是输入x(n),图(b)是输出y(m)。 (a)输入阶跃序列x(n) (b)输出序列y(m) 图11-27 MATLAB下的仿真 M = 2; %延迟数值 N = 3; %滤波器级数 R = 32; %抽取因子 x =100.*ones(1,300); %幅值为100的阶跃序列 q =quantizer([80],'fixed'); % 输入信号属性 y =cicdecimate(M, N, R, x, q); %调用CIC抽取器 然后,对cic3_decimator程序代码进行仿真,仿真结果如图11-28所示(综合、仿真都是在QuartusII软件下完成的)。 |