m基于FPGA的积分梳状CIC滤波器verilog设计

目录

1.算法描述

2.仿真效果预览

3.verilog核心程序

4.完整FPGA


1.算法描述

积分梳状滤波器,是指该滤波器的冲激响应具有如下形式:

其物理框图如图所示:

可见,CIC滤波器是由两部分组成:累积器H1和H2梳状滤波器的级联

       现若假设用N级CIC滤波器来代替,每一级的滤波器系数长度为R,每一级的差分延迟为M,抽取数为R,那么可以得到CIC抽取滤波器结构图:

 

       可以看到,N级CIC滤波器在功能上相当于N级完全相同的FIR滤波器的级联。如果按传统的FIR滤波器方式实现,那么N级FIR滤波器的每一级都需要RM个存储单元和一个累加器,但如果用CIC方式实现,那么N级CIC滤波器的每一级只需要M个存储单元。

       通常,由于CIC滤波器的传统结构需要大量的延迟单元,这会大大增加系统的硬件资源消耗,所以,在一般情况下,CIC滤波器采用的设计结构式Hogenauer结构形式,该结构形式如下所示:

 采用这种结构之后,大大降低了系统延迟单元资源。

    这里设计的五级CIC滤波器。那么其基本结构如上图所示,在降采样的左右都有五个延迟单元。

但是在CIC滤波的时候,会导致输出的位宽大大增加,但是如果单独对中间的处理信号进行截位,这会导致处理精度不够,从而影响整个系统的性能,所以,这里我们首先将输入的信号进行扩展。

由于我们输入的中频信号通过ADC是位宽为14,在下变频之后,通过截位处理,其输出的数据仍为14位,所以,我们将CIC滤波的输入为14位,但是考虑到处理中间的益处情况以及保证处理精度的需要,我们首先将输入位宽扩展为40位,从而保证了处理精度以及溢出的情况。

基于FPGA的5级CIC滤波器的设计与实现

       这里首先说明一下为什么使用的级别是5级。从硬件资源角度考虑,CIC滤波器的级数太高,会导致最终输出的数据位宽很大,通过简单的验证,当CIC的级数大于5的时候,输出的位宽>50。这显然会导致硬件资源的大量占用,如果CIC级数太小,比如1,2级。这在其处理效果上没有任何意义,基本无法达到预计的效果,通过仿真分析,一般情况下,选择4级,5级比较合理,因此,这里我们选择5级的CIC滤波器。

       5级滤波器的基本结构为:

2.仿真效果预览

本系统进行了两个平台的开发,分别是:

Vivado2019.2

Quartusii18.0+ModelSim-Altera 6.6d  Starter Edition

其中Vivado2019.2仿真结果如下:

 

 

 

Quartusii18.0+ModelSim-Altera 6.6d  Starter Edition的测试结果如下:

 

3.verilog核心程序

module cic_top(
               i_clk,  //input clock
					i_rst,  //system reset
					i_din,  //the input datas
					o_clk16, //the clock 8 clock 
					o_dout  //the output of CIC 
              );
 
parameter WIDTH = 48;				  
				  
input            i_clk;
input            i_rst;
input[13:0]      i_din;
output           o_clk16;
output[WIDTH-1:0]o_dout;				  
				  				  
wire[WIDTH-1:0] result01 ;
wire[WIDTH-1:0] result02 ;
wire[WIDTH-1:0] result03 ;
wire[WIDTH-1:0] result04 ;
wire[WIDTH-1:0] result05 ;
wire[WIDTH-1:0] adders;
 
assign adders = {i_din[13],i_din[13],i_din[13],i_din[13],i_din[13],i_din[13],i_din[13],i_din[13],
                 i_din[13],i_din[13],i_din[13],i_din[13],i_din[13],i_din[13],i_din[13],i_din[13],
                 i_din[13],i_din[13],i_din[13],i_din[13],i_din[13],i_din[13],i_din[13],i_din[13],
                 i_din[13],i_din[13],i_din[13],i_din[13],i_din[13],i_din[13],i_din[13],i_din[13],
                 i_din[13],i_din[13],i_din};//spread the signal 
 
 
//level 1
//level 1	
cic_jifen cic_jifen_u1(
                      .i_clk  (i_clk),
					       .i_rst  (i_rst),
					       .i_din  (adders),
					       .o_dout (result01)
                      );
 
 
 
 
//level 2
//level 2	
cic_jifen cic_jifen_u2(
                      .i_clk  (i_clk),
					       .i_rst  (i_rst),
					       .i_din  (result01),
					       .o_dout (result02)
                      );
							 
//level 3	
//level 3
cic_jifen cic_jifen_u3(
                      .i_clk  (i_clk),
					       .i_rst  (i_rst),
					       .i_din  (result02),
					       .o_dout (result03)
                      );
 
 
//level 4	
//level 4	
cic_jifen cic_jifen_u4(
                      .i_clk  (i_clk),
					       .i_rst  (i_rst),
					       .i_din  (result03),
					       .o_dout (result04)
                      );
 
 
 
//level 5	
//level 5
cic_jifen cic_jifen_u5(
                      .i_clk  (i_clk),
					       .i_rst  (i_rst),
					       .i_din  (result04),
					       .o_dout (result05)
                      );
 
 
//================================================================
//================================================================
 
reg[3:0]cnt = 4'b00000;
always @(posedge i_clk or posedge i_rst)
begin
     if(i_rst)
	  begin
	  cnt <= 4'b0000;
	  end
else begin
     cnt <= cnt + 4'b0001;
     end
end
assign o_clk16 = cnt[3];
 
//================================================================
 
wire[WIDTH-1:0] result11 ;
wire[WIDTH-1:0] result12 ;
wire[WIDTH-1:0] result13 ;
wire[WIDTH-1:0] result14 ;
wire[WIDTH-1:0] result15 ;
 
 
//level 1
//level 1
cic_chaf cic_chaf_u1(
                    .i_clk  (o_clk16),
					     .i_rst  (i_rst),
					     .i_din  (result05),
					     .o_dout (result11)
                    );
 
//level 2
//level 2
cic_chaf cic_chaf_u2(
                    .i_clk  (o_clk16),
					     .i_rst  (i_rst),
					     .i_din  (result11),
					     .o_dout (result12)
                    );
						  
//level 3
//level 3
cic_chaf cic_chaf_u3(
                    .i_clk  (o_clk16),
					     .i_rst  (i_rst),
					     .i_din  (result12),
					     .o_dout (result13)
                    );
						  
//level 4
//level 4
cic_chaf cic_chaf_u4(
                    .i_clk  (o_clk16),
					     .i_rst  (i_rst),
					     .i_din  (result13),
					     .o_dout (result14)
                    );
//level 5
//level 5
cic_chaf cic_chaf_u5(
                    .i_clk  (o_clk16),
					     .i_rst  (i_rst),
					     .i_din  (result14),
					     .o_dout (result15)
                    );
 
assign o_dout = result15;
				  
endmodule
01_115m

4.完整FPGA

V

  • 0
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我爱C编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值