-- -------------------------------------------------------------------------- -- -- TRASHERNET SoC - A Trashy Ethernet SoC for FPGAs -- -- -------------------------------------------------------------------------- -- -- TODO -- -------------------------------------------------------------------------- -- -- Author : Markus Koch -- Contributors : None -- License : Mozilla Public License (MPL) Version 2 -- -------------------------------------------------------------------------- -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity synchronizer is generic( init_value : std_logic := '0'; -- Default value of all synchronized signals after reset (ignored when `init_value_v` is set) init_value_v : std_logic_vector := ""; -- Set this reset the bits of the vector individually, leave "" to use `init_value` for all. stages : natural := 2 -- Number of synchronizer flip flops per channel ); port( clk : in std_logic; -- Synchronizer clock rst : in std_logic; -- Asynchronous reset data_in_a : in std_logic_vector; -- Asynchronous signal input data_out : out std_logic_vector -- Synchronized signal output ); end entity synchronizer; architecture rtl of synchronizer is type synchronizer_chain_t is array (stages - 1 downto 0) of std_logic_vector(data_in_a'range); signal synchronizer_chain : synchronizer_chain_t; begin assert ((init_value_v'length = 0) or (init_value_v'length = data_in_a'length)) report "init_value_v must have the same width as data_in_a when used" severity error; sync_p : process(clk, rst) is begin if (rst = '1') then if (init_value_v'length = 0) then synchronizer_chain <= (others => (others => init_value)); else synchronizer_chain <= (others => init_value_v); end if; elsif (rising_edge(clk)) then for i in synchronizer_chain'high - 1 downto synchronizer_chain'low loop synchronizer_chain(i + 1) <= synchronizer_chain(i); end loop; synchronizer_chain(0) <= data_in_a; end if; end process sync_p; data_out <= synchronizer_chain(synchronizer_chain'high); end architecture rtl;