-----------------------------------------------------------------------
-- PicoBlaze IRQ controller
--
--  Vylepsena verze
--
-- Any interrupt comming to this block (int_1 to int_4) is converted to
-- one interrupt signal connected to PicoBlaze processor. The address of
-- active interrupt input is stored in data register available on address
-- given by the INT_controler generic parameter "port_ID".
-- There is a priority on interrupt inputs. If there are
-- several concurrent requests at one time, the one with lower number
-- will be reported to the processor first.
--
-- The request is not cleared by int_ACK signal from processor, but by
-- reading value of the active interrupt vector from the register.
--
-- The priority encoding has the following rule:
--  > The first interrupt comming to the controller is reported to the processor.
--  > If there are more at once and no one is reported to processor, the one with
--    highest priority is forwarded.
--  > If there is an active interrupt, other new interrupts must wait until
--    the active one is serviced (once) no matter how high their priority is.
--
--
-- Status:
--  COMPLETE        YES
--  SIMULATED       YES
--  TESTED          YES
--
--
-- int_en1_port_ID
-- [0] enable interrupt 1
-- [1] enable interrupt 2
-- [2] enable interrupt 3
-- [3] enable interrupt 4
-- [4] enable interrupt 5
-- [5] enable interrupt 6
-- [6] enable interrupt 7
-- [7] enable interrupt 8
--
-- int_en2_port_ID
-- [0] enable interrupt  9
-- [1] enable interrupt 10
-- [2] enable interrupt 11
-- [3] enable interrupt 12
-- [4] enable interrupt 13
-- [5] enable interrupt 14
-- [6] enable interrupt 15
-- [7] enable interrupt 16
--
--  int_edg1_port_ID
-- [0] interrupt 1 edge sensitive (when H)
-- [1] interrupt 2 edge sensitive (when H)
-- [2] interrupt 3 edge sensitive (when H)
-- [3] interrupt 4 edge sensitive (when H)
-- [4] interrupt 5 edge sensitive (when H)
-- [5] interrupt 6 edge sensitive (when H)
-- [6] interrupt 7 edge sensitive (when H)
-- [7] interrupt 8 edge sensitive (when H)
--
--  int_edg2_port_ID
-- [0] interrupt  9 edge sensitive (when H)
-- [1] interrupt 10 edge sensitive (when H)
-- [2] interrupt 11 edge sensitive (when H)
-- [3] interrupt 12 edge sensitive (when H)
-- [4] interrupt 13 edge sensitive (when H)
-- [5] interrupt 14 edge sensitive (when H)
-- [6] interrupt 15 edge sensitive (when H)
-- [7] interrupt 16 edge sensitive (when H)
--
--#####################################################################
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library UNISIM;
use UNISIM.Vcomponents.ALL;
--#####################################################################
ENTITY INT_controler_16 IS
  GENERIC(
    data_port_ID:           STD_LOGIC_VECTOR(7 DOWNTO 0):= "00000010";  -- Interrupt number register port ID
    int_en1_port_ID:        STD_LOGIC_VECTOR(7 DOWNTO 0):= "00000100";  -- Interrupt Enable status/control port ID
    int_en2_port_ID:        STD_LOGIC_VECTOR(7 DOWNTO 0):= "00000101";  -- Interrupt Enable status/control port ID
    int_edg1_port_ID:       STD_LOGIC_VECTOR(7 DOWNTO 0):= "00001000";  -- Interrupt Edge status/control port ID
    int_edg2_port_ID:       STD_LOGIC_VECTOR(7 DOWNTO 0):= "00001001"); -- Interrupt Edge status/control port ID
  PORT(
    clk:            IN  STD_LOGIC;
    rst:            IN  STD_LOGIC;

    -- interrupt inputs
    int_1:          IN  STD_LOGIC;      -- highest priority
    int_2:          IN  STD_LOGIC;
    int_3:          IN  STD_LOGIC;
    int_4:          IN  STD_LOGIC;
    int_5:          IN  STD_LOGIC;
    int_6:          IN  STD_LOGIC;
    int_7:          IN  STD_LOGIC;
    int_8:          IN  STD_LOGIC;
    int_9:          IN  STD_LOGIC;
    int_10:         IN  STD_LOGIC;
    int_11:         IN  STD_LOGIC;
    int_12:         IN  STD_LOGIC;
    int_13:         IN  STD_LOGIC;
    int_14:         IN  STD_LOGIC;
    int_15:         IN  STD_LOGIC;
    int_16:         IN  STD_LOGIC;      -- lowest priority

    -- processor interface
    Data_out:       OUT STD_LOGIC_VECTOR(7 DOWNTO 0);   -- Interrupt number OUT (PicoBlaze IN)
    int_en_out_1:   OUT STD_LOGIC_VECTOR(7 DOWNTO 0);   -- Enable status reg OUT (PicoBlaze IN)
    int_en_out_2:   OUT STD_LOGIC_VECTOR(7 DOWNTO 0);   -- Enable status reg OUT (PicoBlaze IN)
    int_edge_out_1: OUT STD_LOGIC_VECTOR(7 DOWNTO 0);   -- Edge status reg OUT (PicoBlaze IN)
    int_edge_out_2: OUT STD_LOGIC_VECTOR(7 DOWNTO 0);   -- Edge status reg OUT (PicoBlaze IN)
    Data_in:        IN  STD_LOGIC_VECTOR(7 DOWNTO 0);   -- Data IN (PicoBlaze OUT)
    Address:        IN  STD_LOGIC_VECTOR(7 DOWNTO 0);   -- Address IN (PicoBlaze Port ID OUT)
    read_strobe:    IN  STD_LOGIC;                      -- PicoBlaze read strobe
    write_strobe:   IN  STD_LOGIC;                      -- PicoBlaze write strobe
    proc_int:       OUT STD_LOGIC;                      -- PicoBlaze interrupt IN
    proc_int_ack:   IN  STD_LOGIC                       -- PicoBlaze interrupt ACK OUT
    );
