-------------------------------------------------------------------------------
-- Title      : Custom AHB slave
-------------------------------------------------------------------------------
-- File       : Interrupt_Source.vhd
-- Author     : Haris Akkool
-- Company    : Microsemi Corporation
-- Device     : SmartFusion
-- Standard   : VHDL
-------------------------------------------------------------------------------
-- Description: This code creates two timers Timer1 and Timer2. Timer 1 generates
--              interrupt for every 2000001 clock cycles of FAB_CLK
--              Timer 2 generates interrupt for every 10000004 clock cycles.
--              Asynchronous input SWITCH_N is taken as interrupt. This input is
--              synchronized and detected using pulse detection logic.
-------------------------------------------------------------------------------
-- Copyright (c) 2011   Microsemi Corporation
--                      All rights reserved.
-------------------------------------------------------------------------------
-- Revisions  : V1.0
-------------------------------------------------------------------------------

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;

entity Interrupt_Source is
  port ( SWITCH_N        : in std_logic;
         FAB_CLK         : in std_logic;
         FAB_LOCK        : in std_logic;
         SWITCH_INTRPT   : out std_logic;
         COUNTER1_INTRPT : out std_logic;
         COUNTER2_INTRPT : out std_logic);


end Interrupt_Source;

architecture behav of Interrupt_Source is

signal switch_intrpt_temp  : std_logic;
signal switch_intrpt_temp1 : std_logic;
signal switch_intrpt_temp2 : std_logic;

signal counter1,counter2   : std_logic_vector(31 downto 0);

begin

-- Synchonization of Asynchronous switch input
 
process (FAB_CLK, SWITCH_N)
begin
   if(SWITCH_N = '0') then
       switch_intrpt_temp   <= '0';
       switch_intrpt_temp1  <= '0';
       switch_intrpt_temp2  <= '0';
   elsif (FAB_CLK'event and FAB_CLK='1') then
       switch_intrpt_temp   <= '1';
       switch_intrpt_temp1  <= switch_intrpt_temp;
       switch_intrpt_temp2  <= switch_intrpt_temp1;
   end if;
end process;

-- Pulse detection and pulse generation logic

process (FAB_CLK,FAB_LOCK)
begin
   if(FAB_LOCK = '0') then
         SWITCH_INTRPT   <= '0';
   elsif (FAB_CLK'event and FAB_CLK='1') then
      if(switch_intrpt_temp1 = '1' and switch_intrpt_temp2 = '0') then
         SWITCH_INTRPT   <= '1';
       else
         SWITCH_INTRPT   <= '0';
       end if;
    end if;
end process;
     
-- Timer1 implemetation and generation of Fabric intrrupt upon the expiry of
-- timer value. The timer value is 2000001 clock cycles of FAB_CLK 

process (FAB_CLK,FAB_LOCK)
begin
   if(FAB_LOCK = '0') then
       counter1          <= (others => '0');
       COUNTER1_INTRPT   <= '0';
   elsif (FAB_CLK'event and FAB_CLK='1') then
      if(counter1 = X"001E8480") then
        counter1         <= (others => '0');
        COUNTER1_INTRPT  <= '1';
      else
        counter1         <= counter1 + '1';
        COUNTER1_INTRPT  <= '0';
      end if;
    end if;
end process;

-- Timer2 implemetation and generation of Fabric intrrupt upon the expiry of
-- timer value. The timer value is 10000004 clock cycles of FAB_CLK 

process (FAB_CLK,FAB_LOCK)
begin
   if(FAB_LOCK = '0') then
       counter2          <= (others => '0');
       COUNTER2_INTRPT   <= '0';
   elsif (FAB_CLK'event and FAB_CLK='1') then
      if(counter2 = X"00989684") then
        counter2         <= (others => '0');
        COUNTER2_INTRPT  <= '1';
      else
        counter2         <= counter2 + '1';
        COUNTER2_INTRPT  <= '0';
      end if;
    end if;
end process;

end behav;

