@ -1,10 +1,11 @@
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				library ieee;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				use ieee.std_logic_1164.all;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				use ieee.numeric_std.all;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				entity soc_reset is
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    generic (
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        PLL_RESET_CLOCKS : integer := 32;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        SOC_RESET_CLOCKS : integer := 32;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        PLL_RESET_BITS   : integer := 5;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        SOC_RESET_BITS   : integer := 5;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        RESET_LOW        : boolean := true
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        );
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    port (
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -20,26 +21,38 @@ entity soc_reset is
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				end soc_reset;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				architecture rtl of soc_reset is
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    signal ext_rst_n     : std_ulogic;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    signal rst_n         : std_ulogic;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    signal pll_rst_reg : std_ulogic_vector(PLL_RESET_CLOCKS downto 0) := (others => '1');
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    signal soc_rst_reg   : std_ulogic_vector(SOC_RESET_CLOCKS downto 0) := (others => '1');
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    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_rst_n <= ext_rst_in when RESET_LOW else not ext_rst_in;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    rst_n <= ext_rst_n and pll_locked_in;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    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 <= pll_rst_reg(0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    pll_rst_out <= not pll_rst_cnt(pll_rst_cnt'left);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    -- Pass active high reset around
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    rst_out <= soc_rst_reg(0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    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
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            pll_rst_reg <= '0' & pll_rst_reg(pll_rst_reg'length-1 downto 1);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            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;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -49,10 +62,12 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    soc_reset_0 : process(pll_clk)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if (rising_edge(pll_clk)) then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if (rst_n = '0') then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                soc_rst_reg <= (others => '1');
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                soc_rst_reg <= '0' & soc_rst_reg(soc_rst_reg'length-1 downto 1);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            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;