阶段三:IIR滤波器

🔁 第13课:IIR滤波器原理

无限冲激响应滤波器——高效率的递归结构

1. IIR滤波器的基本概念

IIR(Infinite Impulse Response)滤波器的输出不仅取决于当前和过去的输入,还取决于过去的输出值(反馈回路),因此冲激响应在理论上是无限长的:

y[n] = Σ(k=0 to M) b[k]·x[n-k] - Σ(k=1 to N) a[k]·y[n-k]

其中b[k]为前馈系数(零点系数),a[k]为反馈系数(极点系数)。系统函数为:

H(z) = Y(z)/X(z) = Σ(k=0 to M) b[k]·z⁻ᵏ / (1 + Σ(k=1 to N) a[k]·z⁻ᵏ) = B(z)/A(z)

IIR的核心特点:有极点!极点位置决定稳定性,极点靠近单位圆则频率响应出现峰值。

2. IIR vs FIR 全面对比

📋 IIR与FIR特性对比

特性FIRIIR
冲激响应有限长无限长(递归衰减)
稳定性始终稳定需极点在单位圆内
线性相位可实现一般不可实现
相同指标阶数高(10-100+)低(4-10)
计算量
系数量化敏感度高(极点偏移危险)
设计方法窗函数/频率采样/等波纹模拟原型+双线性变换
群延迟常数M/2频率相关(非线性)
溢出振荡可能(需饱和算术)
极限环可能(量化引起)

3. IIR滤波器的稳定性

IIR稳定的充要条件:所有极点严格在单位圆内(|p_k|<1)。对于因果系统:

BIBO稳定 ⟺ H(z)的所有极点满足|p_k| < 1 ⟺ Σ|h[n]| < ∞

稳定性判定方法:(1)直接求极点位置;(2)Jury稳定性判据(代数方法,不需要求极点);(3)Schur-Cohn判据。工程中最常用的是确保极点位置远离单位圆。

⚠️ IIR稳定性注意事项

4. Verilog实现:基本IIR滤波器

//=============================================
// dsp_iir_direct1.v
// IIR直接I型滤波器
// y[n] = Σ b[k]*x[n-k] - Σ a[k]*y[n-k]
//=============================================
module dsp_iir_direct1 #(
    parameter DATA_WIDTH = 16,
    parameter COEFF_WIDTH = 16,
    parameter NUM_B = 5,              // 前馈阶数
    parameter NUM_A = 4,              // 反馈阶数
    parameter OUT_WIDTH = 32
)(
    input  wire                          clk,
    input  wire                          rst_n,
    input  wire                          data_valid,
    input  wire signed [DATA_WIDTH-1:0]  data_in,
    input  wire signed [COEFF_WIDTH-1:0] b_coeffs [0:NUM_B-1],
    input  wire signed [COEFF_WIDTH-1:0] a_coeffs [0:NUM_A-1],
    output reg  signed [OUT_WIDTH-1:0]   data_out,
    output reg                           out_valid
);
    reg signed [DATA_WIDTH-1:0]  x_delay [0:NUM_B-1];
    reg signed [OUT_WIDTH-1:0]   y_delay [0:NUM_A-1];
    integer i;

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            for (i = 0; i < NUM_B; i = i + 1) x_delay[i] <= 0;
            for (i = 0; i < NUM_A; i = i + 1) y_delay[i] <= 0;
            data_out <= 0; out_valid <= 1'b0;
        end else if (data_valid) begin
            // 更新输入延迟线
            x_delay[0] <= data_in;
            for (i = 1; i < NUM_B; i = i + 1) x_delay[i] <= x_delay[i-1];

            // 计算输出:前馈-反馈
            data_out <= compute_iir();

            // 更新输出延迟线
            y_delay[0] <= data_out;
            for (i = 1; i < NUM_A; i = i + 1) y_delay[i] <= y_delay[i-1];

            out_valid <= 1'b1;
        end else out_valid <= 1'b0;
    end

    function signed [OUT_WIDTH-1:0] compute_iir;
        reg signed [OUT_WIDTH-1:0] acc;
        reg signed [DATA_WIDTH+COEFF_WIDTH-1:0] prod;
        integer j;
        begin
            acc = 0;
            // 前馈求和
            for (j = 0; j < NUM_B; j = j + 1) begin
                prod = x_delay[j] * b_coeffs[j];
                acc = acc + prod;
            end
            // 反馈求和(减去)
            for (j = 0; j < NUM_A; j = j + 1) begin
                prod = y_delay[j] * a_coeffs[j];
                acc = acc - prod;
            end
            compute_iir = acc;
        end
    endfunction
endmodule

5. Verilog实现:IIR稳定性监测器

