commit
						14da542d4a
					
				@ -1,69 +0,0 @@
 | 
			
		||||
-- The Potato Processor - A simple processor for FPGAs
 | 
			
		||||
-- (c) Kristian Klomsten Skordal 2018 <kristian.skordal@wafflemail.net>
 | 
			
		||||
 | 
			
		||||
library ieee;
 | 
			
		||||
use ieee.std_logic_1164.all;
 | 
			
		||||
use work.pp_utilities.all;
 | 
			
		||||
 | 
			
		||||
--! @brief System reset unit.
 | 
			
		||||
--! Because most resets in the processor core are synchronous, at least one
 | 
			
		||||
--! clock pulse has to be given to the processor while the reset signal is
 | 
			
		||||
--! asserted. However, if the clock generator is being reset at the same time,
 | 
			
		||||
--! the system clock might not run during reset, preventing the processor from
 | 
			
		||||
--! properly resetting.
 | 
			
		||||
entity pp_soc_reset is
 | 
			
		||||
	generic(
 | 
			
		||||
		RESET_CYCLE_COUNT : natural := 20000000
 | 
			
		||||
	);
 | 
			
		||||
	port(
 | 
			
		||||
		clk : in std_logic;
 | 
			
		||||
 | 
			
		||||
		reset_n   : in  std_logic;
 | 
			
		||||
		reset_out : out std_logic;
 | 
			
		||||
 | 
			
		||||
		system_clk        : in std_logic;
 | 
			
		||||
		system_clk_locked : in std_logic
 | 
			
		||||
	);
 | 
			
		||||
end entity pp_soc_reset;
 | 
			
		||||
 | 
			
		||||
architecture behaviour of pp_soc_reset is
 | 
			
		||||
 | 
			
		||||
	subtype counter_type is natural range 0 to RESET_CYCLE_COUNT;
 | 
			
		||||
	signal counter : counter_type;
 | 
			
		||||
 | 
			
		||||
	signal fast_reset : std_logic := '0';
 | 
			
		||||
	signal slow_reset : std_logic := '1';
 | 
			
		||||
begin
 | 
			
		||||
 | 
			
		||||
	reset_out <= slow_reset;
 | 
			
		||||
 | 
			
		||||
--	process(clk)
 | 
			
		||||
--	begin
 | 
			
		||||
--		if rising_edge(clk) then
 | 
			
		||||
--			if reset_n = '0' then
 | 
			
		||||
--				fast_reset <= '1';
 | 
			
		||||
--			elsif system_clk_locked = '1' then
 | 
			
		||||
--				if fast_reset = '1' and slow_reset = '1' then
 | 
			
		||||
--					fast_reset <= '0';
 | 
			
		||||
--				end if;
 | 
			
		||||
--			end if;
 | 
			
		||||
--		end if;
 | 
			
		||||
--	end process;
 | 
			
		||||
 | 
			
		||||
	process(system_clk)
 | 
			
		||||
	begin
 | 
			
		||||
		if rising_edge(system_clk) then
 | 
			
		||||
			if reset_n = '0' then
 | 
			
		||||
				slow_reset <= '1';
 | 
			
		||||
				counter <= RESET_CYCLE_COUNT;
 | 
			
		||||
			else
 | 
			
		||||
				if counter = 0 then
 | 
			
		||||
					slow_reset <= '0';
 | 
			
		||||
				else
 | 
			
		||||
					counter <= counter - 1;
 | 
			
		||||
				end if;
 | 
			
		||||
			end if;
 | 
			
		||||
		end if;
 | 
			
		||||
	end process;
 | 
			
		||||
 | 
			
		||||
end architecture behaviour;
 | 
			
		||||
@ -0,0 +1,59 @@
 | 
			
		||||
library ieee;
 | 
			
		||||
use ieee.std_logic_1164.all;
 | 
			
		||||
 | 
			
		||||
entity soc_reset is
 | 
			
		||||
    generic (
 | 
			
		||||
        PLL_RESET_CLOCKS : integer := 32;
 | 
			
		||||
        SOC_RESET_CLOCKS : integer := 32;
 | 
			
		||||
        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_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');
 | 
			
		||||
begin
 | 
			
		||||
    ext_rst_n <= ext_rst_in when RESET_LOW else not ext_rst_in;
 | 
			
		||||
    rst_n <= ext_rst_n and pll_locked_in;
 | 
			
		||||
 | 
			
		||||
    -- PLL reset is active high
 | 
			
		||||
    pll_rst_out <= pll_rst_reg(0);
 | 
			
		||||
    -- Pass active high reset around
 | 
			
		||||
    rst_out <= soc_rst_reg(0);
 | 
			
		||||
 | 
			
		||||
    -- 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.
 | 
			
		||||
    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);
 | 
			
		||||
        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
 | 
			
		||||
            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);
 | 
			
		||||
            end if;
 | 
			
		||||
        end if;
 | 
			
		||||
    end process;
 | 
			
		||||
end rtl;
 | 
			
		||||
@ -0,0 +1,106 @@
 | 
			
		||||
library ieee;
 | 
			
		||||
use ieee.std_logic_1164.all;
 | 
			
		||||
 | 
			
		||||
entity soc_reset_tb is
 | 
			
		||||
end soc_reset_tb;
 | 
			
		||||
 | 
			
		||||
