CIC滤波器的RTL实现(二)Verilog实现

1. 设计需求

这里,我们按照以下要求为例子,设计一个CIC滤波器

输入信号位宽5bits 有符号数
阶数3
降采样率8
差分延迟长度1

通过以上设计要求,可以计算出滤波器的增益为\left ( {8 \times 1} \right )^3=512,最小位宽为5+\left \lceil 3log2(8\times 1) \right \rceil=14 bits

2. RTL代码

这里,由于是一个3阶的cic,从输出的第3个数据开始完成滤波器的建立,这里dout_settle_vld是只得建立后的数据vld。

module sinc3(
  input                 clk             ,
  input                 rst_n           ,
  input signed [4:0]    din             ,
  input                 din_en          ,
  output signed [13:0]  dout            ,
  output reg            dout_vld        ,
  output                dout_settle_vld
);

  reg  signed [13:0] cic_i_in1;
  reg  signed [13:0] cic_i_in2;
  reg  signed [13:0] cic_i_in3;
  reg  signed [13:0] cic_c_in1;
  reg  signed [13:0] cic_c_in1_d;
  wire signed [13:0] cic_c_out1;
  reg  signed [13:0] cic_c_out1_d;
  wire signed [13:0] cic_c_out2;
  reg  signed [13:0] cic_c_out2_d;
  wire signed [13:0] cic_c_out3;


  reg [2:0] downsample_cnt;
  wire downsample_en;
  reg [1:0] settle_cnt;

  //3 stages of integrator
  always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
      cic_i_in1 <= 14'sd0;
    end
    else if(din_en) begin
      cic_i_in1 <= cic_i_in1 + din;
    end
  end

  always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
      cic_i_in2 <= 14'sd0;
    end
    else if(din_en) begin
      cic_i_in2 <= cic_i_in2 + cic_i_in1;
    end
  end

  always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
      cic_i_in3 <= 14'sd0;
    end
    else if(din_en) begin
      cic_i_in3 <= cic_i_in3 + cic_i_in2;
    end
  end

  //downsample
  always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
      downsample_cnt <= 3'd0;
    end
    else if (din_en) begin
      downsample_cnt <= downsample_cnt + 3'd1;
    end
  end

  assign downsample_en = &downsample_cnt & din_en;

  //3-stages of comb
  always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
      cic_c_in1 <= 14'd0;
    end
    else if(downsample_en) begin
      cic_c_in1 <= cic_i_in3;
    end
  end

  always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
      cic_c_in1_d <= 14'd0;
    end
    else if(downsample_en) begin
      cic_c_in1_d <= cic_c_in1;
    end
  end

  assign cic_c_out1 = cic_c_in1 - cic_c_in1_d ;

  always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
      cic_c_out1_d <= 14'd0;
    end
    else if(downsample_en) begin
      cic_c_out1_d <= cic_c_out1;
    end
  end

  assign cic_c_out2 = cic_c_out1 - cic_c_out1_d;

  always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
      cic_c_out2_d <= 14'd0;
    end
    else if(downsample_en) begin
      cic_c_out2_d <= cic_c_out2;
    end
  end

  assign cic_c_out3 = cic_c_out2 - cic_c_out2_d;

  //vld logic
  always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
      dout_vld <= 1'b0;
    end
    else begin
      dout_vld <= downsample_en;
    end
  end

  always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
      settle_cnt <= 2'd0;
    end
    else if(settle_cnt != 2'd2 && dout_vld == 1'b1)
      settle_cnt <= settle_cnt + 2'd1;
  end

  assign dout_settle_vld = (settle_cnt == 2'd2) && (dout_vld == 1'b1);
  assign dout = cic_c_out3;
endmodule

附上testbench

module tb_top;

bit                 clk             ;
bit                 rst_n           ;
bit signed [4:0]    din             ;
bit                 din_en          ;
wire signed [13:0]  dout            ;
wire                dout_vld        ;
wire                dout_settle_vld ;

initial begin
  clk = 1'b0;
  rst_n = 1'b0;
  din = 5'sd0;
  din_en = 1'd0;
  #23;
  rst_n = 1'b1;
  din = 5'd3;
  repeat(100) begin
    @(posedge clk) #1;
    din_en = 1'b1;
    @(posedge clk) #1;
    din_en = 1'b0;
    @(posedge clk) #1;
    @(posedge clk) #1;
    @(posedge clk) #1;
    @(posedge clk) #1;
    @(posedge clk) #1;
  end
end

always #10 clk = ~clk;

sinc3 u_sinc3(
  .clk             (clk            ),
  .rst_n           (rst_n          ),
  .din             (din            ),
  .din_en          (din_en         ),
  .dout            (dout           ),
  .dout_vld        (dout_vld       ),
  .dout_settle_vld (dout_settle_vld)
);

endmodule

3 实验结果

这里给了一个幅度为3的直流输入,滤波器从第三个输出开始保持稳定,并且稳定后的值为1536,输入被放大了512倍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值