Skip to main content
added 9 characters in body
Source Link
tim
  • 920
  • 7
  • 13

\$ t_{resolution} < N \times T_{clock} - t_{setup} \$\$ t_{resolution} < N_{cycles} \times T_{clock} - t_{setup} \$

\$ t_{resolution} < N \times T_{clock} - t_{setup} \$

\$ t_{resolution} < N_{cycles} \times T_{clock} - t_{setup} \$

Added an explanation of metastability and flipflop resolution time.
Source Link
tim
  • 920
  • 7
  • 13

You need at least two flip-flops to synchronise the signal to the clock. One flip-flop is not reliable.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Sync is
    generic
    (
        SYNC_BITS: positive := 3  -- Number of bits in the synchronisation buffer (2 minimum).
    );
    port
    (
        clock : in std_logic;
        input : in std_logic;  -- Asynchronous input.
        output: out std_logic  -- Synchronous output.
    );
end entity;

architecture V1 of Sync is

    constant SYNC_BUFFER_MSB: positive := SYNC_BITS - 1;
    signal sync_buffer: std_logic_vector(SYNC_BUFFER_MSB downto 0) := (others => '0');  -- N-bit synchronisation buffer (2 bits minimum).
    alias sync_input: std_logic is sync_buffer(SYNC_BUFFER_MSB);  -- The synchronised input is the MSB of the synchronisation buffer.

begin

    assert SYNC_BITS >= 2 report "Need a minimum of 2 bits in the synchronisation buffer.";

    process(clock)
    begin
        if rising_edge(clock) then
            sync_buffer <= sync_buffer(SYNC_BUFFER_MSB - 1 downto 0) & input;
        end if;
        output <= sync_input;
    end process;

end architecture;

Metastability

Figures from Digital Design and Computer Architecture by Harris & Harris

Figure 1 – Input changing before, after or during aperture.

Figure 1 – Input changing before, after or during aperture.


Figure 2 – Simple synchroniser.

Figure 2 – Simple synchroniser.


If the input, D, changes within the aperture (set-up and hold time) around the clock edge, the output, D2, is undetermined (metastable) and will take time to resolve to logic 0 or logic 1.

If the resolution time is less than the clock period minus the set-up time, the input to the second flip-flop will be stable, thus the output will successfully follow the input on the next clock edge.

If the resolution time is greater than the clock period minus the set-up time, the input to the second flip-flop will be between 0 and 1 (metastable) on the clock edge causing, it too, to become metastable:

\$ t_{resolution} > T_{clock} - t_{setup} \$

...so, three flip-flops are needed.

With higher clock frequencies, the ratio of resolution time, \$t_{resolution}\$, to clock period, \$T_{clock}\$, increases, necessitating even more flip-flops to satisfy the following equations:

\$ t_{resolution} < N \times T_{clock} - t_{setup} \$

\$ N_{flipflops} = N_{cycles} + 1 \$

...where \$N_{cycles} >= 1\$ and is the number of clock cycles to wait for resolution, thus giving a minimum of two flip-flops in the synchronisation buffer/chain.

You need at least two flip-flops to synchronise the signal to the clock. One flip-flop is not reliable.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Sync is
    generic
    (
        SYNC_BITS: positive := 3  -- Number of bits in the synchronisation buffer (2 minimum).
    );
    port
    (
        clock : in std_logic;
        input : in std_logic;  -- Asynchronous input.
        output: out std_logic  -- Synchronous output.
    );
end entity;

architecture V1 of Sync is

    constant SYNC_BUFFER_MSB: positive := SYNC_BITS - 1;
    signal sync_buffer: std_logic_vector(SYNC_BUFFER_MSB downto 0) := (others => '0');  -- N-bit synchronisation buffer (2 bits minimum).
    alias sync_input: std_logic is sync_buffer(SYNC_BUFFER_MSB);  -- The synchronised input is the MSB of the synchronisation buffer.

begin

    assert SYNC_BITS >= 2 report "Need a minimum of 2 bits in the synchronisation buffer.";

    process(clock)
    begin
        if rising_edge(clock) then
            sync_buffer <= sync_buffer(SYNC_BUFFER_MSB - 1 downto 0) & input;
        end if;
        output <= sync_input;
    end process;

end architecture;

You need at least two flip-flops to synchronise the signal to the clock. One flip-flop is not reliable.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Sync is
    generic
    (
        SYNC_BITS: positive := 3  -- Number of bits in the synchronisation buffer (2 minimum).
    );
    port
    (
        clock : in std_logic;
        input : in std_logic;  -- Asynchronous input.
        output: out std_logic  -- Synchronous output.
    );
end entity;

architecture V1 of Sync is

    constant SYNC_BUFFER_MSB: positive := SYNC_BITS - 1;
    signal sync_buffer: std_logic_vector(SYNC_BUFFER_MSB downto 0) := (others => '0');  -- N-bit synchronisation buffer (2 bits minimum).
    alias sync_input: std_logic is sync_buffer(SYNC_BUFFER_MSB);  -- The synchronised input is the MSB of the synchronisation buffer.

