> 技术文档 > Verilog边沿检测(同步上升沿、下降沿、双边沿检测)_verilog上升沿检测

Verilog边沿检测(同步上升沿、下降沿、双边沿检测)_verilog上升沿检测

边沿信号的使用在Verilog语言中非常常见,下面是我的学习总结

1、同步上升沿检测 A&!A_d1

(红色虚线为系统时钟的上升沿)

assign sig_a_flag=sig_a&!sig_a_d1;

sig_a为原信号
sig_a_d1为延迟一拍信号(打一拍)
!sig_a_d1为延迟一拍信号的取反
sig_a_flag为上升沿标志

工作原理

  1. 在时钟上升沿到来时:

    • 如果 sig_a 从低电平变为高电平(即当前周期为高电平,上一周期为低电平),sig_a & !sig_a_d1 的结果为 1,表示检测到上升沿。
    • 如果 sig_a 保持高电平或从高电平变为低电平,sig_a & !sig_a_d1 的结果为 0,表示没有检测到上升沿。
  2. sig_a_d1 是 sig_a 的延迟一拍的值,通常通过时钟同步的方式实现。例如,在 Verilog 中可以通过寄存器来实现延迟。

2、同步下降沿检测   !A&A_d1

assign sig_a_flag=!sig_a&sig_a_d1;

sig_a为原信号
sig_a_d1为延迟一拍信号(打一拍)
!sig_a为原信号的取反
sig_a_flag为上升沿标志

工作原理

  1. 时钟上升沿到来时

    • 如果 sig_a 从高电平变为低电平(即当前周期为低电平,上一周期为高电平),则 !sig_a & sig_a_d1 的结果为 1,表示检测到下降沿。
    • 如果 sig_a 保持低电平或从低电平变为高电平,则 !sig_a & sig_a_d1 的结果为 0,表示没有检测到下降沿。
  2. 延迟信号 sig_a_d1

    • sig_a_d1 是 sig_a 的延迟一拍的值,通常通过时钟同步的方式实现。例如,在 Verilog 中可以通过寄存器来实现延迟。

3、同步双边沿检测(异或) A^B  或  (A&!B)|(!A&B)

assign sig_a_anyedge=sig_a^sig_a_d1;//或assign sig_a_anyedge=(!sig_a&sig_a_d1)|(sig_a&!sig_a_d1);

sig_a为原信号
sig_a_d1为延迟一拍信号(打一拍)
sig_a_flag为双边沿信号

工作原理

  1. 时钟同步

    • 该逻辑假设 sig_a 是同步信号,即 sig_a 的变化发生在时钟有效边沿附近。
    • sig_a_d1 是 sig_a 经过一个时钟周期延迟后的值,通常通过寄存器实现。
  2. 边沿检测过程

    • 在每个时钟上升沿,比较当前的 sig_a 和上一周期的 sig_a_d1
    • 如果两者不同,表示在上一时钟周期到当前时钟周期之间,sig_a 发生了一次边沿变化(上升沿或下降沿)。

1、同步上升沿检测测试代码

module edge_detector ( input wire clk, // 时钟信号 input wire rst_n, // 异步复位信号,低电平有效 input wire sig_a, // 输入信号 output reg sig_a_flag // 上升沿检测标志); reg sig_a_d1; // 用于存储 sig_a 的延迟一拍值 always @(posedge clk or negedge rst_n) begin if (!rst_n) begin sig_a_d1 <= 1\'b0; // 复位时将延迟值清零 sig_a_flag <= 1\'b0; // 复位时将标志清零 end else begin sig_a_d1 <= sig_a; // 将 sig_a 延迟一拍 sig_a_flag <= sig_a & !sig_a_d1; // 检测上升沿 end endendmodule

2、同步下降沿检测测试代码

module edge_detector ( input wire clk, // 时钟信号 input wire rst_n, // 异步复位信号,低电平有效 input wire sig_a, // 输入信号 output reg sig_a_flag // 下降沿检测标志); reg sig_a_d1; // 用于存储 sig_a 的延迟一拍值 always @(posedge clk or negedge rst_n) begin if (!rst_n) begin sig_a_d1 <= 1\'b0; // 复位时将延迟值清零 sig_a_flag <= 1\'b0; // 复位时将标志清零 end else begin sig_a_d1 <= sig_a; // 将 sig_a 延迟一拍 sig_a_flag <= !sig_a & sig_a_d1; // 检测下降沿 end endendmodule

3、同步双边沿检测测试代码

module edge_detector ( input wire clk, // 时钟信号 input wire rst_n, // 异步复位信号,低电平有效 input wire sig_a, // 输入信号 output wire sig_a_anyedge // 双边沿检测标志); reg sig_a_d1; // 用于存储 sig_a 的延迟一拍值 // 同步延迟寄存器 always @(posedge clk or negedge rst_n) begin if (!rst_n) begin sig_a_d1 <= 1\'b0; // 复位时将延迟值清零 end else begin sig_a_d1 <= sig_a; // 将 sig_a 延迟一拍 end end // 双边沿检测逻辑 assign sig_a_anyedge = sig_a ^ sig_a_d1;endmodule

4、双边沿检测拓展

扩展:区分上升沿和下降沿

如果不仅需要检测双边沿,还需要分别区分上升沿和下降沿,可以对原逻辑进行扩展。

module edge_detector ( input wire clk, // 时钟信号 input wire rst_n, // 异步复位信号,低电平有效 input wire sig_a, // 输入信号 output reg sig_a_rise, // 上升沿检测标志 output reg sig_a_fall, // 下降沿检测标志 output wire sig_a_anyedge // 双边沿检测标志); reg sig_a_d1; // 用于存储 sig_a 的延迟一拍值 // 同步延迟寄存器 always @(posedge clk or negedge rst_n) begin if (!rst_n) begin sig_a_d1 <= 1\'b0; sig_a_rise <= 1\'b0; sig_a_fall <= 1\'b0; end else begin sig_a_d1 <= sig_a; sig_a_rise <= sig_a & !sig_a_d1; // 上升沿检测 sig_a_fall <= !sig_a & sig_a_d1; // 下降沿检测 end end // 双边沿检测逻辑 assign sig_a_anyedge = sig_a ^ sig_a_d1;endmodule
  • sig_a_rise 用于检测上升沿。
  • sig_a_fall 用于检测下降沿。
  • sig_a_anyedge 用于检测任意边沿。

这样可以根据需要分别处理上升沿和下降沿事件。

双边沿检测广泛应用于需要捕捉信号变化的场合,例如:

  • 事件触发:当某个信号发生变化时触发特定操作。
  • 数据同步:在数据传输中检测数据的变化以进行同步处理。
  • 状态机控制:根据输入信号的变化切换状态机的状态。

通过合理使用双边沿检测逻辑,可以提高系统对信号变化的响应速度和准确性。