I used to be stupid before
Always @ (Posedge signal)
Such code to detect the rising edge of signal, a lot of problems.
After being instructed by a classmate in the lab, he will never do so foolishly. Of course, you won't do that after reading it.
The principle of detecting the rising edge: The signal is sampled using a high-frequency clock, so to realize the rising edge detection, the clock frequency must be at least twice times the highest frequency of the signal, or leak detection may occur. See the code below for details.
Module Edge_check (CLK, Rst_n, Signal, Pos_edge, Neg_edge, Both_edge); input clk;input rst_n;input signal;output Pos_edge ; output Neg_edge;output Both_edge;reg sig_r0, sig_r1; Status register always @ (Posedge CLK or Negedge rst_n) if (!rst_n) begin sig_r0 <= 1 ' b0; SIG_R1 <= 1 ' b0; End ELSE begin Sig_r0 <= signal; Sig_r1 <= sig_r0; End Assign Pos_edge = (~SIG_R1) & (SIG_R0); Assign Neg_edge = Sig_r1 & (~sig_r0); Assign Both_edge = sig_r1 ^ sig_r0;
The RTL view after the Quartus II cabling is as follows:
As can be seen from the RTL view, the circuit is implemented by a D trigger with an asynchronous reset.
The simulation view of the Modelsim is as follows, which shows that the rising and falling edges have been detected, but there is a delay due to the use of clock synchronization detection.
Or the above Verilog code can also change a way of writing, efficiency is not too much;
Module Edge_check (CLK, Rst_n, Signal, Pos_edge, Neg_edge, Both_edge); input clk;input rst_n;input signal;output Pos_edge ; output Neg_edge;output Both_edge;reg [1:0]sig_fifo;reg sig_r0, SIG_R1; Status register always @ (Posedge CLK or Negedge rst_n) if (!rst_n) begin Sig_fifo <= 2 ' B0; End ELSE begin Sig_fifo <= {sig_fifo[0], signal}; End Assign Pos_edge = (Sig_fifo = = 2 ' B01); assign Neg_edge = (Sig_fifo = = 2 ' B10); Assign Both_edge = sig_fifo[0] ^ sig_fifo[1];
The resulting RTL view is
[Turn]FPGA edge detection