-------------------------------------------------------------------------------
--
-- (C) Copyright 2017 DFC Design, s.r.o., Brno, Czech Republic
-- Author: Marek Kvas (m.kvas@dspfpga.com)
--
-------------------------------------------------------------------------------
--
-- One bit clock domain crossing for Xilinx Vivado toolchain.
--
-------------------------------------------------------------------------------


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

entity xcdc is
   generic (
      g_length       : integer := 2;
      g_rst_val      : std_logic := '0';
      g_data_width   : integer := 1
           );
   port (
      RSTN        : in  std_logic;
      DCLK        : in  std_logic;
      DATA_IN     : in  std_logic_vector(g_data_width-1 downto 0);
      DATA_OUT    : out std_logic_vector(g_data_width-1 downto 0)
        );
end entity;


architecture synthesis of xcdc is
   type vector_array is array (natural range <>) of std_logic_vector(g_data_width-1 downto 0);
   signal dl   : vector_array(g_length - 1  downto 0) := (others=>(others => '0'));

   -- Prevent optimization like shift register replacement,
   -- ensure close placement of sync-chain and 
   -- make Vivado happy
   attribute ASYNC_REG           : string;
   attribute ASYNC_REG of dl     : signal is "true";

begin

   dl_shift_proc : process(DCLK)
   begin
      if rising_edge(DCLK) then
         if RSTN = '0' then
            for i in 0 to g_length-1 loop
               dl(i) <= (others => g_rst_val);
            end loop;
         else
            dl <= dl(dl'left - 1 downto 0) & DATA_IN;
         end if;
      end if;
   end process;

   DATA_OUT <= dl(dl'left);


end architecture;