# How to design a good Edge Detector

## 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.