vme_irq_controller.vhd 9.11 KB
Newer Older
Tom Levens's avatar
Tom Levens committed
1 2 3 4 5
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
-- VME64x Core
-- http://www.ohwr.org/projects/vme64x-core
--------------------------------------------------------------------------------
dpedrett's avatar
dpedrett committed
6
--
7
-- unit name:     vme_irq_controller
Tom Levens's avatar
Tom Levens committed
8 9 10 11 12 13 14 15 16 17 18 19 20 21
--
-- author:        Pablo Alvarez Sanchez <pablo.alvarez.sanchez@cern.ch>
--                Davide Pedretti       <davide.pedretti@cern.ch>
--
-- description:
--
--   This block acts as Interrupter. Phases of an interrupt cycle:
--
--   1) The Interrupt Controller receives an interrupt request by the WB bus;
--      this request is a pulse on the INT_Req input
--   2) The Interrupt Controller asserts ('0') one of the 7 VME_IRQ lines;
--      --> request of a service.
--      The Interrupt priority is specificated by the Master writing the
--      INT_Level register in the CR/CSR space
22
--   3) The Interrupter Controller waits for the falling edge on the VME_IACKIN
Tom Levens's avatar
Tom Levens committed
23 24 25 26 27 28 29 30 31 32
--      line.
--   4) When detects VME_IACKIN_n_i = '0' and the Interrupt Handler initiates
--      the Interrupt cycle by asserting AS,the Interrupt Controller check if it
--      is the responding interrupter. Indeed before responding to an interrupt
--      acknowledge cycle the interrupter shall have an interrupt request
--      pending, shall check if the level of that request match the level
--      indicated on the address lines A1, A2 and A3,the data transfer width
--      during the interrupt acknowledge cycle should be equal or greater than
--      the size the it can respond with, and it shall receive a falling edge on
--      its IACKIN*.
33
--   5) If it is the responding interrupter, it should send the source/ID on the
Tom Levens's avatar
Tom Levens committed
34 35 36 37 38 39 40 41
--      VME_DATA lines (in our case the source/ID is the INT_Vector that the
--      Master can write in the corresponding register in the CR/CSR space) and
--      it terminates the interrupt cycle with an acknowledge before releasing
--      the IRQ lines. If it isn't the responding interrupter, it should pass a
--      falling edge on down the daisy-chain so other interrupters can respond.
--
--   All the output signals are registered
--
42
--   To implement the above-mentioned 5 phases, the following FSM has been
Tom Levens's avatar
Tom Levens committed
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
--   implemented:
--       __________
--   |--| IACKOUT2 |<-|
--   |  |__________|  |
--   |                |
--   |    _________   |  _________     _________     _________
--   |-->|  IDLE   |--->|  IRQ    |-->| WAIT_AS |-->| WAIT_DS |-------------->|
--       |_________|    |_________|   |_________|   |_________|               |
--          |             |                                                   |
--          |             |                       _________      _________    |
--          |             |---------<------------| IACKOUT1| <--| CHECK   |<--|
--          |                                    |_________|    |_________|
--          |                     __________     __________         |
--          |--<-----------------|  DTACK   |<--| DATA_OUT |---<----|
--                               |__________|   |__________|
--
--  The interrupter wait the IACKIN falling edge in the IRQ state, so if the
--  interrupter don't have interrupt pending for sure it will not respond
--  because it is in IDLE.
--  If the slave module does not have an interrupt pending (IDLE state) and it
--  receives a falling edge on the IACKIN, it shall pass the falling edge
--  through the daisy chain.
--  To obtain this the IACKOUT2 state has been added.
--
--  Time constraint:
dpedrett's avatar
dpedrett committed
68
--
69
--  Time constraint #35:
Tom Levens's avatar
Tom Levens committed
70
--
71 72
-- Clk         ____      ____      ____      ____      ____      ____
--       _____|    |____|    |____|    |____|    |____|    |____|    |_____
Tom Levens's avatar
Tom Levens committed
73
--
74 75
-- VME_AS1_n_i   __________________________________________________________
--       _______|
Tom Levens's avatar
Tom Levens committed
76
--
77 78
-- VME_AS_n_i                                ______________________________
--       ___________________________________|
Tom Levens's avatar
Tom Levens committed
79
--
80 81
-- s_AS_RisingEge                                      _________
--       _____________________________________________|         |__________
Tom Levens's avatar
Tom Levens committed
82
--
83 84
-- s_IACKOUT     __________________________________________________________
--       _______|
Tom Levens's avatar
Tom Levens committed
85
--
86 87
-- VME_IACKOUT_  __________________________________________________________
--       _______|
dpedrett's avatar
dpedrett committed
88
--
89 90 91
--       _______________________________________________________  _________
--                                       IACKOUT 1/2            \/ IDLE/IRQ
--       _______________________________________________________/\_________
Tom Levens's avatar
Tom Levens committed
92 93
--
--  To respect the time constraint indicated with the number 35 fig. 55 pag. 183
94 95 96
--  in the "VMEbus Specification" ANSI/IEEE STD1014-1987, it is necessary to
--  generate the VME_AS1_n_i signal which is the AS signal that is not sampled,
--  and assign this signal to the s_IACKOUT signal when the fsm is in the IACKOUTx
Tom Levens's avatar
Tom Levens committed
97 98 99 100
--  state.
--
--  The LWORD* input is not used now, since this is a D08(O) Interrupter (see
--  Table 31 page 157 VMEbus specification).
dpedrett's avatar
dpedrett committed
101
--
Tom Levens's avatar
Tom Levens committed
102 103
--  Since this is a D08 interrupter we do not need to monitor the LWORD* and
--  DS1* lines and the Vector (1 byte) is outputted in the D00-D07 data lines.
dpedrett's avatar
dpedrett committed
104
--
Tom Levens's avatar
Tom Levens committed
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
-- dependencies:
--
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
--------------------------------------------------------------------------------
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your
-- option) any later version. This source is distributed in the hope that it
-- will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details. You should have
-- received a copy of the GNU Lesser General Public License along with this
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
--------------------------------------------------------------------------------
-- last changes: see log.
--------------------------------------------------------------------------------
-- TODO: -
--------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
128
use work.vme64x_pkg.all;
Tom Levens's avatar
Tom Levens committed
129

