--------------------------------------------------------------------------------------------------------------- -- RISA Project -- Author: A.Greensted -- Module: -- Description: -- History: --------------------------------------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library CommonLib; use CommonLib.CommonPkg.all; entity WatchDogTimer is port ( clk : in std_logic; enable : in std_logic; nReset : in std_logic; dIn : in std_logic_vector(15 downto 0); controlRegWEn : in std_logic; controlRegOut : out std_logic_vector(15 downto 0); timerWEn : in std_logic; timerOut : out std_logic_vector(15 downto 0); timeoutIF : out std_logic); end WatchDogTimer; architecture General of WatchDogTimer is signal count : unsigned(15 downto 0); -- Controls: Counter input signal timerEn : std_logic; signal prescalerReset : std_logic; signal prescalerSel : std_logic_vector(2 downto 0); -- Prescaler outputs signal count1 : std_logic; signal count3 : std_logic; signal count15 : std_logic; signal count63 : std_logic; signal count255 : std_logic; signal count1023 : std_logic; signal count2047 : std_logic; signal scalerOut : std_logic; signal scaledCountEn : std_logic; signal timeout : std_logic; begin timerOut <= std_logic_vector(count); controlRegOut(15 downto 5) <= (others => '0'); controlRegOut(4) <= timerEn; controlRegOut(3) <= '0'; -- Always read prescalerReset as 0 controlRegOut(2 downto 0) <= prescalerSel; -- RegWriteControl ------------------------------------------------------------------------------------------- -- Controls writing to control register --------------------------------------------------------------------------------------------------------------- RegWriteControl : process(clk) begin if (clk'event and clk='1') then prescalerReset <= '0'; -- reset this to zero if (nReset='0') then timerEn <= '0'; prescalerReset <= '0'; prescalerSel <= b"000"; elsif (enable='1') then -- Control Reg Write if (controlRegWEn = '1') then timerEn <= dIn(4); prescalerReset <= dIn(3); prescalerSel <= dIn(2 downto 0); end if; end if; end if; end process RegWriteControl; -- PrescaleCounter -------------------------------------------------------------------------------------------- -- Used to prescale the enable pulses. for counter longer periods, at lesser resolution --------------------------------------------------------------------------------------------------------------- PrescaleCounter : process(clk) variable count : unsigned(10 downto 0); begin if (clk'event and clk='1') then if (nReset='0' or prescalerReset='1' or timerWEn='1') then count := (others => '0'); count1 <= '0'; count3 <= '0'; count15 <= '0'; count63 <= '0'; count255 <= '0'; count1023 <= '0'; count2047 <= '0'; elsif (enable='1' and timerEn='1') then count := count + 1; count1 <= '0'; count3 <= '0'; count15 <= '0'; count63 <= '0'; count255 <= '0'; count1023 <= '0'; count2047 <= '0'; if (count(0)='1') then count1 <= '1'; end if; if (count(1 downto 0)=b"11") then count3 <= '1'; end if; if (count(3 downto 0)=b"1111") then count15 <= '1'; end if; if (count(5 downto 0)=b"11_1111") then count63 <= '1'; end if; if (count(7 downto 0)=b"1111_1111") then count255 <= '1'; end if; if (count(9 downto 0)=b"11_1111_1111") then count1023 <= '1'; end if; if (count(10 downto 0)=b"111_1111_1111") then count2047 <= '1'; end if; end if; end if; end process PrescaleCounter; -- ScaleSelector ---------------------------------------------------------------------------------------------- -- Mux to select the require prescale ammount --------------------------------------------------------------------------------------------------------------- ScaleSelector: scalerOut <= timerEn when prescalerSel = b"000" else count1 when prescalerSel = b"001" else count3 when prescalerSel = b"010" else count15 when prescalerSel = b"011" else count63 when prescalerSel = b"100" else count255 when prescalerSel = b"101" else count1023 when prescalerSel = b"110" else count2047 when prescalerSel = b"111" else '0'; scaledCountEn <= timerEn and scalerOut; -- Timer ------------------------------------------------------------------------------------------------------ -- The actual Timer --------------------------------------------------------------------------------------------------------------- Timer : process(clk) begin if (clk'event and clk='1') then if (nReset='0') then count <= (others => '0'); elsif (enable='1') then if (timerWEn='1') then count <= unsigned(dIn); elsif (scaledCountEn='1') then if (timeout='0') then count <= count + 1; end if; end if; end if; end if; end process Timer; -- Timeout Detect --------------------------------------------------------------------------------------------- -- Generates the match signals --------------------------------------------------------------------------------------------------------------- timeout <= '1' when count=x"FFFF" else '0'; TimeoutPulseGenerator : PulseGenerator port map ( clk => clk, nReset => nReset, enable => enable, input => timeout, pulse => timeoutIF); end General;