手把手教你用Verilog实现一个二倍抽取的多相滤波器(附MATLAB系数生成)

张开发
2026/4/19 11:32:41 15 分钟阅读

分享文章

手把手教你用Verilog实现一个二倍抽取的多相滤波器(附MATLAB系数生成)
手把手教你用Verilog实现二倍抽取多相滤波器从MATLAB系数生成到FPGA实战在数字信号处理领域多相滤波器因其高效的数据速率转换能力而备受青睐。想象一下这样的场景你正在处理来自高速ADC的数据流采样率高达100MHz但FPGA的主频限制让你无法实时处理这些数据。这时二倍抽取的多相滤波器就像一位精明的交通指挥员既能有效过滤噪声又能将数据流量减半让后续处理游刃有余。本文将带你从MATLAB系数生成开始逐步构建一个完整的Verilog实现方案特别适合FPGA和数字IC领域的初学者或需要快速上手的工程师。1. 多相滤波器基础与设计准备多相滤波器的核心思想是将一个高阶滤波器分解为多个并行的低阶子滤波器每个子滤波器处理数据流的不同相位。这种结构不仅降低了单个滤波器的复杂度还巧妙地将抽取操作融入滤波过程实现了滤波-抽取的一体化处理。MATLAB系数生成步骤首先确定滤波器规格通带频率fp 0.4*(fs/2)阻带频率fs 0.6*(fs/2)通带波纹0.1 dB阻带衰减60 dB使用firpm函数设计原型低通滤波器% 滤波器参数设置 taps 64; % 滤波器阶数 f [0 0.4 0.6 1]; % 频率边界 a [1 1 0 0]; % 理想幅频响应 w [1 10]; % 通带和阻带权重 % 生成滤波器系数 h firpm(taps-1, f, a, w);对系数进行多相分解% 二相分解 polyphase_coeff reshape(h, 2, []); p0 polyphase_coeff(1,:); % 第一相系数 p1 polyphase_coeff(2,:); % 第二相系数关键参数对比表参数原型滤波器多相分解后阶数6432 (每相)工作频率2a MHza MHz吞吐量2a MSPSa MSPS硬件资源高降低约40%2. 时钟域与数据流设计二倍抽取多相滤波器的精髓在于时钟相位关系的巧妙利用。当原始数据速率为2a MHz时我们使用两个相位相反的a MHz时钟CLK_1和CLK_2来驱动双相滤波器。时钟关系示意图CLK_1: _|‾|_|‾|_|‾|_|‾|_ CLK_2: ‾|_|‾|_|‾|_|‾|_| 采样点: ↑ ↑ ↑ ↑ D0 D1 D2 D3数据分配原理在CLK_1上升沿采样偶数索引数据D0, D2,...到第一相在CLK_2上升沿采样奇数索引数据D1, D3,...到第二相Verilog实现的关键代码段// 时钟生成模块 module clk_gen( input clk_2a, // 原始2a MHz时钟 input rst, output reg clk_a, // a MHz时钟 output clk_1, // 第一相时钟 output clk_2 // 第二相时钟 ); always (posedge clk_2a or posedge rst) begin if(rst) clk_a 1b0; else clk_a ~clk_a; end assign clk_1 clk_a; assign clk_2 ~clk_a; endmodule重要提示在实际FPGA实现中建议使用全局时钟缓冲器(BUFG)来分配时钟信号避免时钟偏移(skew)问题。3. 双相滤波器Verilog实现基于上述时钟方案我们可以构建完整的双相滤波器结构。以下是核心模块的实现顶层模块结构module polyphase_filter_2x( input clk_2a, // 原始高速时钟 input rst, input signed [15:0] data_in, // 输入数据 output reg signed [15:0] data_out // 抽取后输出 ); // 内部信号声明 wire clk_1, clk_2; reg signed [15:0] data_1, data_2; // 实例化时钟生成模块 clk_gen u_clk_gen(.clk_2a(clk_2a), .rst(rst), .clk_1(clk_1), .clk_2(clk_2)); // 第一相滤波器 fir_filter u_fir_p0( .clk(clk_1), .rst(rst), .data_in(data_in), .data_out(data_1) ); // 第二相滤波器 fir_filter u_fir_p1( .clk(clk_2), .rst(rst), .data_in(data_in), .data_out(data_2) ); // 结果相加在CLK_1上升沿 always (posedge clk_1 or posedge rst) begin if(rst) data_out 16d0; else data_out data_1 data_2; end endmoduleFIR滤波器子模块优化技巧采用对称系数结构减少乘法器数量使用流水线技术提高工作频率对乘法结果进行适当位宽截取平衡精度和资源消耗module fir_filter( input clk, input rst, input signed [15:0] data_in, output reg signed [15:0] data_out ); // 滤波器系数存储器从MATLAB生成 parameter COEFF_WIDTH 16; parameter TAPS 32; reg signed [COEFF_WIDTH-1:0] coeff [0:TAPS-1]; initial $readmemb(fir_coeff.txt, coeff); // 延迟线寄存器 reg signed [15:0] delay_line [0:TAPS-1]; // 乘积累加器 integer i; always (posedge clk or posedge rst) begin if(rst) begin for(i0; iTAPS; ii1) delay_line[i] 16d0; data_out 16d0; end else begin // 移位延迟线 for(iTAPS-1; i0; ii-1) delay_line[i] delay_line[i-1]; delay_line[0] data_in; // 乘积累加 reg signed [31:0] acc; acc 0; for(i0; iTAPS; ii1) acc acc delay_line[i] * coeff[i]; data_out acc[30:15]; // 适当截取 end end endmodule4. 仿真验证与调试技巧一个可靠的验证方案对确保设计正确性至关重要。我们构建测试平台来验证滤波器的功能和时序。测试平台关键组件时钟生成模块输入数据激励模拟ADC输出参考模型MATLAB生成的理想输出自动对比检查器module tb_polyphase_filter(); reg clk_2a; reg rst; reg signed [15:0] data_in; wire signed [15:0] data_out; // 实例化被测设计 polyphase_filter_2x uut( .clk_2a(clk_2a), .rst(rst), .data_in(data_in), .data_out(data_out) ); // 时钟生成假设2a100MHz initial begin clk_2a 0; forever #5 clk_2a ~clk_2a; // 10ns周期 end // 测试序列 initial begin // 初始化 rst 1; data_in 0; #100 rst 0; // 发送测试信号例如正弦波 for(integer i0; i1000; ii1) begin #10 data_in $sin(i/10.0)*32767; // 生成正弦波 end // 结束仿真 #1000 $finish; end // 自动检查输出 always (posedge uut.clk_1) begin if(!rst) begin // 这里添加与参考输出的比较逻辑 $display(Output: %d, data_out); end end endmodule常见问题排查指南时序不收敛检查时钟相位关系是否精确添加适当的流水线寄存器降低乘法器工作频率输出数据异常验证系数加载是否正确检查数据位宽和符号处理确认复位逻辑是否彻底资源占用过高尝试使用CSD编码优化乘法器考虑系数对称性减少计算量评估位宽是否可以进一步优化调试技巧在Vivado/Quartus中使用SignalTap/ILA抓取内部信号特别关注时钟边沿与数据采样的对齐关系。5. 性能优化与扩展应用经过基础实现后我们可以从多个维度优化设计资源优化技术系数对称性利用FIR滤波器通常具有对称系数可以合并相同系数的乘法运算// 优化后的乘积累加逻辑针对对称系数 for(i0; iTAPS/2; ii1) begin sum delay_line[i] delay_line[TAPS-1-i]; acc acc sum * coeff[i]; end时分复用乘法器在资源受限情况下单个乘法器分时处理多个乘积CSD编码将系数转换为规范符号位表示用移位和加法替代乘法时序优化技术关键路径分析识别组合逻辑最长的路径流水线插入在适当位置添加寄存器平衡时序操作数重排序优化乘法累加的执行顺序扩展应用场景多通道处理通过时分复用实现多通道滤波可配置抽取率扩展为支持任意有理数倍率转换自适应滤波动态更新滤波器系数不同实现方案对比实现方式资源占用最大频率适用场景直接型FIR高低低阶滤波器转置型FIR中中中等速度要求分布式算法低高高阶高速滤波全并行结构极高极高超高速处理在实际项目中我们曾遇到一个有趣的案例处理40MHz带宽的雷达信号时采用本文介绍的结构仅用100MHz时钟就实现了等效200MHz的数据处理能力。关键在于精确控制两相时钟的相位关系并在加法节点前插入适当的流水线寄存器最终时序裕量达到2.3ns。

更多文章