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为上升沿标志
工作原理
-
在时钟上升沿到来时:
- 如果
sig_a
从低电平变为高电平(即当前周期为高电平,上一周期为低电平),sig_a & !sig_a_d1
的结果为 1,表示检测到上升沿。 - 如果
sig_a
保持高电平或从高电平变为低电平,sig_a & !sig_a_d1
的结果为 0,表示没有检测到上升沿。
- 如果
-
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为上升沿标志
工作原理
-
时钟上升沿到来时:
- 如果
sig_a
从高电平变为低电平(即当前周期为低电平,上一周期为高电平),则!sig_a & sig_a_d1
的结果为 1,表示检测到下降沿。 - 如果
sig_a
保持低电平或从低电平变为高电平,则!sig_a & sig_a_d1
的结果为 0,表示没有检测到下降沿。
- 如果
-
延迟信号
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为双边沿信号
工作原理
-
时钟同步:
- 该逻辑假设
sig_a
是同步信号,即sig_a
的变化发生在时钟有效边沿附近。 sig_a_d1
是sig_a
经过一个时钟周期延迟后的值,通常通过寄存器实现。
- 该逻辑假设
-
边沿检测过程:
- 在每个时钟上升沿,比较当前的
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
用于检测任意边沿。
这样可以根据需要分别处理上升沿和下降沿事件。
双边沿检测广泛应用于需要捕捉信号变化的场合,例如:
- 事件触发:当某个信号发生变化时触发特定操作。
- 数据同步:在数据传输中检测数据的变化以进行同步处理。
- 状态机控制:根据输入信号的变化切换状态机的状态。
通过合理使用双边沿检测逻辑,可以提高系统对信号变化的响应速度和准确性。