architecture behave of soc_reset_tb is
 | 
			
		||||
    signal ext_clk       : std_ulogic;
 | 
			
		||||
    signal pll_clk       : std_ulogic;
 | 
			
		||||
 | 
			
		||||
    signal pll_locked_in : std_ulogic;
 | 
			
		||||
    signal ext_rst_in    : std_ulogic;
 | 
			
		||||
 | 
			
		||||
    signal pll_rst_out          : std_ulogic;
 | 
			
		||||
    signal pll_rst_out_expected : std_ulogic;
 | 
			
		||||
    signal rst_out                : std_ulogic;
 | 
			
		||||
    signal rst_out_expected       : std_ulogic;
 | 
			
		||||
 | 
			
		||||
    constant clk_period : time := 10 ns;
 | 
			
		||||
 | 
			
		||||
    type test_vector is record
 | 
			
		||||
        pll_locked_in : std_ulogic;
 | 
			
		||||
        ext_rst_in    : std_ulogic;
 | 
			
		||||
        pll_rst_out : std_ulogic;
 | 
			
		||||
        rst_out       : std_ulogic;
 | 
			
		||||
    end record;
 | 
			
		||||
 | 
			
		||||
    type test_vector_array is array (natural range <>) of test_vector;
 | 
			
		||||
    constant test_vectors : test_vector_array := (
 | 
			
		||||
        -- PLL not locked, reset button not pressed
 | 
			
		||||
        ('0', '1', '1', '1'),
 | 
			
		||||
        ('0', '1', '1', '1'),
 | 
			
		||||
        ('0', '1', '1', '1'),
 | 
			
		||||
        ('0', '1', '1', '1'),
 | 
			
		||||
        -- Reset is removed from the PLL
 | 
			
		||||
        ('0', '1', '0', '1'),
 | 
			
		||||
        ('0', '1', '0', '1'),
 | 
			
		||||
        ('0', '1', '0', '1'),
 | 
			
		||||
        -- At some point PLL comes out of reset
 | 
			
		||||
        ('1', '1', '0', '1'),
 | 
			
		||||
        ('1', '1', '0', '1'),
 | 
			
		||||
        ('1', '1', '0', '1'),
 | 
			
		||||
        ('1', '1', '0', '1'),
 | 
			
		||||
        -- Finally SOC comes out of reset
 | 
			
		||||
        ('1', '1', '0', '0'),
 | 
			
		||||
        ('1', '1', '0', '0'),
 | 
			
		||||
 | 
			
		||||
        -- PLL locked, reset button pressed
 | 
			
		||||
        ('1', '0', '0', '1'),
 | 
			
		||||
        ('1', '0', '0', '1'),
 | 
			
		||||
        ('1', '0', '0', '1'),
 | 
			
		||||
        -- PLL locked, reset button released
 | 
			
		||||
        ('1', '1', '0', '1'),
 | 
			
		||||
        ('1', '1', '0', '1'),
 | 
			
		||||
        ('1', '1', '0', '1'),
 | 
			
		||||
        -- Finally SOC comes out of reset
 | 
			
		||||
        ('1', '1', '0', '0')
 | 
			
		||||
        );
 | 
			
		||||
begin
 | 
			
		||||
    soc_reset_0: entity work.soc_reset
 | 
			
		||||
        generic map (
 | 
			
		||||
            PLL_RESET_CLOCKS => 4,
 | 
			
		||||
            SOC_RESET_CLOCKS => 4,
 | 
			
		||||
            RESET_LOW => true
 | 
			
		||||
            )
 | 
			
		||||
        port map (
 | 
			
		||||
            ext_clk => ext_clk,
 | 
			
		||||
            pll_clk => pll_clk,
 | 
			
		||||
            pll_locked_in => pll_locked_in,
 | 
			
		||||
            ext_rst_in => ext_rst_in,
 | 
			
		||||
            pll_rst_out => pll_rst_out,
 | 
			
		||||
            rst_out => rst_out
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
    clock: process
 | 
			
		||||
    begin
 | 
			
		||||
        ext_clk <= '0';
 | 
			
		||||
        pll_clk <= '0';
 | 
			
		||||
        wait for clk_period/2;
 | 
			
		||||
        ext_clk <= '1';
 | 
			
		||||
        pll_clk <= '1';
 | 
			
		||||
        wait for clk_period/2;
 | 
			
		||||
    end process clock;
 | 
			
		||||
 | 
			
		||||
    stim: process
 | 
			
		||||
    begin
 | 
			
		||||
        for i in test_vectors'range loop
 | 
			
		||||
            (pll_locked_in, ext_rst_in, pll_rst_out_expected, rst_out_expected) <= test_vectors(i);
 | 
			
		||||
 | 
			
		||||
            --report "pll_locked_in " & std_ulogic'image(pll_locked_in);
 | 
			
		||||
            --report "ext_rst_in " & std_ulogic'image(ext_rst_in);
 | 
			
		||||
            --report "pll_rst_out " & std_ulogic'image(pll_rst_out);
 | 
			
		||||
            --report "rst_out" & std_ulogic'image(rst_out);
 | 
			
		||||
 | 
			
		||||
            assert pll_rst_out_expected = pll_rst_out report "pll_rst_out bad";
 | 
			
		||||
            assert rst_out_expected = rst_out report "rst_out bad";
 | 
			
		||||
 | 
			
		||||
            wait for clk_period;
 | 
			
		||||
        end loop;
 | 
			
		||||
 | 
			
		||||
	wait for clk_period;
 | 
			
		||||
 | 
			
		||||
        assert false report "end of test" severity failure;
 | 
			
		||||
        wait;
 | 
			
		||||
    end process;
 | 
			
		||||
end behave;
 | 
			
		||||
					Loading…
					
					
				
		Reference in New Issue