16阶FIR低通滤波器 Verilog Quartus

名称:16阶FIR低通滤波器 Verilog Quartus

软件:Quartus

语言:Verilog

功能介绍

该工程实现了一个16阶线性相位FIR低通滤波器,输入为16位有符号采样数据,支持连续数据流处理,并通过in_valid和out_valid信号标识输入与输出样本的有效周期。模块使用低有效异步复位,可在系统启动时清零17级样本移位寄存器、计数器和输出寄存器。 滤波器针对44.1 kHz采样率和4 kHz截止频率进行设计,适合音频信号中的高频噪声抑制。测试平台产生1 kHz与10 kHz正弦分量叠加的输入信号,仿真观察到输出在初始填充阶段后趋于平滑,低频成分得到保留,高频成分受到衰减。 工程采用Q11定点系数,9个独立系数由17个对称抽头归约得到,在保证数值精度的同时减少乘法器数量。Quartus工程和ModelSim仿真文件可用于继续综合、波形分析及参数调整。

运行环境

开发语言为Verilog,工程使用Intel Quartus进行项目管理、综合和RTL实现,仿真环境为ModelSim。工程顶层设计名为fir16_lp_filter,配套测试模块为fir16_lp_tb。设计不依赖特殊厂商IP,主要使用标准Verilog时序逻辑、数组寄存器、定点乘法和加法运算,便于在支持Verilog的FPGA开发环境中继续验证。

设计思路

本设计面向44.1 kHz采样率、4 kHz截止频率的音频低通处理场景,采用MATLAB窗函数法生成16阶线性相位FIR滤波器。滤波器具有17个抽头,使用Hamming窗在阻带衰减和过渡带宽度之间取得折中,并将浮点系数量化为Q11格式,便于在Verilog中使用定点乘加完成实时处理。 硬件结构充分利用线性相位FIR系数的对称性,将17个抽头归并为8组对称样本和1个中心样本,只需9路乘法运算即可完成卷积。输入样本通过17级移位寄存器保存,乘积采用28位有符号数据表示,累加阶段扩展到32位,最后算术右移11位恢复Q11数值并截取16位输出。sample_cnt用于判断移位寄存器是否完成填充,保证out_valid仅在获得完整滤波窗口后有效。

模块结构

工程顶层模块为fir16_lp_filter,主要由17级有符号样本移位寄存器、sample_cnt输入计数器、对称抽头求和网络、9路定点乘法器、32位累加器、Q11算术右移和输出时序控制组成。fir16_lp_tb作为仿真测试模块,负责产生时钟、复位和双频率叠加输入信号,并观察din、dout、in_valid及out_valid等信号。 数据路径中,x[0]保存最新输入样本,x[16]保存最旧样本;s0至s7分别对应8组对称抽头之和,center对应中心抽头。p0至p8完成乘法后进入符号扩展累加器,acc_shift完成定点缩放。qpf、qws、qsf等Quartus工程文件以及生成的综合数据库和ModelSim工作库共同构成可复现的设计环境。

演示视频

配套演示视频展示了16阶FIR低通滤波器的运行过程,可结合工程文件观察输入、输出及有效信号的时序关系。视频中的连续数据流场景对应ModelSim测试平台产生的滤波验证过程,便于快速了解模块复位、数据装载和输出稳定阶段。

仿真图/仿真说明/设计文档图片

工程配套设计文档包含FIR滤波器理论、MATLAB系数设计与Q11量化过程、Verilog结构说明、Quartus综合结果以及ModelSim仿真分析。文档图片覆盖频率响应、系数数据、RTL结构和输入输出波形,可用于对照理解滤波器填充阶段、连续数据处理及高频抑制效果。

16阶FIR低通滤波器 Verilog Quartus 设计文档图片 image1.png

16阶FIR低通滤波器 Verilog Quartus 设计文档图片 image2.png

16阶FIR低通滤波器 Verilog Quartus 设计文档图片 image4.png

16阶FIR低通滤波器 Verilog Quartus 设计文档图片 image5.png

16阶FIR低通滤波器 Verilog Quartus 设计文档图片 image6.png

16阶FIR低通滤波器 Verilog Quartus 设计文档图片 image7.png

16阶FIR低通滤波器 Verilog Quartus 设计文档图片 image8.png

16阶FIR低通滤波器 Verilog Quartus 设计文档图片 image9.png

16阶FIR低通滤波器 Verilog Quartus 设计文档图片 image1.png

16阶FIR低通滤波器 Verilog Quartus 设计文档图片 image2.png

16阶FIR低通滤波器 Verilog Quartus 设计文档图片 image3.png

16阶FIR低通滤波器 Verilog Quartus 设计文档图片 image4.png

16阶FIR低通滤波器 Verilog Quartus 设计文档图片 image5.png

16阶FIR低通滤波器 Verilog Quartus 设计文档图片 image6.png