begin

    assert SYNC_BITS >= 2 report "Need a minimum of 2 bits in the synchronisation buffer.";

    process(clock)
    begin
        if rising_edge(clock) then
            sync_buffer <= sync_buffer(SYNC_BUFFER_MSB - 1 downto 0) & input;
        end if;
        output <= sync_input;
    end process;

end architecture;

Metastability

Figures from Digital Design and Computer Architecture by Harris & Harris

Figure 1 – Input changing before, after or during aperture.

Figure 1 – Input changing before, after or during aperture.


Figure 2 – Simple synchroniser.

Figure 2 – Simple synchroniser.


If the input, D, changes within the aperture (set-up and hold time) around the clock edge, the output, D2, is undetermined (metastable) and will take time to resolve to logic 0 or logic 1.

If the resolution time is less than the clock period minus the set-up time, the input to the second flip-flop will be stable, thus the output will successfully follow the input on the next clock edge.

If the resolution time is greater than the clock period minus the set-up time, the input to the second flip-flop will be between 0 and 1 (metastable) on the clock edge causing, it too, to become metastable:

\$ t_{resolution} > T_{clock} - t_{setup} \$

...so, three flip-flops are needed.

With higher clock frequencies, the ratio of resolution time, \$t_{resolution}\$, to clock period, \$T_{clock}\$, increases, necessitating even more flip-flops to satisfy the following equations:

\$ t_{resolution} < N \times T_{clock} - t_{setup} \$

\$ N_{flipflops} = N_{cycles} + 1 \$

...where \$N_{cycles} >= 1\$ and is the number of clock cycles to wait for resolution, thus giving a minimum of two flip-flops in the synchronisation buffer/chain.

added 2 characters in body
Source Link
tim
  • 920
  • 7
  • 13

You need at least two flip-flops to synchronise the signal to the clock. One flip-flop is not reliable.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Sync is
    generic
    (
        SYNC_BITS: positive := 3  -- Number of bits in the synchronisation buffer (2 minimum).
    );
    port
    (
        clock : in std_logic;
        input : in std_logic;  -- Asynchronous input.
        output: out std_logic  -- Synchronous output.
    );
end entity;

architecture V1 of Sync is

    constant SYNC_BUFFER_MSB: positive := SYNC_BITS - 1;
    signal sync_buffer: std_logic_vector(SYNC_BUFFER_MSB downto 0) := (others => '0');  -- N-bit synchronisation buffer (2 bits minimum).
    alias sync_input: std_logic is sync_buffer(SYNC_BUFFER_MSB);  -- The synchronised input is the MSB of the synchronisation buffer.

begin

    assert SYNC_BITS >= 2 report "Need a minimum of 2 bits in the synchronisation buffer.";

    process(clock)
    begin
        if rising_edge(clock) then
            sync_buffer <= sync_buffer(SYNC_BUFFER_MSB - 1 downto 0) & input;
        end if;
        output <= sync_input;
    end process;

end architecture;
```

You need at least two flip-flops to synchronise the signal to the clock. One flip-flop is not reliable.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Sync is
    generic
    (
        SYNC_BITS: positive := 3  -- Number of bits in the synchronisation buffer (2 minimum).
    );
    port
    (
        clock : in std_logic;
        input : in std_logic;  -- Asynchronous input.
        output: out std_logic  -- Synchronous output.
    );
end entity;

architecture V1 of Sync is

    constant SYNC_BUFFER_MSB: positive := SYNC_BITS - 1;
    signal sync_buffer: std_logic_vector(SYNC_BUFFER_MSB downto 0) := (others => '0');  -- N-bit synchronisation buffer (2 bits minimum).
    alias sync_input: std_logic is sync_buffer(SYNC_BUFFER_MSB);  -- The synchronised input is the MSB of the synchronisation buffer.

begin

    assert SYNC_BITS >= 2 report "Need a minimum of 2 bits in the synchronisation buffer.";

    process(clock)
    begin
        if rising_edge(clock) then
            sync_buffer <= sync_buffer(SYNC_BUFFER_MSB - 1 downto 0) & input;
        end if;
        output <= sync_input;
    end process;

end architecture;
```

You need at least two flip-flops to synchronise the signal to the clock. One flip-flop is not reliable.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Sync is
    generic
    (
        SYNC_BITS: positive := 3  -- Number of bits in the synchronisation buffer (2 minimum).
    );
    port
    (
        clock : in std_logic;
        input : in std_logic;  -- Asynchronous input.
        output: out std_logic  -- Synchronous output.
    );
end entity;

architecture V1 of Sync is

    constant SYNC_BUFFER_MSB: positive := SYNC_BITS - 1;
    signal sync_buffer: std_logic_vector(SYNC_BUFFER_MSB downto 0) := (others => '0');  -- N-bit synchronisation buffer (2 bits minimum).
    alias sync_input: std_logic is sync_buffer(SYNC_BUFFER_MSB);  -- The synchronised input is the MSB of the synchronisation buffer.

begin

    assert SYNC_BITS >= 2 report "Need a minimum of 2 bits in the synchronisation buffer.";

    process(clock)
    begin
        if rising_edge(clock) then
            sync_buffer <= sync_buffer(SYNC_BUFFER_MSB - 1 downto 0) & input;
        end if;
        output <= sync_input;
    end process;

end architecture;
Source Link
tim
  • 920
  • 7
  • 13
Loading