取以下两个方法,并且不会影响滤波的正确性:
(1) 所采用的数据编码具有如下特点:当从高端溢出时返回到低端,从低端溢出时返回到高端,其实质是对数据求模;
(2) 寄存器所存数值的大小大于,等于整个滤波器最后输出地数值范围。 第一个条件采用二进制补码形式实现(在Modelsim中会自动将负数用二进制补码表示)。
下面分析如何实现第二个条件:
为了得到CIC滤波器的幅频响应,将z?eiw带入系统的传递函数,即式(8),为
i2?F/(MF2)i2?f/M?e了表示方便把z?eiw表示成z?eiw?ei2?F/F1?e的形式,其
中f?F/F2称为相对于F2的归一化频率,将它带入(8)式可得N级CIC滤波器的幅频响应:
sin(?Df)H(f)?Nsin(?f/M)N (13)
从式(13)可知,N级CIC滤波器级联的最大幅度增益为:
G=(DM)N (14)
由于DM的值很大,N级CIC滤波器级联的(DM)N的值也很大,所以在设计过程中为了防止溢出,必须相应的扩大数据的位数,以减少误差。如果B为输入数据的位数,
in那么最大内部位宽为:
B?B?Nlg(DM) (15) out in2其中Nlg(DM)为最大动态范围的增长。为防止数据溢出,最大限度的节省FPGA的
2硬件资源,应该把积分器的积分部分和梳状的寄存器位宽扩展到Bout位[8]。
设计的时候从CIC滤波器的功能要求出发,将该滤波器分为三个部分:积分部分:实现了三个积分器;抽取部分:实现了下采样功能;梳状部分:实现了三个梳状器,再分析各个模块所实现的功能,并对这三个模块进行详细的设计。 4.1 前端设计:
首先对CIC滤波器的各个参数进行设定:滤波器的输入数据为8位,级数N为3,梳状部分的延迟D为2,抽取因子为16 ,并且由(15)式可计算出它的最大内部位宽
10
为23。根据精度要求,输出可以取小于23,本设计中取23位。然后从CIC滤波器的功能要求出发,将该滤波器的输入信号设为以下几个:reset, clk, x_in, 其中reset是复位信号(防止程序运行过程中产生随机数),clk是输入的时钟信号,x_in是所输入的8位的数据。输出信号为:y_out,它表示所输出的23位的数据。则端口列表为:
input reset;
input clk;
input [7:0] x_in;
output [22:0] y_out;
寄存器型的变量可以理解为实际电路中的寄存器,它具有记忆特性,是一种存储元件,在输入信号消失后它可以保持原有的数值不变。寄存器型变量一般使用关键字reg进行定义,并且在定义时可以加入位宽,位宽为1的变量也称为标量,位宽大于1的变量称为矢量。由于在Verilog HDL中默认的变量类型是wire型,所以如果某个变量的类型需要为寄存器型,则必须在程序中加以定义,而且值得注意的是,任何在always块内被赋值的变量都必须是寄存器型[9]。在本设计中,需定义如下变量:
reg derived_clk;
reg[3:0] counter;
reg[22:0] IntReg0[1:0],IntReg1[1:0],IntReg2[1:0],IntReg3; reg[22:0] ComReg0[2:0],ComReg1[2:0],ComReg2[2:0],ComReg3;
4.2 积分器模块设计:
三级的CIC滤波器前面的积分部分是由三个一级的积分器级联而成,是一类IIR滤波器,但是它没有前馈,而只有回馈部分。分别用寄存器:IntReg0[1:0],IntReg1[1:0],IntReg2[1:0]来表示第一,第二,第三个一级积分器,积分器的输出放在寄存器IntReg3中。积分器实现的关键是如何实现输入信号的延时,本设计是通过将输入信号放在寄存器中,经过一个单位的延时以后再调用这个寄存器中的值,从而实现延时的,积分器模块的实现如下: //积分器实现模块
always @(posedge clk) //时钟上升沿有效 begin: INTEGRATOR
//复位时所有的寄存器输出为0
if(!reset)
11
*/
begin
IntReg0[0] <=0; IntReg0[1] <=0; IntReg1[0] <=0; IntReg1[1] <=0; IntReg2[0] <=0; IntReg2[1] <=0; IntReg3 <=0; end
else
begin
IntReg0[0][7:0] <= x_in; //将输入信号赋值给IntReg0的低八位 IntReg0[1] <= IntReg0[0]; /*将IntReg0[0]赋值给IntReg0[1]相当于延时
IntReg1[0] <= IntReg0[1] + IntReg0[0]; IntReg1[1] <= IntReg1[0];
IntReg2[0] <= IntReg1[1] + IntReg1[0]; IntReg2[1] <= IntReg2[0];
IntReg3 <= IntReg2[1] + IntReg2[0]; end
end
4.3 抽取器模块设计:
改变系统的抽样频率有两种方法:其中减少抽样率的过程成为信号的“抽取”,也称为“抽样率压缩”;增加抽样率的过程称为信号的“插值”,亦称为“抽样率扩张”。抽取器的主要作用是转换抽样率,使系统工作在多抽样率状态。本设计中所要用到的是抽样压缩,其定义如下:
当信号的抽样数据量太大时,可以在每A个抽样中取一个,或者说每隔A-1个抽样取出一个,以便减小数据量,A是整数,称为抽取因子,这样的抽取称为整数倍抽取[10]。
本设计中抽取器的实现主要是通过一个计数器来实现的,因为抽取因子为16,所以定义了一个4位的计数器reg [3:0] counter,其具体的实现模块如下:
12
//计数器
always @(posedge clk) begin end
if(!reset)
counter <= 0;
else begin
if(counter>=10) //生成下采样后的时钟 derived_clk = 1; else
derived_clk = 0; counter = counter + 1; end
4.4 梳状器模块设计:
梳状滤波器的积分器是一类FIR滤波器,由于这种滤波器每个抽头系数非“0”,即“1”,因此仅需延时器和加法器就可以实现。它是由三个单级的微分器级联而成的,分别用ComReg0[2:0],ComReg1[2:0],ComReg2[2:0]来表示依次第一,第二,第三个一级的微分器,梳状器的输出放在寄存器ComReg3中。实现它的关键也是延时部分的实现,但是跟积分器不同的是,梳状器的延时是两个时间单位,因此要将信号连续赋值给两个寄存器来实现延时。其具体的实现模块如下: //梳状器实现模块
always @(posedge derived_clk)
begin:COMB if(!reset) begin
ComReg0[0] <= 0; ComReg0[1] <= 0; ComReg0[2] <= 0; ComReg1[0] <= 0;
13
ComReg1[1] <= 0; ComReg1[2] <= 0; ComReg2[0] <= 0; ComReg2[1] <= 0; ComReg2[2] <= 0; ComReg3 <= 0; end
else begin
ComReg0[0] <= IntReg3; 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
end
将上述三个模块综合起来,就形成了一个完整的Verilog HDL的CIC滤波器的程序
见附录2。
5. 在Modelsim环境下的功能仿真:
验证是保证设计在功能上的正确性的一个过程,要对所设计的程序进行仿真验证就要编写一个Testbench文本,即测试平台。简单来说,在仿真的时候Testbench用来产生测试激励给待验证设计(DUV),或者称为待测设计(DUT),同时检查DUV的输出是否与预期的一致,达到验证设计功能的目的。图12为基于Testbench的仿真流程:
14
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库FPGA的CIC滤波器的设计(3)在线全文阅读。
相关推荐: