阶段二:FIR滤波器

📐 第09课:FIR直接型结构

FIR滤波器的直接型硬件实现——延迟线与MAC

1. FIR直接型结构详解

直接型(Direct Form)是FIR最自然的实现结构,直接对应差分方程y[n]=Σh[k]x[n-k]。硬件由移位寄存器(延迟线)和乘累加器(MAC)组成。关键路径:1个乘法器延迟+log₂(M+1)个加法器延迟。

y[n] = h[0]x[n] + h[1]x[n-1] + ... + h[M]x[n-M]

🎯 直接型结构特征

2. 流水线优化的直接型FIR

//=============================================
// dsp_fir_pipelined.v
// 流水线直接型FIR
// 加法树+流水线寄存器优化时序
//=============================================
module dsp_fir_pipelined #(
    parameter DATA_WIDTH = 16,
    parameter COEFF_WIDTH = 16,
    parameter TAP = 16,
    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] coeffs [0:TAP-1],
    output reg  signed [OUT_WIDTH-1:0]   data_out,
    output reg                           out_valid
);
    reg signed [DATA_WIDTH-1:0] sr [0:TAP-1];
    reg signed [DATA_WIDTH+COEFF_WIDTH-1:0] products [0:TAP-1];
    reg prod_valid;
    reg signed [OUT_WIDTH-1:0] partial [0:TAP/2-1];
    reg partial_valid;
    integer i;
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            for (i=0;i<TAP;i=i+1) begin sr[i]<=0; products[i]<=0; end
            prod_valid <= 0;
        end else if (data_valid) begin
            sr[0] <= data_in;
            for (i=1;i<TAP;i=i+1) sr[i] <= sr[i-1];
            for (i=0;i<TAP;i=i+1) products[i] <= sr[i]*coeffs[i];
            prod_valid <= 1;
        end else prod_valid <= 0;
    end
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            for (i=0;i<TAP/2;i=i+1) partial[i]<=0;
            partial_valid <= 0;
        end else if (prod_valid) begin
            for (i=0;i<TAP/2;i=i+1)
                partial[i] <= products[2*i]+products[2*i+1];
            partial_valid <= 1;
        end else partial_valid <= 0;
    end
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin data_out<=0; out_valid<=0; end
        else if (partial_valid) begin
            data_out <= 0;
            for (i=0;i<TAP/2;i=i+1) data_out <= data_out+partial[i];
            out_valid <= 1;
        end else out_valid <= 0;
    end
endmodule

3. 循环缓冲区FIR

//=============================================
// dsp_fir_circular.v
// 循环缓冲区FIR——避免数据搬移
//=============================================
module dsp_fir_circular #(
    parameter DATA_WIDTH = 16,
    parameter COEFF_WIDTH = 16,
    parameter TAP = 16,
    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] coeffs [0:TAP-1],
    output reg  signed [OUT_WIDTH-1:0]   data_out,
    output reg                           out_valid
);
    reg signed [DATA_WIDTH-1:0] buffer [0:TAP-1];
    reg [$clog2(TAP)-1:0] write_ptr;
    integer i; reg [$clog2(TAP)-1:0] read_ptr;
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin write_ptr<=0; data_out<=0; out_valid<=1'b0;
            for (i=0;i<TAP;i=i+1) buffer[i]<=0;
        end else if (data_valid) begin
            buffer[write_ptr] <= data_in;
            data_out <= 0;
            for (i=0;i<TAP;i=i+1) begin
                read_ptr = (write_ptr-i)%TAP;
                data_out <= data_out + buffer[read_ptr]*coeffs[i];
            end
            write_ptr <= write_ptr+1'b1;
            out_valid <= 1'b1;
        end else out_valid <= 1'b0;
    end
endmodule

4. 系数量化与资源优化

📊 系数量化对频率响应的影响

量化位数阻带衰减退化适用场景
32位浮点仿真验证
24位定点<1dB高精度音频
16位定点1-3dB通用信号处理
12位定点3-10dB低精度应用

🔧 面积优化技术

技术乘法器数适用场景
对称系数优化(M+1)/2线性相位FIR
时分复用单MAC1低速应用
CSD编码0(用加法)常数系数
子滤波器共享(M+1)/L多通道

5. 练习

📝 练习1:关键路径计算

64阶直接型FIR,乘法器延迟3ns,加法器延迟1ns,求最大时钟频率。若插入2级流水线,频率提升多少?

📝 练习2:循环缓冲验证

用仿真验证dsp_fir_circular.v与dsp_fir_direct.v在相同输入下输出一致。

📝 练习3:时分复用FIR

设计单乘法器时分复用FIR:工作时钟为采样率的TAP倍,每TAP个时钟周期完成一次完整MAC。

📝 练习4:CSD编码

