用verilog实现边沿检测(上升沿,下降沿,双边)

    技术2023-06-06  83

    不是很难却困扰过我的一个问题

    边沿检测?不是可以直接把待检测的信号写在always块里吗?

    其实不是的,这个题目的本意是在同步电路中实现这样的功能,如果把待检测的信号写在always块里面,相当于把输入信号接到了触发器的clk上,这样电路就变成异步的了,后面还需要把信号同步,得不偿失。

    正解是使用两个触发器,再通过逻辑组合判断边沿。

    边沿检测代码:

    module edge_detector(input clk, rst_n, din, output raising_edge_detect,falling_edge_detect,double_edge_detect); reg q0,q1; assign raising_edge_detect = q0 & (~q1); assign falling_edge_detect = ~q0 & q1; assign double_edge_detect = q0 ^ q1; always@(posedge clk, negedge rst_n) begin if(!rst_n) begin q0 <= 0; q1 <= 0; end else begin q0 <= din; q1 <= q0; end end endmodule

    testbench:

    `timescale 1ns/1ns module edge_detector_tb; reg CLK,RST_N,DIN; wire RAISING_EDGE_DETECT,FALLING_EDGE_DETECT,DOUBLE_EDGE_DETECT; reg i,j; edge_detector U_edge_detector( .clk(CLK), .rst_n(RST_N), .din(DIN), .raising_edge_detect(RAISING_EDGE_DETECT), .falling_edge_detect(FALLING_EDGE_DETECT), .double_edge_detect(DOUBLE_EDGE_DETECT) ); initial begin CLK = 0 ; for(i = 0 ; i<10000; i=i+1) begin #1 CLK = ~CLK; end end initial begin DIN = 0 ; for(j = 0 ; j<100; j=j+1) begin #10 DIN = 0; #10 DIN = 1; #10 DIN = 1; #10 DIN = 1; #10 DIN = 0; #10 DIN = 0; #10 DIN = 1; #10 DIN = 0; #10 DIN = 1; #10 DIN = 0; end end initial begin RST_N = 1; #5 RST_N = 0; #5 RST_N = 1; end endmodule

     仿真结果:

    Processed: 0.009, SQL: 9