END INT_controler_16;
--#####################################################################
ARCHITECTURE Behavioral OF INT_controler_16 IS
--#####################################################################
  SIGNAL  int_1i:       STD_LOGIC := '0';       -- latched interrupt  1
  SIGNAL  int_2i:       STD_LOGIC := '0';       -- latched interrupt  2
  SIGNAL  int_3i:       STD_LOGIC := '0';       -- latched interrupt  3
  SIGNAL  int_4i:       STD_LOGIC := '0';       -- latched interrupt  4
  SIGNAL  int_5i:       STD_LOGIC := '0';       -- latched interrupt  5
  SIGNAL  int_6i:       STD_LOGIC := '0';       -- latched interrupt  6
  SIGNAL  int_7i:       STD_LOGIC := '0';       -- latched interrupt  7
  SIGNAL  int_8i:       STD_LOGIC := '0';       -- latched interrupt  8
  SIGNAL  int_9i:       STD_LOGIC := '0';       -- latched interrupt  9
  SIGNAL int_10i:       STD_LOGIC := '0';       -- latched interrupt 10
  SIGNAL int_11i:       STD_LOGIC := '0';       -- latched interrupt 11
  SIGNAL int_12i:       STD_LOGIC := '0';       -- latched interrupt 12
  SIGNAL int_13i:       STD_LOGIC := '0';       -- latched interrupt 13
  SIGNAL int_14i:       STD_LOGIC := '0';       -- latched interrupt 14
  SIGNAL int_15i:       STD_LOGIC := '0';       -- latched interrupt 15
  SIGNAL int_16i:       STD_LOGIC := '0';       -- latched interrupt 16

  SIGNAL  int_1b:       STD_LOGIC := '0';       -- buffered interrupt 1
  SIGNAL  int_2b:       STD_LOGIC := '0';       -- buffered interrupt 2
  SIGNAL  int_3b:       STD_LOGIC := '0';       -- buffered interrupt 3
  SIGNAL  int_4b:       STD_LOGIC := '0';       -- buffered interrupt 4
  SIGNAL  int_5b:       STD_LOGIC := '0';       -- buffered interrupt 5
  SIGNAL  int_6b:       STD_LOGIC := '0';       -- buffered interrupt 6
  SIGNAL  int_7b:       STD_LOGIC := '0';       -- buffered interrupt 7
  SIGNAL  int_8b:       STD_LOGIC := '0';       -- buffered interrupt 8
  SIGNAL  int_9b:       STD_LOGIC := '0';       -- buffered interrupt 9
  SIGNAL int_10b:       STD_LOGIC := '0';       -- buffered interrupt 10
  SIGNAL int_11b:       STD_LOGIC := '0';       -- buffered interrupt 11
  SIGNAL int_12b:       STD_LOGIC := '0';       -- buffered interrupt 12
  SIGNAL int_13b:       STD_LOGIC := '0';       -- buffered interrupt 13
  SIGNAL int_14b:       STD_LOGIC := '0';       -- buffered interrupt 14
  SIGNAL int_15b:       STD_LOGIC := '0';       -- buffered interrupt 15
  SIGNAL int_16b:       STD_LOGIC := '0';       -- buffered interrupt 16

  SIGNAL proc_int_i:    STD_LOGIC := '0';       -- internal interrupt signal
  SIGNAL int_shreg:     STD_LOGIC_VECTOR(7 DOWNTO 0):= X"00";       -- shift register to delay new interrupt request
                                                                    -- so that picoblaze can disable it (by instruction)

  SIGNAL Data_int:      STD_LOGIC_VECTOR(7 DOWNTO 0):= X"00";

  SIGNAL int_en_1:      STD_LOGIC_VECTOR(7 DOWNTO 0):= X"0F";   -- Interrupt enable register
  SIGNAL int_en_2:      STD_LOGIC_VECTOR(7 DOWNTO 0):= X"0F";   -- Interrupt enable register
  SIGNAL int_edge_1:    STD_LOGIC_VECTOR(7 DOWNTO 0):= X"0F";   -- Interrupt edge sensitive register
  SIGNAL int_edge_2:    STD_LOGIC_VECTOR(7 DOWNTO 0):= X"0F";   -- Interrupt edge sensitive register
