trashernet-soc/fpga/hdl/generics/synchronizer.vhd

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;