将系数h[k]={0.125,0.375,0.5,0.375,0.125}转换为CSD编码,统计非零位数。

🏆 成就解锁:直接型架构师

✅ 深入理解了FIR直接型结构

✅ 实现了流水线优化的直接型FIR

✅ 掌握了循环缓冲区FIR设计

✅ 理解了关键路径与时序优化

✅ 了解了CSD编码等面积优化技术

✅ 掌握了系数量化对频率响应的影响

6. 直接型FIR的功耗优化

在电池供电的嵌入式系统中,FIR滤波器的功耗是关键指标:

⚡ 低功耗FIR设计技术

7. 直接型FIR的时序分析详解

关键路径分析是高性能FIR设计的核心:

关键路径 = T_setup + T_mult + ⌈log₂(M+1)⌉·T_add + T_wire

其中T_setup为触发器建立时间,T_mult为乘法器延迟,T_add为加法器延迟,T_wire为布线延迟。对于64阶FIR:T_mult=3ns, T_add=1ns, log₂65≈7,关键路径≈3+7×1=10ns,最大频率100MHz。插入流水线后:T_clk≈max(T_mult, T_add+T_setup)≈4ns,最大频率250MHz。

8. CSD编码详解

正则有符号数字(CSD)编码将每个系数表示为最少的非零位,用加法/减法替代乘法器:

CSD规则:不出现连续的非零位,即0→0, 01→01, 011→10̄(1̄表示-1)

📊 CSD编码示例

十进制二进制CSD非零位数
0.1250.00100.00101
0.3750.01100.10̄102
0.50.10000.10001
0.68750.10111.0̄10̄13

6. 直接型FIR的时序分析详解

关键路径分析是高性能FIR设计的核心。对于M阶直接型FIR:

T_critical = T_setup + T_mult + ⌈log₂(M+1)⌉·T_add + T_wire

其中T_setup为触发器建立时间,T_mult为乘法器延迟,T_add为加法器延迟,T_wire为布线延迟。

📊 典型时序分析

阶数M加法树深度T_critical(ns)Fmax(MHz)
1643+4×1=7143
3253+5×1=8125
6473+7×1=10100
12883+8×1=1191

插入2级流水线后:T_clk ≈ max(T_mult, T_add+T_setup) ≈ 4ns,Fmax ≈ 250MHz

7. 功耗优化技术

⚡ 低功耗FIR设计

8. CSD编码详解

正则有符号数字(CSD)编码将系数表示为最少非零位,用加减法替代乘法器:

CSD规则:不出现连续非零位,即01→01, 011→10̄(1̄表示-1)

📊 CSD编码示例与节省效果

十进制二进制CSD非零位数(二进制)非零位数(CSD)节省
0.1250.00100.0010110%
0.3750.01100.10̄10220%
0.68750.10111.0̄10̄1330%
0.43750.01110.100̄13233%
0.93750.11111.000̄14250%

CSD编码对FIR的面积优化:16位系数平均非零位数从8位降至4-5位,加法器数量减半。在FPGA上,每个非零位对应一个LUT+加法器,CSD编码可将DSP slice使用量降低40-60%。

9. 直接型FIR的FPGA实现映射

Xilinx FPGA的DSP48E2 slice天然适配FIR的MAC运算:

🔧 DSP48E2资源映射

FIR组件DSP48功能说明
乘法器25×18 pre-adder+multiplier支持对称预加
累加器48-bit accumulator自动扩展精度
流水线内部3级寄存器最高~500MHz
级联PCOUT→PCIN级联无额外路由延迟

关键:DSP48E2的A:B端口支持25×18乘法,B端口18位可用于系数。内部预加器(B+D)×A支持对称FIR的x[n]+x[n-M]预加,节省一半乘法器。

10. 直接型FIR的验证策略

FIR滤波器的完整验证流程:

  1. 脉冲响应测试:输入δ[n],输出应为h[n],验证系数正确
  2. 频率扫描测试:输入正弦扫频信号,验证通带/阻带特性
  3. 阶跃响应测试:验证直流增益和群延迟
  4. 定点精度验证:比较定点输出与浮点参考的误差
  5. 最坏情况测试:满量程输入检查溢出
  6. 长时间稳定性:运行数百万样本确认无积累误差

11. 补充:FIR直接型结构的进阶主题

FIR直接型结构在进阶应用中还有以下重要主题值得深入研究:

📚 进阶研究方向

12. 与前后课程的关联

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

🔗 课程关联图

13. 设计经验总结

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

📌 关键设计检查清单

13. 设计经验总结

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

📌 关键设计检查清单

13. 设计经验总结

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

📌 关键设计检查清单

13. 设计经验总结

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

📌 关键设计检查清单

13. 设计经验总结

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

📌 关键设计检查清单

13. 设计经验总结

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

📌 关键设计检查清单