//=============================================
// dsp_iir_stability.v
// IIR滤波器稳定性监测器
// 检测输出溢出和极限环振荡
//=============================================
module dsp_iir_stability #(
    parameter DATA_WIDTH = 16,
    parameter OUT_WIDTH = 32,
    parameter THRESHOLD = 30            // 溢出阈值(位数)
)(
    input  wire                          clk,
    input  wire                          rst_n,
    input  wire signed [OUT_WIDTH-1:0]   data_in,
    output reg                           overflow_warn,    // 溢出警告
    output reg                           limit_cycle_warn, // 极限环警告
    output reg                           stable            // 稳定标志
);
    // 溢出检测
    wire sign_bit = data_in[OUT_WIDTH-1];
    wire [OUT_WIDTH-2:0] magnitude = data_in[OUT_WIDTH-2:0];
    wire overflow = (magnitude > (1 << THRESHOLD));

    // 极限环检测:连续N个零输入后输出仍非零
    reg signed [OUT_WIDTH-1:0] prev_out;
    reg [$clog2(100)-1:0] zero_input_cnt;
    reg signed [OUT_WIDTH-1:0] last_nonzero;

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            overflow_warn <= 0;
            limit_cycle_warn <= 0;
            stable <= 1;
            prev_out <= 0;
            zero_input_cnt <= 0;
            last_nonzero <= 0;
        end else begin
            prev_out <= data_in;
            overflow_warn <= overflow;

            // 简化极限环检测
            if (data_in == 0) begin
                zero_input_cnt <= zero_input_cnt + 1;
            end else begin
                zero_input_cnt <= 0;
                last_nonzero <= data_in;
            end

            // 连续100个周期输入为零但输出仍振荡
            if (zero_input_cnt > 50 && data_in != 0)
                limit_cycle_warn <= 1;
            else
                limit_cycle_warn <= 0;

            stable <= !overflow_warn && !limit_cycle_warn;
        end
    end
endmodule

6. IIR滤波器的典型应用

📋 IIR滤波器应用场景

应用IIR类型阶数原因
音频均衡器二阶参数均衡2/阶低延迟、精确峰谷
生物医学滤波Butterworth4-8通带最平坦
控制系统补偿器2-4低延迟、低阶数
语音编码全极点(LP)10-16声道建模
去加重滤波一阶高通1FM广播标准

7. IIR设计方法概述

IIR滤波器的标准设计路线:模拟原型→双线性变换→数字IIR。常用模拟原型:

📋 四种模拟原型

原型特点适用场景
Butterworth通带最平坦通用滤波
Chebyshev I型通带等波纹,阻带单调窄过渡带
Chebyshev II型通带单调,阻带等波纹阻带控制
椭圆(Cauer)通带阻带均等波纹最低阶数

8. 练习

📝 练习1:IIR稳定性

IIR系统H(z)=1/(1-0.9z⁻¹+0.2z⁻²),求极点位置并判断稳定性。

📝 练习2:差分方程计算

y[n]=x[n]+0.5y[n-1],x[n]={1,0,0,0},手动计算y[0]到y[5]。

📝 练习3:FIR vs IIR阶数对比

对于低通滤波器:fs=44.1kHz,通带0-4kHz,阻带5kHz以上,通带波纹0.1dB,阻带衰减60dB。估算FIR和IIR(Butterworth)分别需要的阶数。

📝 练习4:稳定性监测改进

修改dsp_iir_stability.v,添加极点位置在线估计功能。

🏆 成就解锁:IIR探索者

✅ 理解了IIR滤波器的基本原理与系统函数

✅ 掌握了IIR vs FIR的核心区别

✅ 理解了IIR稳定性及其判定方法

✅ 实现了IIR直接I型滤波器

✅ 实现了IIR稳定性监测器

✅ 了解了IIR的典型应用和设计路线

11. 补充:IIR滤波器原理的进阶主题

IIR滤波器原理在进阶应用中还有以下重要主题值得深入研究:

📚 进阶研究方向

12. 与前后课程的关联

本课内容在整个DSP课程体系中处于承上启下的位置:

🔗 课程关联图

13. 设计经验总结

在实际工程中,IIR滤波器原理的设计经验总结如下:(1)始终从系统级需求出发,不要过早陷入实现细节;(2)先用浮点仿真验证算法正确性,再转为定点;(3)系数量化后必须重新验证频率响应;(4)硬件实现前用C/MATLAB模型作为参考;(5)综合后检查时序和资源是否符合预期;(6)板级验证时用已知的测试信号对比参考输出。每一步验证都是必要的,跳过任何一步都可能导致最终的调试时间成倍增加。

📌 关键设计检查清单

13. 设计经验总结

在实际工程中,IIR滤波器原理的设计经验总结如下:(1)始终从系统级需求出发,不要过早陷入实现细节;(2)先用浮点仿真验证算法正确性,再转为定点;(3)系数量化后必须重新验证频率响应;(4)硬件实现前用C/MATLAB模型作为参考;(5)综合后检查时序和资源是否符合预期;(6)板级验证时用已知的测试信号对比参考输出。每一步验证都是必要的,跳过任何一步都可能导致最终的调试时间成倍增加。

📌 关键设计检查清单

13. 设计经验总结