部分代码

以下展示顶层模块 fir16_lp_filter 的部分代码,完整源码请下载压缩包查看。

module fir16_lp_filter(
    input wire clk,                    // 时钟信号
    input wire rst_n,                  // 复位信号(低有效)
    input wire in_valid,               // 输入数据有效标志
    input wire signed [15:0] din,      // 16位有符号输入数据
    output reg out_valid,              // 输出数据有效标志
    output reg signed [15:0] dout      // 16位有符号滤波输出
);

// 存放最近17个输入样本的移位寄存器
// x[0]为最新采样,x[16]为最旧采样
reg signed [15:0] x[0:16];

// 计数器:统计已经输入的样本数,用于判断滤波器是否“填满”
reg [4:0] sample_cnt;

// 用于for循环索引的整数变量
integer i;

// 9个独立的Q11格式系数(12位有符号数)
// 由于FIR系数对称,共有17个系数,这里只写出前9个
localparam signed [11:0] C0 = -7;
localparam signed [11:0] C1 = -8;
localparam signed [11:0] C2 = -7;
localparam signed [11:0] C3 = 14;
localparam signed [11:0] C4 = 69;
localparam signed [11:0] C5 = 159;
localparam signed [11:0] C6 = 264;
localparam signed [11:0] C7 = 349;
localparam signed [11:0] C8 = 382;

// 8对对称抽头之和,以及中心抽头
// 这样可以用“先加后乘”的方式,减少乘法器数量
wire signed [15:0] s0 = x[0] + x[16];
wire signed [15:0] s1 = x[1] + x[15];
wire signed [15:0] s2 = x[2] + x[14];
wire signed [15:0] s3 = x[3] + x[13];
wire signed [15:0] s4 = x[4] + x[12];
wire signed [15:0] s5 = x[5] + x[11];
wire signed [15:0] s6 = x[6] + x[10];
wire signed [15:0] s7 = x[7] + x[9];
wire signed [15:0] center = x[8];

// 每对和/中心抽头与对应系数相乘
// 输入为16位与12位相乘,乘积理论上需要28位
wire signed [27:0] p0 = s0 * C0;
wire signed [27:0] p1 = s1 * C1;
wire signed [27:0] p2 = s2 * C2;
wire signed [27:0] p3 = s3 * C3;
wire signed [27:0] p4 = s4 * C4;
wire signed [27:0] p5 = s5 * C5;
wire signed [27:0] p6 = s6 * C6;
wire signed [27:0] p7 = s7 * C7;
wire signed [27:0] p8 = center * C8;

// 将28位乘积符号扩展到32位后相加
// 这样可以安全地累加9路乘积,避免溢出
wire signed [31:0] acc =
    {{4{p0[27]}}, p0} +
    {{4{p1[27]}}, p1} +
    {{4{p2[27]}}, p2} +
    {{4{p3[27]}}, p3} +
    {{4{p4[27]}}, p4} +
    {{4{p5[27]}}, p5} +
    {{4{p6[27]}}, p6} +
    {{4{p7[27]}}, p7} +
    {{4{p8[27]}}, p8};

// 对累加结果做算术右移11位,相当于除以2^11
// 对应MATLAB中Q11系数缩放,最后截断到16位输出
wire signed [31:0] acc_shift = acc >>> 11;

// 时序逻辑:移位寄存器更新、计数器更新以及输出寄存
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        // 异步复位:清零所有寄存器
        for (i = 0; i <= 16; i = i + 1) begin
            x[i] <= 16'sd0;
        end
        sample_cnt <= 5'd0;
        dout <= 16'sd0;
        out_valid <= 1'b0;
    end else begin
        // 有新数据输入时,移位寄存器整体右移一位,x[0]装入din
        if (in_valid) begin
            for (i = 16; i > 0; i = i - 1) begin
                x[i] <= x[i - 1];
            end
            x[0] <= din;

            // 统计输入过的样本数,最多加到17
            if (sample_cnt != 5'd17) begin
                sample_cnt <= sample_cnt + 1'b1;
            end
        end

        // 将移位后的卷积结果输出,截取低16位
        dout <= acc_shift[15:0];

        // 当滤波器“填满”并且当前周期有有效输入时,输出才视为有效
        if (sample_cnt >= 5'd16 && in_valid) begin
            out_valid <= 1'b1;
        end else begin
            out_valid <= 1'b0;
        end
    end
end

endmodule

代码文件(付费下载)

📥 付费后此处显示完整工程压缩包下载链接。
1、代码文件需要付费后才可见。
2、支付问题请联系微信公众号客服。
3、优质Verilog/VHDL代码资源,所见即所得。
Verilog/VHDL资源下载 » 16阶FIR低通滤波器 Verilog Quartus

注册为本站会员,充值100得150,详情咨询客服

目前为止共有 *** 位优秀的会员加入! 立刻加入会员