---------------------------------------------------------------------------- -- fifo_reset.vhd -- FIFO Reset Manager -- Version 1.0 -- -- Copyright (C) 2013 H.Poetzl -- -- This program is free software: you can redistribute it and/or -- modify it under the terms of the GNU General Public License -- as published by the Free Software Foundation, either version -- 2 of the License, or (at your option) any later version. ---------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.ALL; entity fifo_reset is port ( wclk : in std_logic; rclk : in std_logic; reset : in std_logic; -- fifo_rst : out std_logic; fifo_rdy : out std_logic ); end entity fifo_reset; architecture RTL of fifo_reset is begin reset_proc : process(wclk, rclk, reset) variable wcnt_v : natural range 7 downto 0; variable rcnt_v : natural range 7 downto 0; variable wrdy_v : std_logic := '0'; variable rrdy_v : std_logic := '0'; variable rst_v : std_logic := '0'; type state_t is (ready_s, delay_s, pre_s, reset_s, post_s); variable wstate : state_t := delay_s; variable rstate : state_t := delay_s; begin if rising_edge(wclk) then case wstate is when ready_s => -- fifo write ready if reset = '1' then wrdy_v := '0'; wstate := delay_s; end if; when delay_s => -- delay by 1 wclk wstate := pre_s; when pre_s => wcnt_v := 4; if rst_v = '1' then -- wait for sync wstate := reset_s; end if; when reset_s => if wcnt_v = 0 then if reset = '0' then wstate := post_s; end if; else wcnt_v := wcnt_v - 1; end if; when post_s => if wcnt_v = 2 then if rst_v = '0' then -- wait for sync wrdy_v := '1'; wstate := ready_s; end if; else wcnt_v := wcnt_v + 1; end if; end case; end if; if rising_edge(rclk) then case rstate is when ready_s => -- fifo read ready if reset = '1' then rrdy_v := '0'; rstate := delay_s; end if; when delay_s => -- delay by 1 rclk rstate := pre_s; when pre_s => rcnt_v := 4; if rst_v = '1' then -- wait for sync rstate := reset_s; end if; when reset_s => if rcnt_v = 0 then if reset = '0' then rstate := post_s; end if; else rcnt_v := rcnt_v - 1; end if; when post_s => if rcnt_v = 2 then if rst_v = '0' then -- wait for sync rrdy_v := '1'; rstate := ready_s; end if; else rcnt_v := rcnt_v + 1; end if; end case; end if; if wstate = pre_s and rstate = pre_s then rst_v := '1'; elsif wstate = post_s and rstate = post_s then rst_v := '0'; end if; fifo_rdy <= wrdy_v and rrdy_v; fifo_rst <= rst_v; end process; end RTL;