在 FPGA/Verilog 开发中,资源极少、极易实现、最常用 的滤波算法就这 4 种 ,完全适合你刚才遇到的 slice 资源紧张 场景,我按推荐优先级给你整理好,直接复制就能用。
最适合 FPGA 的 4 种极简滤波算法
1. 消抖滤波(最简单、0 资源)
用途 :按键、开关、电平信号、毛刺消除
优点 :纯计数器,几乎不占资源
原理:连续 N 次采样相同才认为有效,过滤瞬间干扰
verilog
module debounce_filter(
input clk,
input rst_n,
input din,
output reg dout
);
reg [3:0] cnt; // 只用 4 位计数器,超省资源
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
cnt <= 0;
dout <= 0;
end else begin
if(din == dout) // 输入与当前输出一致
cnt <= 0;
else begin
cnt <= cnt + 1'b1;
if(cnt == 4'd10) begin // 连续稳定10次才更新
dout <= din;
cnt <= 0;
end
end
end
end
endmodule
2. 中位值滤波(抗脉冲干扰最强)
用途 :温度、电压、电流等模拟量采集
优点 :剔除尖峰干扰,资源极小
原理:采 N 个数,排序后取中间值
verilog
// 3 点中位值滤波,最省资源版本
module median_filter_3(
input clk,
input [7:0] din,
output [7:0] dout
);
reg [7:0] d1, d2, d3;
always @(posedge clk) begin
d1 <= din;
d2 <= d1;
d3 <= d2;
end
// 纯组合逻辑取中间值
assign dout = (d1 & d2) | (d2 & d3) | (d1 & d3);
endmodule
资源:3 个寄存器 + 少量组合逻辑,几乎可以忽略。
3. 算术平均滤波(最平滑)
用途 :随机噪声、ADC 采集
优点:平滑效果好,资源可控
verilog
// 4 点平均滤波(2^n 除法,无需除法器,极省资源)
module avg_filter_4(
input clk,
input [7:0] din,
output [7:0] dout
);
reg [7:0] d[0:3];
reg [9:0] sum; // 只需 10 位
always @(posedge clk) begin
d[0] <= din;
d[1] <= d[0];
d[2] <= d[1];
d[3] <= d[2];
sum <= d[0] + d[1] + d[2] + d[3];
end
assign dout = sum >> 2; // 右移2位 = 除以4,无除法器
endmodule
关键 :用 2^n 平均,不用除法器,资源暴减!
4. 一阶惯性滤波(动态性能最好)
用途 :慢速变化信号(温度、液位)
优点:资源 = 1 个寄存器 + 1 个加法器
verilog
// 最简一阶滤波:Y = Y + (X-Y)/8
module first_order_filter(
input clk,
input [7:0] din,
output reg [7:0] dout
);
always @(posedge clk) begin
dout <= dout + (din - dout)>>3;
end
endmodule
资源 :整个滤波只用 1 个 8bit 寄存器,是 FPGA 里最省资源的平滑滤波。
快速选择指南
| 滤波类型 | 资源占用 | 适用场景 | 推荐指数 |
|---|---|---|---|
| 消抖滤波 | ⭐ 0 资源 | 按键、电平、去毛刺 | ⭐⭐⭐⭐⭐ |
| 中位值滤波 | ⭐ 极少 | 剔除尖峰、脉冲干扰 | ⭐⭐⭐⭐ |
| 算术平均 | ⭐⭐ 很少 | ADC、随机噪声 | ⭐⭐⭐⭐ |
| 一阶惯性 | ⭐ 最少 | 慢变信号、超省资源 | ⭐⭐⭐⭐⭐ |
最省资源的终极建议(针对你资源溢出的情况)
- 优先用:消抖滤波 / 一阶惯性滤波
资源几乎可以忽略不计 - 平均滤波只使用 2^n 点 (4/8/16)
避免使用除法器,节省大量 slice - 中位值滤波只用 3 点
资源最小,抗干扰最强
总结
- Verilog 里最易实现、最省资源的就是这 4 种;
- 一阶惯性滤波是资源最少的平滑滤波,整个电路仅 1 个寄存器;
- 消抖滤波 适合数字信号,中位值适合抗尖峰;
- 全部代码都能直接使用,不会造成 slice 资源溢出。
你需要我把其中任意一种改成 12bit ADC 专用 或 带位宽配置 的通用版吗?