Level vs edge
In digital synchronous design sometimes we need to detect the transition ‘0’->’1′ or ‘1’->’0’ of a signal.
As a simple example, suppose you have a counter with enable input port connected to an external push button. You need to count +1 every time you push the button.
Let the counter clock to be for example 50 MHz. The clock period is 20 ns. Even if you are very very fast in pushing the button it will be difficult to generate a pulse of 20 ns in order to enable the counter for only one clock cycle.
For example, if you push the button even for few millisecond, let say for instance 200 ms, your counter will be enabled for 200 ms/20 ns = 10.000.000 of clock cycle!
As you can see we need another solution than trying to push the button very very fast!
Detect the transition
The solution is to implement something that is able to detect the transition of our input signal: an edge detector, no matter how long your control signal remains high, you are detecting the transition from ‘0’ to ‘1’.
In this case, we have the opposite problem: the control signal shall remain high at least 2 clock cycle (remember Nyquist theorem? ) to be sure to sample the signal correctly.
Using the architecture in Figure2, we can generate a pulse of one clock, no matter how long is the input control signal, so every time we push the button we will count +1.
VHDL implementation of an edge-detector
A possible VHDL implementation is:
library ieee; use ieee.std_logic_1164.all; entity edge_detector is port ( i_clk : in std_logic; i_rstb : in std_logic; i_input : in std_logic; o_pulse : out std_logic); end edge_detector; architecture rtl of edge_detector is signal r0_input : std_logic; signal r1_input : std_logic; begin p_rising_edge_detector : process(i_clk,i_rstb) begin if(i_rstb='0') then r0_input <= '0'; r1_input <= '0'; elsif(rising_edge(i_clk)) then r0_input <= i_input; r1_input <= r0_input; end if; end process p_rising_edge_detector; o_pulse <= not r1_input and r0_input; end rtl;
in case you need to detect the falling edge the solution is very simple:
o_pulse <= not r0_input and r1_input;
In the simulation of Figure3 is clear that the circuit generates a pulse of only one clock cycle, no matter how long is the control signal.
Typical mistake in edge detector implementation
Surfing the web, you can find many examples of rising edge detector as reported in Figure4.
This implementation contains a big mistake.
Let see a simulation of this circuits. As you can see, if the edge of the input signal is very close to the internal clock edge the pulse generated is very short as shown in Figure5 and Figure6. Moreover, it is possible to lose the detection due to the internal physical delay of the circuit.
So, when you have to interface asynchronous domain with a synchronous one you shall put a first sampling stage before implementing any combinatorial operation.
As a general rule, to minimize metastability issue, a possible solution is to put 2 register stage before any combinatorial operation.
As a drawback, this solution will introduce a delay of one clock cycle in the output of the circuits.
If you appreciated this post, please help us to share it with your friend.
[social_sharing style=”style-7″ fb_like_url=”https://surf-vhdl.com/how-to-design-a-good-edge-detector” fb_color=”light” fb_lang=”en_US” fb_text=”like” fb_button_text=”Share” tw_lang=”en” tw_url=”https://surf-vhdl.com/how-to-design-a-good-edge-detector” tw_button_text=”Share” g_url=”https://surf-vhdl.com/how-to-design-a-good-edge-detector” g_lang=”en-GB” g_button_text=”Share” linkedin_url=”https://surf-vhdl.com/how-to-design-a-good-edge-detector” linkedin_lang=”en_US” alignment=”center”]
If you need to contact us, please write to: surf.vhdl@gmail.com
We appreciate any of your comment, please post below:
I appreciated your article as a beginner in vhdl, however I think it could have been made much clearer.
Two pedagogical mistakes:
– The vhdl code does not correspond strictly to the preceding diagram. When reading the code for the first time we cannot help wonder what is this reset doing there ?
It just disturbs our mind which is focused on the main issue of the post.
In addition having the same signal names than in the diagram would also help a lot.
– Later on you show us a typical mistake found on other sites. My first thouht is why the heck removing the inverter and using the /Q output should not work ?
I realized later that you also made another change: you removed the first register and apparently that is the (only ?) reason why the circuit does not work.
But at the end of the article we still do not know if having only removed the inverter and using /Q could have caused any problems !
Hi, thank you for your feedback!
In the post, I do not use /Q because the code is RTL code.
As you can see “not r1_input” in the RTL code is definitely R1_input_inv.
Moreover, it can be view as /Q.
The post would report a possible VHDL/RTL implementation of an edge-detector.
If you write a structural VHDL code using a Flip-Flop component with a /Q output you can avoid the use if the inverter.
The mistake is not the use of the inverter,
but the missing of the first flip-flop as you can see in Figure 5 where the edge is not detected.
I hope I answered your doubts
Ciao
Thank you for the post, it was an interesting read! However, I’m a bit sceptical to the section “Typical mistake in edge detector implementation”. Either the input signal is asynchronous, in which case both circuits suffer from metastability issues, or the input signal is synchronous, in which case either of the two circuits are fine depending on the use case. The second design may be favorable if you know that the pulse will last long enough for your needs, since less hardware is required and since it decreases the latency of that path (which e.g. is the need here: https://stackoverflow.com/questions/17429280/vhdl-edge-detection). Meanwhile, the added register in the first circuit may be a possible solution if the pulse doesn’t last long enough. Am I right? I’m new to hardware design and would very much like to know your opinion on this.
I read the example there are some issues in the first example.
The example uses an XOR it could be reduced to an AND, NOT as in this canonical example
Hi, I was just wondering, is there any reason why I can’t use the “rising_edge()” and “falling_edge()” functions instead?
because such function trigger the instantiation of a flip-flop connecting the signal inside de function to che clock pin of the flip-flop.
In this example we need to “sample” an edge on an signal
“This implementation contains a big mistake.
Let see a simulation of this circuits. As you can see, if the edge of the input signal is very close to the internal clock edge the pulse generated is very short as shown in Figure5 and Figure6. Moreover, it is possible to lose the detection due to the internal physical delay of the circuit.”
Would you like to elaborate? What was the intended duration of the pulse generated? One clock of 1000ns without getting interfered of input clock and also the input button?
the pulse duration is related to the clock duration
What if you want to detect narrow pulses less than half the clock period ?
it could be possible that the edge is not detected.
You should use a complete clock pulse (high-low) that is at least of the length of the pulse you want to detect. Better if the clock pulse is 1/2 of the pulse length i.e. 1/clock frequency is at least double the pulse width