56 lines
2.2 KiB
VHDL
56 lines
2.2 KiB
VHDL
-- -------------------------------------------------------------------------- --
|
|
-- TRASHERNET SoC - A Trashy Ethernet SoC for FPGAs --
|
|
-- -------------------------------------------------------------------------- --
|
|
-- TODO
|
|
-- -------------------------------------------------------------------------- --
|
|
-- Author : Markus Koch <markus@notsyncing.net>
|
|
-- 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;
|