在FPGA/ASIC数字逻辑设计中,边沿检测是一个高频出现的基础需求。无论是按键按下瞬间的捕获,还是通信协议中数据有效标志的识别,都需要我们精准地"抓住"信号跳变的那一瞬间。
以一段经典的Verilog代码为例,深入解析边沿检测模块的设计原理、应用场景,并完成仿真验证。
一、为什么需要边沿检测?
按键按下:机械开关从断开(高阻/高电平)到闭合(低电平),我们只关心"按下"那个下降沿
FIFO写使能:当写请求信号从0变1时,触发一次写入操作
协议握手:AXI等总线协议中,VALID/READY的上升沿标志着一次传输开始
如果直接用组合逻辑判断信号电平,你会得到一个持续的使能信号;而边沿检测模块的作用,就是将这个"持续电平"转化为仅持续一个时钟周期的高电平脉冲,方便后续模块采样处理。
二、双触发器
核心代码采用了两级D触发器采样结构:
always @(posedge i_clk) begin
if (i_rst) begin
signal_in_dff1 <= 1'b0;
signal_in_dff2 <= 1'b0;
end else begin
signal_in_dff1 <= i_signal_in; // 当前状态
signal_in_dff2 <= signal_in_dff1; // 上一拍状态
end
end
这里有两个关键作用:
跨时钟域同步:如果 i_signal_in 来自异步时钟域,两级触发器可以有效降低亚稳态传播的概率
状态记忆:signal_in_dff1 保存当前采样值,signal_in_dff2 保存上一拍值。通过对比两者,我们就能判断"刚才发生了什么"
边沿判断逻辑:
上升沿:signal_in_dff1 & ~signal_in_dff2(当前为1,上一拍为0)
下降沿:~signal_in_dff1 & signal_in_dff2(当前为0,上一拍为1)
任意沿:signal_in_dff1 ^ signal_in_dff2(两拍不同即翻转)
模块通过参数 EDGE 在编译时选择模式,综合工具会自动优化掉无关逻辑,零运行时开销。
三、典型应用场景
1. 按键消抖与触发
机械按键按下时会产生数毫秒的抖动。经过外部消抖电路后,再用上升沿检测模块捕获"稳定按下"的瞬间,生成单周期脉冲去触发状态机或中断。
2. 状态机跳转
在Moore/Mealy状态机中,很多转移条件依赖于事件的"发生"而非"持续"。边沿检测将电平事件转化为脉冲事件,让状态转移更清晰。
3. 脉冲计数与频率测量
对输入信号做任意沿检测,每检测到一个边沿就计数一次,配合固定时间窗口即可实现简易频率计。
4. 总线协议解析
在SPI、I2C等协议中,片选信号CS的下降沿标志着传输开始,上升沿标志结束。边沿检测模块可以精确提取这些协议事件。
四、仿真验证:如何证明模块是对的?
Testbench的设计思路是"全覆盖+自动断言"。我们同时例化了三种边沿检测模式,共用同一个输入信号,然后设计了七大测试场景:
// 测试1:上升沿(0->1)
// 测试2:保持高电平(无沿)
// 测试3:下降沿(1->0)
// 测试4:保持低电平(无沿)
// 测试5:连续翻转
// 测试6:复位期间翻转(验证屏蔽)
// 测试7:复位后首次边沿
五、如何获取?
关注公众号:我是小灰灰的FPGA,关注我,带你从入门到精通数字逻辑设计。
后台回复(建议复制粘贴):edge_detect
186