在实际工程中,IIR滤波器原理的设计经验总结如下:(1)始终从系统级需求出发,不要过早陷入实现细节;(2)先用浮点仿真验证算法正确性,再转为定点;(3)系数量化后必须重新验证频率响应;(4)硬件实现前用C/MATLAB模型作为参考;(5)综合后检查时序和资源是否符合预期;(6)板级验证时用已知的测试信号对比参考输出。每一步验证都是必要的,跳过任何一步都可能导致最终的调试时间成倍增加。

📌 关键设计检查清单

13. 设计经验总结

在实际工程中,IIR滤波器原理的设计经验总结如下:(1)始终从系统级需求出发,不要过早陷入实现细节;(2)先用浮点仿真验证算法正确性,再转为定点;(3)系数量化后必须重新验证频率响应;(4)硬件实现前用C/MATLAB模型作为参考;(5)综合后检查时序和资源是否符合预期;(6)板级验证时用已知的测试信号对比参考输出。每一步验证都是必要的,跳过任何一步都可能导致最终的调试时间成倍增加。

📌 关键设计检查清单

13. 设计经验总结

在实际工程中,IIR滤波器原理的设计经验总结如下:(1)始终从系统级需求出发,不要过早陷入实现细节;(2)先用浮点仿真验证算法正确性,再转为定点;(3)系数量化后必须重新验证频率响应;(4)硬件实现前用C/MATLAB模型作为参考;(5)综合后检查时序和资源是否符合预期;(6)板级验证时用已知的测试信号对比参考输出。每一步验证都是必要的,跳过任何一步都可能导致最终的调试时间成倍增加。

📌 关键设计检查清单

13. 设计经验总结

在实际工程中,IIR滤波器原理的设计经验总结如下:(1)始终从系统级需求出发,不要过早陷入实现细节;(2)先用浮点仿真验证算法正确性,再转为定点;(3)系数量化后必须重新验证频率响应;(4)硬件实现前用C/MATLAB模型作为参考;(5)综合后检查时序和资源是否符合预期;(6)板级验证时用已知的测试信号对比参考输出。每一步验证都是必要的,跳过任何一步都可能导致最终的调试时间成倍增加。

📌 关键设计检查清单

13. 设计经验总结

在实际工程中,IIR滤波器原理的设计经验总结如下:(1)始终从系统级需求出发,不要过早陷入实现细节;(2)先用浮点仿真验证算法正确性,再转为定点;(3)系数量化后必须重新验证频率响应;(4)硬件实现前用C/MATLAB模型作为参考;(5)综合后检查时序和资源是否符合预期;(6)板级验证时用已知的测试信号对比参考输出。每一步验证都是必要的,跳过任何一步都可能导致最终的调试时间成倍增加。

📌 关键设计检查清单

13. 设计经验总结

在实际工程中,IIR滤波器原理的设计经验总结如下:(1)始终从系统级需求出发,不要过早陷入实现细节;(2)先用浮点仿真验证算法正确性,再转为定点;(3)系数量化后必须重新验证频率响应;(4)硬件实现前用C/MATLAB模型作为参考;(5)综合后检查时序和资源是否符合预期;(6)板级验证时用已知的测试信号对比参考输出。每一步验证都是必要的,跳过任何一步都可能导致最终的调试时间成倍增加。

📌 关键设计检查清单

13. 设计经验总结

在实际工程中,IIR滤波器原理的设计经验总结如下:(1)始终从系统级需求出发,不要过早陷入实现细节;(2)先用浮点仿真验证算法正确性,再转为定点;(3)系数量化后必须重新验证频率响应;(4)硬件实现前用C/MATLAB模型作为参考;(5)综合后检查时序和资源是否符合预期;(6)板级验证时用已知的测试信号对比参考输出。每一步验证都是必要的,跳过任何一步都可能导致最终的调试时间成倍增加。

📌 关键设计检查清单

13. 设计经验总结

在实际工程中,IIR滤波器原理的设计经验总结如下:(1)始终从系统级需求出发,不要过早陷入实现细节;(2)先用浮点仿真验证算法正确性,再转为定点;(3)系数量化后必须重新验证频率响应;(4)硬件实现前用C/MATLAB模型作为参考;(5)综合后检查时序和资源是否符合预期;(6)板级验证时用已知的测试信号对比参考输出。每一步验证都是必要的,跳过任何一步都可能导致最终的调试时间成倍增加。

📌 关键设计检查清单

13. 设计经验总结

在实际工程中,IIR滤波器原理的设计经验总结如下:(1)始终从系统级需求出发,不要过早陷入实现细节;(2)先用浮点仿真验证算法正确性,再转为定点;(3)系数量化后必须重新验证频率响应;(4)硬件实现前用C/MATLAB模型作为参考;(5)综合后检查时序和资源是否符合预期;(6)板级验证时用已知的测试信号对比参考输出。每一步验证都是必要的,跳过任何一步都可能导致最终的调试时间成倍增加。

📌 关键设计检查清单