从零开始动手做Verilog实验--04--11阶FIR滤波器

一、什么是11阶FIR滤波器?

1.FIR滤波器(Finite Impulse Response Filter)的中文名叫做有限长单位冲激响应滤波器

2.它的作用就是对输入的数字信号进行"加工",比如滤除不需要的噪音,或者提取特定频率的信号。

3.看代码更简单

二、代码

1.FIR的代码:

a.构建延迟线(数据缓存):代码利用 tap0 到 tap10 这组寄存器,将输入信号 x 逐级向后传递,从而在内部同时保存了当前及过去10个时刻的采样数据,为滤波计算提供完整的历史数据窗口。

b.利用对称性简化计算:通过 t0 到 t5 的赋值操作,将对称位置的抽头数据(如首尾的 tap0 和 tap10)进行两两相加。这种预处理利用了线性相位FIR滤波器的对称特性,有效减少了后续乘法器的使用数量。

c.采用移位相加代替乘法:在计算累加和 sum 时,代码完全避开了硬件资源消耗极大的乘法运算符,而是通过巧妙的位移(<<)和位拼接({})操作来凑出特定的滤波系数(如 16.875、-11.25 等),极大地优化了硬件面积和运算速度。

拆解 t1 的计算逻辑:

t1 << 4:左移 4 位 ,也就是 乘以 16。

{t17, t17:1}:这是算术右移 1 位(最高位补符号位) ,也就是 乘以 0.5。

{t17, t17, t17:2}:这是算术右移 2 位 ,也就是 乘以 0.25。

{t17, t17, t17, t17:3}:这是算术右移 3 位 ,也就是 乘以 0.125。

把它们加起来:

总系数 = 16+0.5+0.25+0.125=16.875

d.位宽扩展与结果输出:最终的计算结果经过 16 位寄存器 sum 暂存,并通过符号位扩展的方式(将最高位重复拼接)赋值给 16 位输出端口 y,确保了有符号定点数在位宽转换过程中的数值准确性。

c 复制代码
`timescale 1ns / 1ps


module FIR_11(

input clk         ,
input [7:0]x           ,
output reg[15:0] y


    );
    
    reg [15:0]  sum;
    reg [7:0] tap0          ;
    reg [7:0] tap1          ;
    reg [7:0] tap2          ;
    reg [7:0] tap3          ;
    reg [7:0] tap4          ;
    reg [7:0] tap5          ;
    reg [7:0] tap6          ;
    reg [7:0] tap7          ;
    reg [7:0] tap8          ;
    reg [7:0] tap9          ;
    reg [7:0] tap10         ;
    reg [7:0] tap11         ;
                            
    reg [7:0] t0       ;
    reg [7:0] t1       ;
    reg [7:0] t2       ;
    reg [7:0] t3       ;
    reg [7:0] t4       ;
    reg [7:0] t5       ;
    
    
    always @(posedge clk)
    begin
    //-------------------------
        t0<=tap5;
        t1<=tap4+tap6;
        t2<=tap3+tap7;
        t3<=tap2+tap8;
        t4<=tap1+tap9;
        t5<=tap0+tap10;
   
    //------------------
        tap10<=tap9;
        tap9<=tap8;
        tap8<=tap7;
        tap7<=tap6;
        tap6<=tap5;
        tap5<=tap4;
        tap4<=tap3;
        tap3<=tap2;
        tap2<=tap1;
        tap1<=tap0;
        tap0<=x;
    
    //---------------------------------
    
    sum<=(t1<<4)+{t1[7],t1[7:1]}+{t1[7],t1[7],t1[7:2]}+
{t1[7],t1[7],t1[7],t1[7:3]}-(t2<<3)-(t2<<2)+t2-{t2[7],t2[7],t2[7:2]}
+(t3<<2)+t3+{t3[7],t3[7],t3[7:2]}+{t3[7],t3[7],t3[7],t3[7],t3[7:4]}
+{t3[7],t3[7],t3[7],t3[7],t3[7],t3[7:5]}
-t4-{t4[7],t4[7:1]}-{t4[7],t4[7],t4[7],t4[7:3]}
+{t5[7],t5[7:1]}-{t5[7],t5[7],t5[7],t5[7],t5[7],t5[7:5]}
+(t0<<7)-((t0<<2)<<2)-(t0<<2)+{t0[7],t0[7:1]}
+{t0[7],t0[7],t0[7:2]}+{t0[7],t0[7],t0[7],t0[7],t0[7:4]};
    
    
    
    
    y<={sum[15],sum[15],sum[15],sum[15],sum[15],sum[15],sum[15],sum[15:7]};
    
  
    
    end

   
endmodule

仿真测试代码:

c 复制代码
`timescale 1ns / 1ps

module tb_FIR_11;

    reg         clk;
    reg  [7:0]  x;
    wire [15:0] y;

    FIR_11 u_FIR_11 (
        .clk(clk),
        .x(x),
        .y(y)
    );

    initial begin
        clk = 0;
        forever #5 clk = ~clk;
    end

    initial begin
        x = 8'd0;
        
        #20;

        #10 x = 8'd127; 
        #10 x = 8'd0;   
        #10 x = 8'd0;
        #10 x = 8'd0;
        
        #200;

        #10 x = 8'd50;
        #200;

        #10 x = -8'd50; 
        #200;
        #10 x = 8'd100;
        #200;

        repeat (20) begin
            #10 x = $random % 256; 
        end

        #100;
        $stop;
    end


endmodule

三、仿真

相关推荐
1560820721915 小时前
JFMRFVU3P5G的bit正常,但烧录mcs程序后加载异常
fpga开发
狂奔蜗牛(bradley)15 小时前
把 EtherCAT 初始化从 FPGA 搬到 ARM:命令通道的接口设计与11个坑
arm开发·人工智能·fpga开发·架构
女神下凡2 天前
芯参谋(37):EEPROM_电路设计指南
arm开发·单片机·嵌入式硬件·fpga开发·设计规范
szxinmai主板定制专家3 天前
工业视觉新思路:FPGA图像预处理+RK NPU推理,实现高速缺陷检测
人工智能·嵌入式硬件·fpga开发·rk3576+codesys
FPGA小徐3 天前
【硬件实战】立创 EDA 绘制 TF/SD 卡模块电路|SPI 模式原理图 + 阻抗匹配 + PCB 布局布线全教程
单片机·嵌入式硬件·fpga开发
狂奔蜗牛(bradley)3 天前
EtherCAT DC 分布式时钟同步的 ModelSim 仿真:从帧模板到从站行为建模
人工智能·嵌入式硬件·fpga开发·架构
ALINX技术博客3 天前
8 通道同步采样 ADC!AN706 波形显示实验 【FPGA黑金云课堂】
fpga开发
szxinmai主板定制专家4 天前
RK3568+FPGA+CODESYS异构控制方案:赋能半导体设备与工业自动化升级
人工智能·fpga开发·自动化·rk3576·半导体设备
辰丁电子4 天前
allegro入门教程-菜单栏Logic
fpga开发·pcb设计·pcb工艺·layout·pcb layout
FPGA小徐5 天前
数字IC/FPGA设计基础_ILA原理与使用
fpga开发