# Verilog功能模块--多数滤波器
**Repository Path**: xuxiaokang/verilog-function-module--majorityFilter
## Basic Information
- **Project Name**: Verilog功能模块--多数滤波器
- **Description**: Verilog功能模块--多数滤波器
- **Primary Language**: Verilog
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2026-04-04
- **Last Updated**: 2026-07-24
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Verilog功能模块--多数表决滤波器
## 前言
多数表决滤波器(Majority Vote Filter)是一种硬件数字滤波电路,用于消除信号中的短时抖动和噪声。该模块通过统计最近 `N` 次采样中目标电平(高/低)出现的次数,当次数达到阈值 `M` 时输出该电平,否则输出相反电平。这种滤波方式在按键去抖、传感器信号抗干扰、FPGA输入同步等场景中广泛应用。
本多数表决滤波器模块具有以下优点:
- **参数化设计**:窗口大小、判决阈值、目标电平均可配置,适应多种滤波需求。
- **高效实现**:仅使用一个移位寄存器和一个小位宽计数器,资源占用低。
- **鲁棒性强**:内部包含参数合法性检查(仿真阶段),复位状态定义清晰。
该模块已通过仿真验证。
---
## 一、设计思路
1. **滑动窗口存储**
使用移位寄存器 `shift_reg` 保存最近 `N` 次采样的信号值,每个时钟周期将新的 `signal_in` 移入最低位,最高位(最旧值)被丢弃。
2. **计数器统计**
通过寄存器 `count` 记录当前窗口内 `TARGET_LEVEL` 出现的次数。更新规则为:
- 新采样 = `TARGET_LEVEL` 且 移出值 ≠ `TARGET_LEVEL` → `count` 加 1;
- 新采样 ≠ `TARGET_LEVEL` 且 移出值 = `TARGET_LEVEL` 且 `count > 0` → `count` 减 1;
- 其他情况 `count` 保持不变。
3. **输出判决**
每个时钟周期比较 `count` 与阈值 `M`:
- `count >= M` → 输出 `TARGET_LEVEL`;
- 否则 → 输出 `~TARGET_LEVEL`。
4. **复位行为**
复位时(`rstn = 0`):
- 移位寄存器初始化为 `~TARGET_LEVEL`(全相反电平);
- 计数器清零;
- 输出设为 `~TARGET_LEVEL`。
5. **参数有效性检查**
模块内部通过 `initial` 块在仿真时检查参数合法性(`N >= 2`, `N >= M`, `M >= 1`, `TARGET_LEVEL ∈ {0,1}`),便于早期发现配置错误。
---
## 二、模块框图
## 三、参数与信号接口
### 3.1 参数接口
| 参数名 | 类型 | 默认值 | 描述 |
| -------------- | ------- | ------ | ---------------------------------------------------- |
| `N` | integer | 6 | 滑动窗口大小(采样次数),必须 ≥ 2 且 ≥ `M` |
| `M` | integer | 5 | 输出判决阈值,必须 ≥ 1 且 ≤ `N` |
| `TARGET_LEVEL` | [0:0] | 1 | 需要统计的电平(0 表示统计低电平,1 表示统计高电平) |
### 3.2 信号接口
| 端口名 | 方向 | 位宽 | 描述 |
| -------------- | ------ | ---- | ---------------------------------- |
| `filtered_out` | output | 1 | 滤波后的输出信号 |
| `signal_in` | input | 1 | 待滤波的输入信号(需同步到时钟域) |
| `clk` | input | 1 | 采样时钟(上升沿有效) |
| `rstn` | input | 1 | 异步复位,低电平有效 |
---
## 四、使用方法
### 4.1 例化示例(Verilog)
```verilog
//++ 实例化多数表决滤波器 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
wire filtered_out;
wire signal_in;
majority_filter #(
.N(6),
.M(5),
.TARGET_LEVEL(1)
) u_majority_filter (
.filtered_out(filtered_out),
.signal_in (signal_in),
.clk (clk),
.rstn (rstn)
);
//-- 实例化多数表决滤波器 ------------------------------------------------------------
```
### 4.2 注意事项
- **输入同步**:`signal_in` 必须已经同步到 `clk` 时钟域,避免亚稳态。
- **资源限制**:参数 `N` 不宜过大(建议 ≤ 256),否则会消耗较多寄存器资源。若需更大窗口,可改用 Block RAM 实现移位寄存器。
---
## 五、仿真验证
我们使用 SystemVerilog 搭建了完整的 testbench,覆盖以下测试项:
| 测试项 | 描述 |
| -------------------------- | ------------------------------------------------------------ |
| 复位检查 | 复位后输出是否为 `~TARGET_LEVEL` |
| 稳定目标电平 | 连续输入 `N+5` 个 `TARGET_LEVEL`,输出应变为 `TARGET_LEVEL` |
| 稳定相反电平 | 连续输入 `N+5` 个 `~TARGET_LEVEL`,输出应保持 `~TARGET_LEVEL` |
| 边界测试(恰好 M 次) | 窗口内恰好 M 个 `TARGET_LEVEL` 时输出 `TARGET_LEVEL`,再输入一个相反电平后输出翻转 |
| 随机序列测试 | 1000 个随机激励,无崩溃或断言失败 |
| 参数化测试(通过修改参数) | 分别测试 `TARGET_LEVEL = 0` 和 `1`,以及不同 `(N, M)` 组合 |
所有测试均已通过,波形验证了逻辑的正确性。下图展示了 `N=6, M=5, TARGET_LEVEL=0` 时连续输入 5 个 0 后输出变为 0 的关键波形片段。
---
## 六、源码分享
源码(含testbenck)已在Gitee和Github中开源,两平台同步。
Gitee:https://gitee.com/xuxiaokang/verilog-function-module--majorityFilter
Github:https://github.com/zhengzhideakang/verilog-function-module--majorityFilter
Vivado 2025.2仿真工程文件通过网盘分享。
欢迎大家关注我的微信公众号:徐晓康的博客,回复以下6位数字获取网盘链接。
236897
建议复制过去不会码错字!
---
如果本文对你有所帮助,欢迎点赞、转发、收藏、评论让更多人看到,赞赏支持就更好了。
如果对文章内容有疑问,**请务必清楚描述问题**,留言评论或私信告知我,我看到会回复。
---
**徐晓康的博客**持续分享高质量硬件、FPGA与嵌入式知识,软件,工具等内容,欢迎大家关注。