VHDL Code for Synchronizer: Syntax, Example, and Tips
A
synchronizer in VHDL is typically implemented using a chain of flip-flops to safely transfer an asynchronous signal into a clock domain. The basic code uses a single process block with sequential assignments to registers triggered by the clock edge, reducing metastability risks.Syntax
A synchronizer uses flip-flops connected in series, clocked by the destination clock. Each flip-flop stage holds the signal for one clock cycle, allowing metastability to settle.
Key parts:
- signal_in: asynchronous input signal
- clk: clock signal for synchronization
- sync_reg: internal registers holding intermediate states
- signal_out: synchronized output signal
vhdl
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity synchronizer is
Port (
clk : in std_logic;
signal_in : in std_logic;
signal_out : out std_logic
);
end synchronizer;
architecture Behavioral of synchronizer is
signal sync_reg : std_logic_vector(1 downto 0);
begin
process(clk)
begin
if rising_edge(clk) then
sync_reg(0) <= signal_in;
sync_reg(1) <= sync_reg(0);
end if;
end process;
signal_out <= sync_reg(1);
end Behavioral;Example
This example shows a 2-stage synchronizer that safely transfers an asynchronous input signal_in into the clock domain clk. The output signal_out is the synchronized signal.
vhdl
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity synchronizer is
Port (
clk : in std_logic;
signal_in : in std_logic;
signal_out : out std_logic
);
end synchronizer;
architecture Behavioral of synchronizer is
signal sync_reg : std_logic_vector(1 downto 0);
begin
process(clk)
begin
if rising_edge(clk) then
sync_reg(0) <= signal_in;
sync_reg(1) <= sync_reg(0);
end if;
end process;
signal_out <= sync_reg(1);
end Behavioral;Common Pitfalls
Common mistakes when writing synchronizers include:
- Using only one flip-flop stage, which risks metastability.
- Not clocking the synchronizer registers with the destination clock.
- Assigning signals combinationally instead of sequentially inside a clocked process.
- Forgetting to declare intermediate registers to hold the signal between stages.
Correct usage requires at least two flip-flops in series clocked by the destination clock to reduce metastability risk.
vhdl
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Wrong: single flip-flop, no metastability protection
entity bad_synchronizer is
Port (
clk : in std_logic;
signal_in : in std_logic;
signal_out : out std_logic
);
end bad_synchronizer;
architecture Behavioral of bad_synchronizer is
begin
process(clk)
begin
if rising_edge(clk) then
signal_out <= signal_in; -- Only one stage, unsafe
end if;
end process;
end Behavioral;
-- Right: two flip-flop stages
entity good_synchronizer is
Port (
clk : in std_logic;
signal_in : in std_logic;
signal_out : out std_logic
);
end good_synchronizer;
architecture Behavioral of good_synchronizer is
signal sync_reg : std_logic_vector(1 downto 0);
begin
process(clk)
begin
if rising_edge(clk) then
sync_reg(0) <= signal_in;
sync_reg(1) <= sync_reg(0);
end if;
end process;
signal_out <= sync_reg(1);
end Behavioral;Quick Reference
- Use at least two flip-flops in series for synchronization.
- Clock all flip-flops with the destination clock domain.
- Use sequential assignments inside a clocked process.
- Declare intermediate signals to hold data between stages.
- Do not use combinational logic for synchronization registers.
Key Takeaways
Always use at least two flip-flops clocked by the destination clock to reduce metastability.
Implement synchronizers with sequential logic inside a clocked process.
Avoid using a single flip-flop stage for asynchronous signal synchronization.
Declare intermediate signals to hold the signal between flip-flop stages.
Never use combinational assignments for synchronizer registers.