在数字信号处理中,抽取(降采样)是常见的操作,但传统方法“先滤波再抽取”会导致计算效率低下,因为滤波器工作在高采样率下。多相抽取滤波(Polyphase Decimation Filter)通过将FIR滤波器分解为多个子滤波器,实现“滤波与抽取一体化”,显著降低计算复杂度,广泛应用于软件无线电、音频处理、图像降采样等领域。
一、多相抽取滤波的原理
1、为什么需要多相抽取滤波?
在数字信号处理中,抽取(Decimation)是最常见的操作之一:将高采样率信号降采样到低采样率,同时通过低通滤波防止混叠。
标准的处理流程是:
高采样率输入 → 抗混叠FIR滤波 → 丢弃多余样本 → 低采样率输出
假设输入采样率为 ( f_s ),抽取因子为 ( M=4 ),滤波器抽头数 ( N=12 )。那么每输入 ( M=4 ) 个样本,我们只保留 1 个输出。但传统的 FIR 滤波器每输入一个样本就要计算全部 12 次乘加,其中 3/4 的计算结果被随后丢弃——这是巨大的浪费。
多相滤波的核心思想:既然每 ( M ) 个输入只输出 1 个,那我们只计算最终会被保留的那部分,将计算量降低为原来的 ( 1/M )。
2、原始 FIR + 抽取
设 FIR 滤波器系数为 (),抽取后的输出为:其中 是抽取因子, 是输出样本索引。
3、多相分解
将求和按模 ( M ) 分组。令 ( n = kM + m' ),其中:
( m' = 0,1,……,M-1 ) 表示“相位”(Phase)
( k = 0,1,……,K-1 ) 表示每组内的抽头序号
代入原公式得:
定义子滤波器(相滤波器):
以及子信号:
则输出可简化为:
4、以 12 抽头、( M=4 ) 为例
原始系数:
( h = [h_0, h_1, h_2, h_3, h_4, h_5, h_6, h_7, h_8, h_9, h_{10}, h_{11}] )
分解为 4 相,每相 3 个抽头:
| 相编号 | 子滤波器系数 | 对应原始系数 |
|---|---|---|
| 相 0 | ( h_0(0), h_0(1), h_0(2) ) | ( h_0, h_4, h_8 ) |
| 相 1 | ( h_1(0), h_1(1), h_1(2) ) | ( h_1, h_5, h_9 ) |
| 相 2 | ( h_2(0), h_2(1), h_2(2) ) | ( h_2, h_6, h_{10} ) |
| 相 3 | ( h_3(0), h_3(1), h_3(2) ) | ( h_3, h_7, h_{11} ) |
每相的计算:最终输出:
二、MATLAB 与 FPGA 算法实现的流程
整个流程分为 MATLAB 算法侧 和 FPGA 硬件侧,两者通过文件交换形成闭环验证:
1、Matlab算法侧
| 步骤 | 任务 | 关键操作 |
|---|---|---|
| 算法建模 | 用浮点验证算法正确性 | fir1()设计滤波器, |
| 定点化分析 | 确定各节点位宽 | fi()定点对象,评估量化噪声 |
| 定点仿真 | 验证定点与浮点误差 | 对比 y_float 与 y_fixed,确保 < 2 LSB |
| 导出数据 | 生成 FPGA 仿真输入 | fprintf()输出 |
| 验证对比 | 读取 FPGA 输出并判定 | load()读取, |
2、FPGA算法侧
| 步骤 | 任务 | 关键操作 |
|---|---|---|
| RTL 设计 | 用 Verilog 实现算法 | 并行结构、流水线、时序逻辑 |
| Testbench | 搭建验证环境 | $readmemh()读输入, |
| 功能仿真 | 验证逻辑正确性 | iverilog / |
| 导出结果 | 生成供 MATLAB 读取的文件 | 十进制文本,方便 load() |
| 综合上板 | Vivado 综合实现 | 时序约束、资源优化、ILA 在线调试 |
三、多相抽取滤波的算法验证
1、Matlab算法实现
Matlab实现功能:
Maltab的流程:
- Step 1: MATLAB运行生成数据(时域+频域)Step 2: Verilog仿真生成 fpga_output.txtStep 3: MATLAB运行验证对比(时域+频域)
2、Matlab算法验证结果
导出滤波器系数(12位有符号):
-7 -1 43 167 344 478 478 344 167 43 -1 -7
多相输出与参考输出最大误差: 0.000000
已导出: fpga_sim_data/input_samples.hex (1024 个样本)
已导出: fpga_sim_data/coef_lut.hex (12个系数)
已导出: fpga_sim_data/ref_output.txt (256 个样本)
FPGA输出样本数 : 256
MATLAB参考数 : 256
最大绝对误差 : 0 (LSB)
平均绝对误差 : 0.00 (LSB)
[PASS] 验证通过!最大误差 0 LSB 在容限内 (<=2)
3、FPGA算法实现
采用多相分解 + 脉动阵列(Systolic Array)实现 :
-
- 12抽头分成4相(抽取因子 M=4),每相 3 个抽头。使用3个处理单元级联形成流水线,每周期完成一相的3次乘加,完成最终累加后,在4周期内累加4相结果,每周期输出1个抽取样本数据延迟链,11级移位寄存器,输出3路数据:sr[0](当前)、sr[5](5 周期前)、sr[10](10 周期前),配合 3 级流水线,通过时间差实现多相数据的选择控制延迟链,3级移位寄存器,将init信号延迟3周期产生ce,用于匹配流水线总延迟并控制输出
4、FPGA算法验证结果
将matlab中产生的正弦混叠测试信号导入到算法模块的输入接口,然后运行仿真,将处理后的数据与matlab中数据进行比对。
148