基于 FPGA 的 FIR 数字滤波器设计
FIR 滤波器在数字信号处理中应用广泛,基于 FPGA 实现具有较高灵活性。本文将介绍如何使用 Quartus 和 Vivado 实现 FIR 滤波器,涵盖从 MATLAB 生成系数到仿真验证的全过程。
1. MATLAB 系数生成
FIR 滤波器的核心是系数。通常使用 MATLAB 设计这些系数。MATLAB 中的 fir1 函数可以方便地生成 FIR 滤波器系数。
例如,设计一个低通滤波器,截止频率为 0.2π,阶数为 20:
n = 20; % 滤波器阶数
Wn = 0.2; % 截止频率
b = fir1(n, Wn); % 生成滤波器系数
生成系数后,可将其导出到文件中供 FPGA 设计使用。使用 dlmwrite 函数保存为文本文件:
dlmwrite('fir_coefficients.txt', b, 'precision', '%.16f');
2. Quartus 实现
在 Quartus 中,可以使用 Verilog 编写 FIR 滤波器代码。FIR 滤波器的实现本质上是卷积运算,每个输入样本与滤波器系数相乘并累加。
以下是一个简单的 FIR 滤波器 Verilog 示例:
module fir_filter (
input clk,
input rst,
input signed [15:0] data_in,
output reg signed [31:0] data_out
);
// 移位寄存器存储输入数据,需根据实际系数定义
reg signed [15:0] shift_reg [0:20];
integer i;
always @(posedge clk or posedge rst) begin
if (rst) begin
for (i = 0; i <= 20; i = i + 1) begin
shift_reg[i] <= 16'b0;
end
data_out <= 32'b0;
end else begin
for (i = 20; i > 0; i = i - 1) begin
shift_reg[i] <= shift_reg[i-1];
end
shift_reg[0] <= data_in;
data_out <= 0;
// 注意:此处 b[i] 需定义为参数或 wire
for (i = 0; i <= 20; i = i + 1) begin
data_out <= data_out + shift_reg[i] * b[i];
end
end
end
endmodule
3. Vivado 实现
Vivado 同样支持 Verilog 实现,并提供 FIR Compiler IP 核以简化设计。使用 FIR Compiler 时,只需配置滤波器参数,工具会自动生成硬件逻辑。
可通过 Tcl 脚本或 GUI 配置 FIR Compiler,设置系数、位宽、时钟频率等参数。配置完成后实例化生成的 IP 核:
module top (
input clk,
input rst,
input signed [15:0] data_in,
output signed [31:0] data_out
);
fir_compiler_0 fir_inst (
.aclk(clk),
.s_axis_data_tdata(data_in),
.s_axis_data_tvalid(1'b1),
.m_axis_data_tdata(data_out)
);
endmodule
4. 仿真验证
仿真用于验证设计正确性。可使用 ModelSim 或 Vivado 自带工具。生成测试数据(如正弦波)作为输入,观察输出波形是否符合预期。
Testbench 示例:
initial begin
clk = 0;
rst = 1;
#10 rst = 0;
#1000 $stop;
end
always #5 clk = ~clk;
initial begin
integer i;
for (i = 0; i < 100; i = i + 1) begin
data_in = $sin(2 * 3.14159 * i / 100);
#10;
end
end


