library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity soc_reset is generic ( PLL_RESET_BITS : integer := 5; SOC_RESET_BITS : integer := 5; RESET_LOW : boolean := true ); port ( ext_clk : in std_ulogic; pll_clk : in std_ulogic; pll_locked_in : in std_ulogic; ext_rst_in : in std_ulogic; pll_rst_out : out std_ulogic; rst_out : out std_ulogic ); end soc_reset; architecture rtl of soc_reset is signal ext_rst0_n : std_ulogic; signal ext_rst1_n : std_ulogic := '0'; signal ext_rst2_n : std_ulogic := '0'; signal rst0_n : std_ulogic; signal rst1_n : std_ulogic := '0'; signal rst2_n : std_ulogic := '0'; signal pll_rst_cnt : std_ulogic_vector(PLL_RESET_BITS downto 0) := (others => '0'); signal soc_rst_cnt : std_ulogic_vector(SOC_RESET_BITS downto 0) := (others => '0'); begin ext_rst0_n <= ext_rst_in when RESET_LOW else not ext_rst_in; rst0_n <= ext_rst0_n and pll_locked_in and not pll_rst_out; -- PLL reset is active high pll_rst_out <= not pll_rst_cnt(pll_rst_cnt'left); -- Pass active high reset around rst_out <= not soc_rst_cnt(soc_rst_cnt'left); -- Wait for external clock to become stable before starting the PLL -- By the time the FPGA has been loaded the clock should be well and -- truly stable, but lets give it a few cycles to be sure. -- -- [BenH] Some designs seem to require a lot more.. pll_reset_0 : process(ext_clk) begin if (rising_edge(ext_clk)) then ext_rst1_n <= ext_rst0_n; ext_rst2_n <= ext_rst1_n; if (ext_rst2_n = '0') then pll_rst_cnt <= (others => '0'); elsif (pll_rst_cnt(pll_rst_cnt'left) = '0') then pll_rst_cnt <= std_ulogic_vector(unsigned(pll_rst_cnt) + 1); end if; end if; end process; -- Once our clock is stable and the external reset button isn't being -- pressed, assert the SOC reset for long enough for the CPU pipeline -- to clear completely. soc_reset_0 : process(pll_clk) begin if (rising_edge(pll_clk)) then rst1_n <= rst0_n; rst2_n <= rst1_n; if (rst2_n = '0') then soc_rst_cnt <= (others => '0'); elsif (soc_rst_cnt(soc_rst_cnt'left) = '0') then soc_rst_cnt <= std_ulogic_vector(unsigned(soc_rst_cnt) + 1); end if; end if; end process; end rtl;