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