-- -- Sync async 40MHz input via 120MHz to internal 40MHz -- cnt = fsm: when 2 cycles = 1 then output high -- signal too short: 000 001 000 -- signal min 2cycles(16.6 ns): -- normal: -- in __.-1---2---3--.___ -- cnt 000 001 010 011 100 000 -- out _______.-----1-----.____ -- -- short signals: -- in __.-1-.___.-1---2-.___ -- cnt 000 001 000 001 010 011 100 000 -- out ________________.-----1-----.___ -- -- long signals: -- in _.-1---2---3---4---5-._____________ -- cnt 000 001 010 011 101 010 011 100 000 -- out _______.-----1-----------2-----.___ -- library ieee; use ieee.std_logic_1164.all; entity asyncin is generic ( oreg : boolean := true); port ( clk40 : in std_logic; clk120 : in std_logic; reset_n : in std_logic; ain : in std_logic; -- async in s40out : out std_logic); -- sync to 40 out end asyncin; architecture behv of asyncin is signal cnt : std_logic_vector(2 downto 0); signal sin : std_logic; -- sync in signal s120, s40 : std_logic; begin -- behv process (clk120) begin -- process if clk120'event and clk120 = '1' then -- rising clock edge sin <= ain; end if; end process; process (clk120, reset_n) begin -- process if reset_n = '0' then -- asynchronous reset (active low) cnt <= "000"; elsif clk120'event and clk120 = '1' then -- rising clock edge if sin = '1' and cnt <= "000" then cnt <= "001"; elsif cnt = "001" and sin = '1' then cnt <= "010"; elsif cnt = "001" and sin = '0' then cnt <= "000"; elsif cnt = "010" then cnt <= "011"; elsif cnt = "011" and sin = '1' then cnt <= "101"; elsif cnt = "011" and sin = '0' then cnt <= "100"; elsif cnt = "100" and sin = '1' then cnt <= "010"; elsif cnt = "101" and sin = '1' then cnt <= "010"; elsif cnt = "101" and sin = '0' then cnt <= "000"; else cnt <= "000"; end if; end if; end process; s120 <= '0' when cnt = "000" or cnt ="001" else '1'; oreg_g : if oreg generate process (clk40) begin -- process if clk40'event and clk40 = '1' then -- rising clock edge s40 <= s120; end if; end process; end generate oreg_g; noreg : if not oreg generate s40 <= s120; end generate noreg; s40out <= s40; end behv;