--#####################################################################
BEGIN
--#####################################################################
-- interrupt processing
  int_proc: PROCESS(clk, rst) BEGIN
  ---------------------------------------------------------------------
    IF rst = '1' THEN
      int_1i <= '0';
      int_2i <= '0';
      int_3i <= '0';
      int_4i <= '0';
      int_5i <= '0';
      int_6i <= '0';
      int_7i <= '0';
      int_8i <= '0';
      int_9i <= '0';
      int_10i <= '0';
      int_11i <= '0';
      int_12i <= '0';
      int_13i <= '0';
      int_14i <= '0';
      int_15i <= '0';
      int_16i <= '0';
    ELSIF clk'EVENT AND clk = '1' THEN
  ---------------------------------------------------------------------
      -- buffering interrupt signals for edge detection
      int_1b <= int_1;
      int_2b <= int_2;
      int_3b <= int_3;
      int_4b <= int_4;
      int_5b <= int_5;
      int_6b <= int_6;
      int_7b <= int_7;
      int_8b <= int_8;
      int_9b <= int_9;
      int_10b <= int_10;
      int_11b <= int_11;
      int_12b <= int_12;
      int_13b <= int_13;
      int_14b <= int_14;
      int_15b <= int_15;
      int_16b <= int_16;
      -----------------------------------------------------------------
      -----------------------------------------------------------------
    -- Interrupt channel #1
      -- Interrupt enabled
      IF int_en_1(0) = '1' THEN
        -- edge sensitive interrupt
        IF int_edge_1(0) = '1' THEN

          -- when processor is reading interrupt vector
          IF Address = data_port_ID AND read_strobe = '1' AND data_int = X"01" THEN
            int_1i <= '0';          -- clear interrupt request
          -- interrupt signal rising edge detection
          ELSIF int_1 = '1' AND int_1b = '0' THEN
            int_1i <= '1';
          END IF;

        -- level sensitive interrupt
        ELSE
          -- forward value of interrupt request;
          -- request is cleared only by reading data register!!!
          IF int_1 = '1' THEN
            int_1i <= '1';
          -- when processor is reading interrupt vector
          ELSIF Address = data_port_ID AND read_strobe = '1' AND data_int = X"01" THEN
            int_1i <= '0';          -- clear interrupt request
          END IF;
        END IF;

      -- when interrupt is disabled
      ELSE
        int_1i <= '0';
      END IF;
      -----------------------------------------------------------------
    -- Interrupt channel #2
      -- Interrupt enabled
      IF int_en_1(1) = '1' THEN
        -- edge sensitive interrupt
        IF int_edge_1(1) = '1' THEN

          -- when processor is reading interrupt vector
          IF Address = data_port_ID AND read_strobe = '1' AND data_int = X"02" THEN
            int_2i <= '0';          -- clear interrupt request
          -- interrupt signal rising edge detection
          ELSIF int_2 = '1' AND int_2b = '0' THEN
            int_2i <= '1';
          END IF;

        -- level sensitive interrupt
        ELSE
          -- forward value of interrupt request;
          -- request is cleared only by reading data register!!!
          IF int_2 = '1' THEN
            int_2i <= '1';
          -- when processor is reading interrupt vector
          ELSIF Address = data_port_ID AND read_strobe = '1' AND data_int = X"02" THEN
            int_2i <= '0';          -- clear interrupt request
          END IF;
        END IF;

      -- when interrupt is disabled
      ELSE
        int_2i <= '0';
      END IF;
      -----------------------------------------------------------------
    -- Interrupt channel #3
      -- Interrupt enabled
      IF int_en_1(2) = '1' THEN
        -- edge sensitive interrupt
        IF int_edge_1(2) = '1' THEN

          -- when processor is reading interrupt vector
          IF Address = data_port_ID AND read_strobe = '1' AND data_int = X"03" THEN
            int_3i <= '0';          -- clear interrupt request
          -- interrupt signal rising edge detection
          ELSIF int_3 = '1' AND int_3b = '0' THEN
            int_3i <= '1';
          END IF;

        -- level sensitive interrupt
        ELSE
          -- forward value of interrupt request;
          -- request is cleared only by reading data register!!!
          IF int_3 = '1' THEN
            int_3i <= '1';
          -- when processor is reading interrupt vector
          ELSIF Address = data_port_ID AND read_strobe = '1' AND data_int = X"03" THEN
            int_3i <= '0';          -- clear interrupt request
          END IF;
        END IF;

      -- when interrupt is disabled
      ELSE
        int_3i <= '0';
      END IF;
      -----------------------------------------------------------------
    -- Interrupt channel #4
      -- Interrupt enabled
      IF int_en_1(3) = '1' THEN
        -- edge sensitive interrupt
        IF int_edge_1(3) = '1' THEN

          -- when processor is reading interrupt vector
          IF Address = data_port_ID AND read_strobe = '1' AND data_int = X"04" THEN
            int_4i <= '0';          -- clear interrupt request
          -- interrupt signal rising edge detection
          ELSIF int_4 = '1' AND int_4b = '0' THEN
            int_4i <= '1';
          END IF;

        -- level sensitive interrupt
        ELSE
          -- forward value of interrupt request;
          -- request is cleared only by reading data register!!!
          IF int_4 = '1' THEN
            int_4i <= '1';
          -- when processor is reading interrupt vector
          ELSIF Address = data_port_ID AND read_strobe = '1' AND data_int = X"04" THEN
            int_4i <= '0';          -- clear interrupt request
          END IF;
        END IF;

      -- when interrupt is disabled
      ELSE
        int_4i <= '0';
      END IF;
      -----------------------------------------------------------------
    -- Interrupt channel #5
      -- Interrupt enabled
      IF int_en_1(4) = '1' THEN
        -- edge sensitive interrupt
        IF int_edge_1(4) = '1' THEN

          -- when processor is reading interrupt vector
          IF Address = data_port_ID AND read_strobe = '1' AND data_int = X"05" THEN
            int_5i <= '0';          -- clear interrupt request
          -- interrupt signal rising edge detection
          ELSIF int_5 = '1' AND int_5b = '0' THEN
            int_5i <= '1';
          END IF;

        -- level sensitive interrupt
        ELSE
          -- forward value of interrupt request;
          -- request is cleared only by reading data register!!!
          IF int_5 = '1' THEN
            int_5i <= '1';
          -- when processor is reading interrupt vector
          ELSIF Address = data_port_ID AND read_strobe = '1' AND data_int = X"05" THEN
            int_5i <= '0';          -- clear interrupt request
          END IF;
        END IF;

      -- when interrupt is disabled
      ELSE
        int_5i <= '0';
      END IF;
      -----------------------------------------------------------------
    -- Interrupt channel #6
      -- Interrupt enabled
      IF int_en_1(5) = '1' THEN
        -- edge sensitive interrupt
        IF int_edge_1(5) = '1' THEN

          -- when processor is reading interrupt vector
          IF Address = data_port_ID AND read_strobe = '1' AND data_int = X"06" THEN
            int_6i <= '0';          -- clear interrupt request
          -- interrupt signal rising edge detection
          ELSIF int_6 = '1' AND int_6b = '0' THEN
            int_6i <= '1';
          END IF;

        -- level sensitive interrupt
        ELSE
          -- forward value of interrupt request;
          -- request is cleared only by reading data register!!!
          IF int_6 = '1' THEN
            int_6i <= '1';
          -- when processor is reading interrupt vector
          ELSIF Address = data_port_ID AND read_strobe = '1' AND data_int = X"06" THEN
            int_6i <= '0';          -- clear interrupt request
          END IF;
        END IF;

      -- when interrupt is disabled
      ELSE
        int_6i <= '0';
      END IF;
      -----------------------------------------------------------------
    -- Interrupt channel #7
      -- Interrupt enabled
      IF int_en_1(6) = '1' THEN
        -- edge sensitive interrupt
        IF int_edge_1(6) = '1' THEN

          -- when processor is reading interrupt vector
          IF Address = data_port_ID AND read_strobe = '1' AND data_int = X"07" THEN
            int_7i <= '0';          -- clear interrupt request
          -- interrupt signal rising edge detection
          ELSIF int_7 = '1' AND int_7b = '0' THEN
            int_7i <= '1';
          END IF;

        -- level sensitive interrupt
        ELSE
          -- forward value of interrupt request;
          -- request is cleared only by reading data register!!!
          IF int_7 = '1' THEN
            int_7i <= '1';
          -- when processor is reading interrupt vector
          ELSIF Address = data_port_ID AND read_strobe = '1' AND data_int = X"07" THEN
            int_7i <= '0';          -- clear interrupt request
          END IF;
        END IF;

      -- when interrupt is disabled
      ELSE
        int_7i <= '0';
      END IF;
      -----------------------------------------------------------------
    -- Interrupt channel #8
      -- Interrupt enabled
      IF int_en_1(7) = '1' THEN
        -- edge sensitive interrupt
        IF int_edge_1(7) = '1' THEN

          -- when processor is reading interrupt vector
          IF Address = data_port_ID AND read_strobe = '1' AND data_int = X"08" THEN
            int_8i <= '0';          -- clear interrupt request
          -- interrupt signal rising edge detection
          ELSIF int_8 = '1' AND int_8b = '0' THEN
            int_8i <= '1';
          END IF;

        -- level sensitive interrupt
        ELSE
          -- forward value of interrupt request;
          -- request is cleared only by reading data register!!!
          IF int_8 = '1' THEN
            int_8i <= '1';
          -- when processor is reading interrupt vector
          ELSIF Address = data_port_ID AND read_strobe = '1' AND data_int = X"08" THEN
            int_8i <= '0';          -- clear interrupt request
          END IF;
        END IF;

      -- when interrupt is disabled
      ELSE
        int_8i <= '0';
      END IF;
      ---------------------------------------------------------------


      -----------------------------------------------------------------
    -- Interrupt channel #9
      -- Interrupt enabled
      IF int_en_2(0) = '1' THEN
        -- edge sensitive interrupt
        IF int_edge_2(0) = '1' THEN

          -- when processor is reading interrupt vector
          IF Address = data_port_ID AND read_strobe = '1' AND data_int = X"09" THEN
            int_9i <= '0';          -- clear interrupt request
          -- interrupt signal rising edge detection
          ELSIF int_9 = '1' AND int_9b = '0' THEN
            int_9i <= '1';
          END IF;

        -- level sensitive interrupt
        ELSE
          -- forward value of interrupt request;
          -- request is cleared only by reading data register!!!
          IF int_9 = '1' THEN
            int_9i <= '1';
          -- when processor is reading interrupt vector
          ELSIF Address = data_port_ID AND read_strobe = '1' AND data_int = X"09" THEN
            int_9i <= '0';          -- clear interrupt request
          END IF;
        END IF;

      -- when interrupt is disabled
      ELSE
        int_9i <= '0';
      END IF;
      -----------------------------------------------------------------
    -- Interrupt channel #10
      -- Interrupt enabled
      IF int_en_2(1) = '1' THEN
        -- edge sensitive interrupt
        IF int_edge_2(1) = '1' THEN

          -- when processor is reading interrupt vector
          IF Address = data_port_ID AND read_strobe = '1' AND data_int = X"0A" THEN
            int_10i <= '0';          -- clear interrupt request
          -- interrupt signal rising edge detection
          ELSIF int_10 = '1' AND int_10b = '0' THEN
            int_10i <= '1';
          END IF;

        -- level sensitive interrupt
        ELSE
          -- forward value of interrupt request;
          -- request is cleared only by reading data register!!!
          IF int_10 = '1' THEN
            int_10i <= '1';
          -- when processor is reading interrupt vector
          ELSIF Address = data_port_ID AND read_strobe = '1' AND data_int = X"0A" THEN
            int_10i <= '0';          -- clear interrupt request
          END IF;
        END IF;

      -- when interrupt is disabled
      ELSE
        int_10i <= '0';
      END IF;
      -----------------------------------------------------------------
    -- Interrupt channel #11
      -- Interrupt enabled
      IF int_en_2(2) = '1' THEN
        -- edge sensitive interrupt
        IF int_edge_2(2) = '1' THEN

          -- when processor is reading interrupt vector
          IF Address = data_port_ID AND read_strobe = '1' AND data_int = X"0B" THEN
            int_11i <= '0';          -- clear interrupt request
          -- interrupt signal rising edge detection
          ELSIF int_11 = '1' AND int_11b = '0' THEN
            int_11i <= '1';
          END IF;

        -- level sensitive interrupt
        ELSE
          -- forward value of interrupt request;
          -- request is cleared only by reading data register!!!
          IF int_11 = '1' THEN
            int_11i <= '1';
          -- when processor is reading interrupt vector
          ELSIF Address = data_port_ID AND read_strobe = '1' AND data_int = X"0B" THEN
            int_11i <= '0';          -- clear interrupt request
          END IF;
        END IF;

      -- when interrupt is disabled
      ELSE
        int_11i <= '0';
      END IF;
      -----------------------------------------------------------------
    -- Interrupt channel #12
      -- Interrupt enabled
      IF int_en_2(3) = '1' THEN
        -- edge sensitive interrupt
        IF int_edge_2(3) = '1' THEN

          -- when processor is reading interrupt vector
          IF Address = data_port_ID AND read_strobe = '1' AND data_int = X"0C" THEN
            int_12i <= '0';          -- clear interrupt request
          -- interrupt signal rising edge detection
          ELSIF int_12 = '1' AND int_12b = '0' THEN
            int_12i <= '1';
          END IF;

        -- level sensitive interrupt
        ELSE
          -- forward value of interrupt request;
          -- request is cleared only by reading data register!!!
          IF int_12 = '1' THEN
            int_12i <= '1';
          -- when processor is reading interrupt vector
          ELSIF Address = data_port_ID AND read_strobe = '1' AND data_int = X"0C" THEN
            int_12i <= '0';          -- clear interrupt request
          END IF;
        END IF;

      -- when interrupt is disabled
      ELSE
        int_12i <= '0';
      END IF;
      -----------------------------------------------------------------
    -- Interrupt channel #13
      -- Interrupt enabled
      IF int_en_2(4) = '1' THEN
        -- edge sensitive interrupt
        IF int_edge_2(4) = '1' THEN

          -- when processor is reading interrupt vector
          IF Address = data_port_ID AND read_strobe = '1' AND data_int = X"0D" THEN
            int_13i <= '0';          -- clear interrupt request
          -- interrupt signal rising edge detection
          ELSIF int_13 = '1' AND int_13b = '0' THEN
            int_13i <= '1';
          END IF;

        -- level sensitive interrupt
        ELSE
          -- forward value of interrupt request;
          -- request is cleared only by reading data register!!!
          IF int_13 = '1' THEN
            int_13i <= '1';
          -- when processor is reading interrupt vector
          ELSIF Address = data_port_ID AND read_strobe = '1' AND data_int = X"0D" THEN
            int_13i <= '0';          -- clear interrupt request
          END IF;
        END IF;

      -- when interrupt is disabled
      ELSE
        int_13i <= '0';
      END IF;
      -----------------------------------------------------------------
    -- Interrupt channel #14
      -- Interrupt enabled
      IF int_en_2(5) = '1' THEN
        -- edge sensitive interrupt
        IF int_edge_2(5) = '1' THEN

          -- when processor is reading interrupt vector
          IF Address = data_port_ID AND read_strobe = '1' AND data_int = X"0E" THEN
            int_14i <= '0';          -- clear interrupt request
          -- interrupt signal rising edge detection
          ELSIF int_14 = '1' AND int_14b = '0' THEN
            int_14i <= '1';
          END IF;

        -- level sensitive interrupt
        ELSE
          -- forward value of interrupt request;
          -- request is cleared only by reading data register!!!
          IF int_14 = '1' THEN
            int_14i <= '1';
          -- when processor is reading interrupt vector
          ELSIF Address = data_port_ID AND read_strobe = '1' AND data_int = X"0E" THEN
            int_14i <= '0';          -- clear interrupt request
          END IF;
        END IF;

      -- when interrupt is disabled
      ELSE
        int_14i <= '0';
      END IF;
      -----------------------------------------------------------------
    -- Interrupt channel #15
      -- Interrupt enabled
      IF int_en_2(6) = '1' THEN
        -- edge sensitive interrupt
        IF int_edge_2(6) = '1' THEN

          -- when processor is reading interrupt vector
          IF Address = data_port_ID AND read_strobe = '1' AND data_int = X"0F" THEN
            int_15i <= '0';          -- clear interrupt request
          -- interrupt signal rising edge detection
          ELSIF int_15 = '1' AND int_15b = '0' THEN
            int_15i <= '1';
          END IF;

        -- level sensitive interrupt
        ELSE
          -- forward value of interrupt request;
          -- request is cleared only by reading data register!!!
          IF int_15 = '1' THEN
            int_15i <= '1';
          -- when processor is reading interrupt vector
          ELSIF Address = data_port_ID AND read_strobe = '1' AND data_int = X"0F" THEN
            int_15i <= '0';          -- clear interrupt request
          END IF;
        END IF;

      -- when interrupt is disabled
      ELSE
        int_15i <= '0';
      END IF;
      -----------------------------------------------------------------
    -- Interrupt channel #16
      -- Interrupt enabled
      IF int_en_2(7) = '1' THEN
        -- edge sensitive interrupt
        IF int_edge_2(7) = '1' THEN

          -- when processor is reading interrupt vector
          IF Address = data_port_ID AND read_strobe = '1' AND data_int = X"10" THEN
            int_16i <= '0';          -- clear interrupt request
          -- interrupt signal rising edge detection
          ELSIF int_16 = '1' AND int_16b = '0' THEN
            int_16i <= '1';
          END IF;

        -- level sensitive interrupt
        ELSE
          -- forward value of interrupt request;
          -- request is cleared only by reading data register!!!
          IF int_16 = '1' THEN
            int_16i <= '1';
          -- when processor is reading interrupt vector
          ELSIF Address = data_port_ID AND read_strobe = '1' AND data_int = X"10" THEN
            int_16i <= '0';          -- clear interrupt request
          END IF;
        END IF;

      -- when interrupt is disabled
      ELSE
        int_16i <= '0';
      END IF;
      ---------------------------------------------------------------


      ---------------------------------------------------------------
      IF Address = data_port_ID AND read_strobe = '1' THEN
         data_int <= X"00";     -- celar data register
      ELSIF int_1i = '1' AND data_int = X"00" THEN
        data_int <= X"01";
      ELSIF int_2i = '1' AND data_int = X"00" THEN
        data_int <= X"02";
      ELSIF int_3i = '1' AND data_int = X"00" THEN
        data_int <= X"03";
      ELSIF int_4i = '1' AND data_int = X"00" THEN
        data_int <= X"04";
      ELSIF int_5i = '1' AND data_int = X"00" THEN
        data_int <= X"05";
      ELSIF int_6i = '1' AND data_int = X"00" THEN
        data_int <= X"06";
      ELSIF int_7i = '1' AND data_int = X"00" THEN
        data_int <= X"07";
      ELSIF int_8i = '1' AND data_int = X"00" THEN
        data_int <= X"08";

      ELSIF int_9i = '1' AND data_int = X"00" THEN
        data_int <= X"09";
      ELSIF int_10i = '1' AND data_int = X"00" THEN
        data_int <= X"0A";
      ELSIF int_11i = '1' AND data_int = X"00" THEN
        data_int <= X"0B";
      ELSIF int_12i = '1' AND data_int = X"00" THEN
        data_int <= X"0C";
      ELSIF int_13i = '1' AND data_int = X"00" THEN
        data_int <= X"0D";
      ELSIF int_14i = '1' AND data_int = X"00" THEN
        data_int <= X"0E";
      ELSIF int_15i = '1' AND data_int = X"00" THEN
        data_int <= X"0F";
      ELSIF int_16i = '1' AND data_int = X"00" THEN
        data_int <= X"10";
      END IF;
  ---------------------------------------------------------------------
    END IF;
  END PROCESS int_proc;

