FPGA教程系列-Vivado中串行FIR设计(非FIR核)
FPGA教程系列-Vivado中串行FIR设计(非FIR核)
什么是FIR滤波器
Finite Impulse Response Filter, 有限冲激响应滤波器,是数字信号处理里最常用、最基础、也最稳定的一类滤波器。“只有零点,没有极点”的滤波器:输出只依赖有限个过去和当前的输入样本,不依赖以前的输出,因此系统总是稳定的。FIR 滤波器是有限长单位冲击响应滤波器。直接型结构如下:

FIR 滤波器本质上就是输入信号与单位冲击响应函数的卷积,表达式如下:

冲激响应(滤波器系数)
h[n] 是FIR滤波器的冲激响应,即滤波器对单位冲激信号的响应序列。h[n]直接对应系数b_n(如h[0]=b₀, h[1]=b₁, …),用于加权输入信号及其延迟值。
通俗理解:h是滤波器的“权重”,决定了滤波器的特性(如低通、高通等)。
延迟算子
z⁻¹ 是Z变换中的延迟算子,表示信号延迟一个采样周期。通俗理解:z⁻¹是“记忆单元”,用于存储输入信号的过去值,供后续加权计算。
Matlab仿真滤波器
FIR滤波器有好几种形式,简单的用matlab程序,仿真出一组系数:
clc;
clear;
close all;% 滤波器参数
order = 10; % 滤波器阶数 (系数个数 = order + 1)
cutoff = 0.4; % 截止频率 (归一化)% 1. 使用汉明窗设计
h_hamming = fir1(order, cutoff, 'low', hamming(order+1));% 2. 使用汉宁窗设计
h_hanning = fir1(order, cutoff, 'low', hanning(order+1));% 3. 使用布莱克曼窗设计 (旁瓣衰减更好,但过渡带更宽)
h_blackman = fir1(order, cutoff, 'low', blackman(order+1));% 绘制频率响应进行比较
figure;
freqz(h_hamming, 1, 1024);
hold on;
freqz(h_hanning, 1, 1024);
freqz(h_blackman, 1, 1024);
title('不同窗函数设计的低通滤波器频率响应');
legend('Hamming', 'Hanning', 'Blackman');
grid on;%量化参数
h_x = round(1023*h_hanning) %

运行以后可以生成一组参数:

这个就是可以在vivado中使用的参数。
Vivado新建工程
有了参数以后,就可以在vivado中建立工程,用单纯的Verilog来编写程序的话,会有很多重复的部分,而System Verilog可以实现参数化的操作,因此这部分选用System Verilog来进行编写。
建立Top文件,fir_top.sv:
`timescale 1ns / 1psmodule fir_top #(// --- 参数定义 ---parameter TAPS = 11, // 滤波器阶数parameter DATA_IN_W = 2, // 输入数据位宽parameter COEF_W = 14, // 系数位宽 (与原IP核匹配)parameter DATA_OUT_W = 20 // 输出数据位宽 (16+ceil(log2(11))=20)
)(input i_clk,input i_rst,input signed [DATA_IN_W-1:0] i_din,output signed [DATA_OUT_W-1:0] o_dout
);// --- 11阶滤波器系数定义 ---// 0, -19, -32, 71, 288, 407, 288, 71, -32, -19, 0localparam signed [COEF_W-1:0] COEF [0:TAPS-1] = '{14'd0, 14'sd19, 14'sd32, 14'd71, 14'd288, 14'd407,14'd288, 14'd71, 14'sd32, 14'sd19, 14'd0};// 注意:Verilog中负数需要用'sd声明,或者在位宽前加s,如14'sd19// --- 延迟链 (移位寄存器) ---reg signed [DATA_IN_W-1:0] x_reg [0:TAPS-1];integer i;always @(posedge i_clk or posedge i_rst) beginif (i_rst) beginfor (i = 0; i < TAPS; i = i + 1) beginx_reg[i] <= {DATA_IN_W{1'b0}};endend else beginx_reg[0] <= i_din;for (i = 1; i < TAPS; i = i + 1) beginx_reg[i] <= x_reg[i-1];endendend// --- 乘法器输出线网数组 ---wire signed [15:0] r [0:TAPS-1]; // 假设乘法器IP核输出为16位// --- 使用 generate 循环实例化乘法器 ---genvar g;generatefor (g = 0; g < TAPS; g = g + 1) begin : mul_genmulter multer_inst (.CLK(i_clk),.A(x_reg[g]), // 连接到对应的延迟寄存器.B(COEF[g]), // 连接到对应的系数.SCLR(i_rst),.P(r[g]) // 输出到对应的线网);endendgenerate// --- 求和 ---assign o_dout = r[0] + r[1] + r[2] + r[3] + r[4] + r[5] + r[6] + r[7] + r[8] + r[9] + r[10];endmodule
乘法器采用的是vivado的IP核,可以参考以前的设计,进行设计。注意是带复位信号的乘法器。
top写完以后可以编写testbench文件:
`timescale 1ns / 1psmodule test_fir;
reg i_clk;
reg i_rst;
reg signed[1:0]i_din;
wire signed[15:0]o_dout;fir_tops fir_tops_u(.i_clk (i_clk),.i_rst (i_rst),.i_din (i_din),.o_dout (o_dout)
);// 时钟生成:周期10ns,频率100MHz
always #5 i_clk = ~i_clk;initial
begin// 初始化i_clk = 1'b1;i_rst = 1'b1;i_din = 2'b00;// 复位持续100ns#100 i_rst = 1'b0;// ==================== 测试序列设计 ====================// 1. 阶跃响应测试 (0 -> +1)$display("=== 阶跃响应测试开始 ===");#50 i_din = 2'b01; // 输入+1,观察滤波器如何从0上升到稳态值#200; // 持续200ns,观察完整的上升过程// 2. 负阶跃响应测试 (+1 -> -1)$display("=== 负阶跃响应测试开始 ===");i_din = 2'b11; // 输入-1,观察滤波器的负向响应#200; // 持续200ns// 3. 回零测试 (-1 -> 0)$display("=== 回零测试开始 ===");i_din = 2'b00; // 输入0,观察滤波器回到零点#200; // 持续200ns// 4. 单脉冲测试 (0 -> +1 -> 0)$display("=== 单脉冲测试开始 ===");i_din = 2'b01; // 输入单个正脉冲#20; // 脉冲宽度20nsi_din = 2'b00; // 回到0#200; // 观察脉冲响应// 5. 双脉冲测试$display("=== 双脉冲测试开始 ===");i_din = 2'b01; // 第一个正脉冲#20;i_din = 2'b00;#30;i_din = 2'b01; // 第二个正脉冲#20;i_din = 2'b00;#200;// 6. 负脉冲测试$display("=== 负脉冲测试开始 ===");i_din = 2'b11; // 负脉冲#20;i_din = 2'b00;#200;// 7. 交替脉冲序列测试$display("=== 交替脉冲序列测试开始 ===");repeat(5) begini_din = 2'b01; // 正脉冲#20;i_din = 2'b00;#30;i_din = 2'b11; // 负脉冲#20;i_din = 2'b00;#30;end// 8. 最后回到零点$display("=== 测试结束,回到零点 ===");i_din = 2'b00;#200;$display("=== 仿真结束 ===");$finish;
end// 监控输出变化
always @(posedge i_clk) begin$display("Time=%0t ns, Input=%d, Output=%d", $time, $signed(i_din), $signed(o_dout));
endendmodule
进行仿真即可,不会仿真的可以问AI

可以看到仿真的结果。
工程文件:https://download.csdn.net/download/fantasygwh2015/92261208