130
entity vme_irq_controller is
131
  generic (
132
    g_RETRY_TIMEOUT : integer range 1024 to 16777215
Tom Levens's avatar
Tom Levens committed
133
  );
134 135 136
  port (
    clk_i           : in  std_logic;
    reset_n_i       : in  std_logic;
137
    INT_Level_i     : in  std_logic_vector (2 downto 0);
138
    INT_Req_i       : in  std_logic;
139 140 141
    irq_pending_o   : out std_logic;
    irq_ack_i       : in  std_logic;
    VME_IRQ_n_o     : out std_logic_vector (7 downto 1)
Tom Levens's avatar
Tom Levens committed
142
  );
143
end vme_irq_controller;
Tom Levens's avatar
Tom Levens committed
144

145
architecture rtl of vme_irq_controller is
146 147 148

  type t_retry_state is (WAIT_IRQ, WAIT_RETRY);

Tom Levens's avatar
Tom Levens committed
149 150 151
  signal retry_state      : t_retry_state;
  signal retry_count      : unsigned(23 downto 0);
  signal retry_mask       : std_logic;
152
  signal s_irq_pending    : std_logic;
dpedrett's avatar
dpedrett committed
153
begin
154
  irq_pending_o <= s_irq_pending;
dpedrett's avatar
dpedrett committed
155

156
  -- Interrupts are automatically masked for g_RETRY_TIMEOUT (i.e. 1 ms) once
157 158
  -- they are acknowledge by the interrupt handler until they are deasserted
  -- by the interrupter.
Tom Levens's avatar
Tom Levens committed
159
  p_retry_fsm : process (clk_i)
160 161
  begin
    if rising_edge(clk_i) then
162 163 164 165 166 167
      if reset_n_i = '0' then
        retry_mask  <= '1';
        retry_state <= WAIT_IRQ;
      else
        case retry_state is
          when WAIT_IRQ =>
168
            if s_irq_pending = '1' and INT_Req_i = '1' then
169 170 171 172
              retry_state <= WAIT_RETRY;
              retry_count <= (others => '0');
              retry_mask  <= '0';
            else
Tom Levens's avatar
Tom Levens committed
173
              retry_mask  <= '1';
174
            end if;
dpedrett's avatar
dpedrett committed
175

176
          when WAIT_RETRY =>
177
            if INT_Req_i = '0' then
178 179 180
              retry_state <= WAIT_IRQ;
            else
              retry_count <= retry_count + 1;
181
              if retry_count = g_RETRY_TIMEOUT then
182 183 184 185
                retry_state <= WAIT_IRQ;
              end if;
            end if;
        end case;
dpedrett's avatar
dpedrett committed
186
      end if;
187 188 189
    end if;
  end process;

Tom Levens's avatar
Tom Levens committed
190
  p_main_fsm : process (clk_i)
191 192 193
  begin
    if rising_edge(clk_i) then
      if reset_n_i = '0' then
194 195
        VME_IRQ_n_o     <= (others => '1');
        s_irq_pending   <= '0';
196
      else
197 198 199
        if s_irq_pending = '0' then
          VME_IRQ_n_o     <= (others => '1');

200
          if INT_Req_i = '1' and retry_mask = '1' then
201
            s_irq_pending <= '1';
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216

            -- Explicit decoding
            case INT_Level_i is
              when "001" =>  VME_IRQ_n_o <= "1111110";
              when "010" =>  VME_IRQ_n_o <= "1111101";
              when "011" =>  VME_IRQ_n_o <= "1111011";
              when "100" =>  VME_IRQ_n_o <= "1110111";
              when "101" =>  VME_IRQ_n_o <= "1101111";
              when "110" =>  VME_IRQ_n_o <= "1011111";
              when "111" =>  VME_IRQ_n_o <= "0111111";
              when others =>
                --  Incorrect value for INT_Level_i, ignore it.
                VME_IRQ_n_o <= "1111111";
                s_irq_pending <= '0';
            end case;
217 218 219 220 221 222
          end if;
        else
          if irq_ack_i = '1' then
            s_irq_pending  <= '0';
          end if;
        end if;
223
      end if;
dpedrett's avatar
dpedrett committed
224
    end if;
225
  end process;
226
end rtl;