-----------------------------------------------------------------------

  proc_int_i <= int_1i OR  int_2i OR  int_3i OR  int_4i OR  int_5i OR  int_6i OR  int_7i OR  int_8i OR
                int_9i OR int_10i OR int_11i OR int_12i OR int_13i OR int_14i OR int_15i OR int_16i;

  interrupt_delay: PROCESS(clk) BEGIN
    IF clk'EVENT AND clk = '1' THEN
      IF proc_int_ack = '1' THEN
        int_shreg <= (OTHERS => '0');
      ELSIF proc_int_i = '1' THEN
        int_shreg <= int_shreg(int_shreg'HIGH-1 DOWNTO 0) & '1';
      ELSE
        int_shreg <= (OTHERS => '0');
      END IF;
    END IF;
  END PROCESS interrupt_delay;
  -- connect internal interrupt signal to the blok output
  proc_int <= int_shreg(int_shreg'HIGH);


  -- Data output is active interrupt input number
  Data_out <= data_int;
  int_en_out_1 <= int_en_1;
  int_en_out_2 <= int_en_2;
  int_edge_out_1 <= int_edge_1;
  int_edge_out_2 <= int_edge_2;

-----------------------------------------------------------------------
-- Data Input
  IN_conrol: PROCESS(clk) BEGIN
    IF clk'EVENT AND clk = '1' THEN
      -----------------------------------------------------------------
      IF Address = int_en1_port_ID AND write_strobe = '1' THEN
        int_en_1 <= Data_in;
      END IF;
      -----------------------------------------------------------------
      IF Address = int_en2_port_ID AND write_strobe = '1' THEN
        int_en_2 <= Data_in;
      END IF;
      -----------------------------------------------------------------
      IF Address = int_edg1_port_ID AND write_strobe = '1' THEN
        int_edge_1 <= Data_in;
      END IF;
      -----------------------------------------------------------------
      IF Address = int_edg2_port_ID AND write_strobe = '1' THEN
        int_edge_2 <= Data_in;
      END IF;
      -----------------------------------------------------------------
    END IF;
  END PROCESS IN_conrol;
--#####################################################################
END Behavioral;
--#####################################################################
