/*-------------------------------------------------------------------------------
-- Title      : Custom AHB slave
-------------------------------------------------------------------------------
-- File       : Interrupt_Source.v
-- Author     : Pavan Marisetti
-- Company    : Microsemi Corporation
-- Device     : SmartFusion
-- Standard   : Verilog
-------------------------------------------------------------------------------
-- 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
-------------------------------------------------------------------------------*/
module Interrupt_Source (

                             input            SWITCH_N,
                             input            FAB_CLK,
                             input            FAB_LOCK,
                             output reg       SWITCH_INTRPT,
                             output reg       COUNTER1_INTRPT,
                             output reg       COUNTER2_INTRPT

                           );

   reg          switch_intrpt_temp,
                switch_intrpt_temp1, switch_intrpt_temp2;
   reg  [31:0]  counter1, counter2;



   /* Synchonization of Asynchronous switch input */
   always@(posedge FAB_CLK or negedge SWITCH_N)
   if(~SWITCH_N)
     begin
       switch_intrpt_temp   <= 1'b0;
       switch_intrpt_temp1  <= 1'b0;
       switch_intrpt_temp2  <= 1'b0;

     end
   else
     begin
       switch_intrpt_temp <= 1'b1;
       switch_intrpt_temp1 <= switch_intrpt_temp;
       switch_intrpt_temp2 <= switch_intrpt_temp1;
     end

   /* Pulse detection and pulse generation logic */
   always@(posedge FAB_CLK or negedge FAB_LOCK)
   if(~FAB_LOCK)
     begin
       SWITCH_INTRPT   <= 1'b0;
     end
   else
     begin
       if(switch_intrpt_temp1 == 1'b1 && switch_intrpt_temp2 == 1'b0)
         begin
           SWITCH_INTRPT   <= 1'b1;
         end
       else
         begin
           SWITCH_INTRPT   <= 1'b0;
         end
     end

   /* Timer  implemetation and generation of Fabric intrrupt upon the expiry of
      timer value. The timer value is 2000001 clock cycles of FAB_CLK */

   always@(posedge FAB_CLK or negedge FAB_LOCK)
   if(~FAB_LOCK)
     begin
       counter1 <= 32'h00000000;
       COUNTER1_INTRPT   <= 1'b0;
     end
   else
     begin
       if(counter1 == 32'h001E8480)
         begin
           counter1 <= 32'h00000000;
           COUNTER1_INTRPT   <= 1'b1;
         end
       else
         begin
           counter1 <= counter1 + 1;
           COUNTER1_INTRPT   <= 1'b0;
         end
     end


   /* Timer  implemetation and generation of Fabric intrrupt upon the expiry of
      timer value. The timer value is 10000004 clock cycles of FAB_CLK */

   always@(posedge FAB_CLK or negedge FAB_LOCK)
   if(~FAB_LOCK)
     begin
       counter2 <= 32'h00000000;
       COUNTER2_INTRPT   <= 1'b0;
     end
   else
     begin
       if(counter2 == 32'h00989684)
         begin
           counter2 <= 32'h00000000;
           COUNTER2_INTRPT   <= 1'b1;
         end
       else
         begin
           counter2 <= counter2 + 1;
           COUNTER2_INTRPT   <= 1'b0;
         end
     end
endmodule