vme_bus.vhd 26.9 KB
Newer Older
Tom Levens's avatar
Tom Levens committed
1
--------------------------------------------------------------------------------
Tom Levens's avatar
Tom Levens committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
-- CERN (BE-CO-HT)
-- VME64x Core
-- http://www.ohwr.org/projects/vme64x-core
--------------------------------------------------------------------------------
--
-- unit name:     VME_bus (VME_bus.vhd)
--
-- author:        Pablo Alvarez Sanchez <pablo.alvarez.sanchez@cern.ch>
--                Davide Pedretti       <davide.pedretti@cern.ch>
--
-- description:
--
--   This block acts as interface between the VMEbus and the CR/CSR space or
--   WBbus.
--
Tom Levens's avatar
Tom Levens committed
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
--                      _________VME_bus__________
--                     |  __________________      |
--                     | |                  |  ___|
--                     | |                  | |   |
--                     | |      MAIN        | | W |
--                   V | |                  | | B | W
--                   M | |      FSM         | |   | B
--                   E | |                  | | M |
--                     | |                  | | A | B
--                   B | |__________________| | S | U
--                   U |  __________________  | T | S
--                   S | |                  | | E |
--                     | |   OTHER DATA &   | | R |
--                     | |   ADDR PROCESS   | |___|
--                     | |__________________|     |
--                     |__________________________|
Tom Levens's avatar
Tom Levens committed
33 34 35 36 37 38 39 40 41 42 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
--
--   The Access decode component decodes the address to check if the board is
--   the responding Slave. This component is of fundamental importance, indeed
--   only one Slave can answer to the Master!
--   In the right side you can see the WB Master who implements the Wb Pipelined
--   single read/write protocol.
--   Each VME board plugged in a slot acts as a VME slave module and it has only
--   one CR/CSR space (conforming with the specification) so only one FPGA at
--   time must drive the output lines on the VME bus; only one FPGA at time can
--   carry the vme64x core or other similar VME slave core.
--   Inside each component is possible read a more detailed description.
--
-- 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;
68
use work.vme64x_pkg.all;
Tom Levens's avatar
Tom Levens committed
69

70
entity vme_bus is
Tom Levens's avatar
Tom Levens committed
71
  generic (
72
    g_CLOCK_PERIOD  : integer
Tom Levens's avatar
Tom Levens committed
73 74
  );
  port (
75
    clk_i           : in  std_logic;
Tom Levens's avatar
Tom Levens committed
76 77
    rst_i           : in  std_logic;

Tom Levens's avatar
Tom Levens committed
78
    -- VME signals
79
    VME_AS_n_i      : in  std_logic;
80
    VME_LWORD_n_o   : out std_logic := '0';
81 82 83 84 85 86 87
    VME_LWORD_n_i   : in  std_logic;
    VME_RETRY_n_o   : out std_logic;
    VME_RETRY_OE_o  : out std_logic;
    VME_WRITE_n_i   : in  std_logic;
    VME_DS_n_i      : in  std_logic_vector(1 downto 0);
    VME_DTACK_n_o   : out std_logic;
    VME_DTACK_OE_o  : out std_logic;
Tom Levens's avatar
Tom Levens committed
88
    VME_BERR_n_o    : out std_logic;
89
    VME_ADDR_i      : in  std_logic_vector(31 downto 1);
90
    VME_ADDR_o      : out std_logic_vector(31 downto 1) := (others => '0');
91 92 93
    VME_ADDR_DIR_o  : out std_logic;
    VME_ADDR_OE_N_o : out std_logic;
    VME_DATA_i      : in  std_logic_vector(31 downto 0);
94
    VME_DATA_o      : out std_logic_vector(31 downto 0) := (others => '0');
95 96 97
    VME_DATA_DIR_o  : out std_logic;
    VME_DATA_OE_N_o : out std_logic;
    VME_AM_i        : in  std_logic_vector(5 downto 0);
98 99 100 101
    VME_IACKIN_n_i  : in  std_logic;
    VME_IACK_n_i    : in  std_logic;
    VME_IACKOUT_n_o : out std_logic;

102
    -- WB signals
Tom Levens's avatar
Tom Levens committed
103 104
    stb_o           : out std_logic;
    ack_i           : in  std_logic;
105 106 107
    dat_o           : out std_logic_vector(31 downto 0);
    dat_i           : in  std_logic_vector(31 downto 0);
    adr_o           : out std_logic_vector(31 downto 0);
108
    sel_o           : out std_logic_vector(3 downto 0);
Tom Levens's avatar
Tom Levens committed
109
    we_o            : out std_logic;
110 111 112 113
    cyc_o           : out std_logic;
    err_i           : in  std_logic;
    stall_i         : in  std_logic;

Tom Levens's avatar
Tom Levens committed
114
    -- Function decoder
115 116
    addr_decoder_i  : in  std_logic_vector(31 downto 0);
    addr_decoder_o  : out std_logic_vector(31 downto 0);
117 118
    decode_start_o  : out std_logic;
    decode_done_i   : in std_logic;
Tom Levens's avatar
Tom Levens committed
119
    am_o            : out std_logic_vector( 5 downto 0);
120
    decode_sel_i    : in  std_logic;
Tom Levens's avatar
Tom Levens committed
121

Tristan Gingold's avatar
Tristan Gingold committed
122
    -- CR/CSR space signals:
Tom Levens's avatar
Tom Levens committed
123 124 125 126 127
    cr_csr_addr_o   : out std_logic_vector(18 downto 2);
    cr_csr_data_i   : in  std_logic_vector( 7 downto 0);
    cr_csr_data_o   : out std_logic_vector( 7 downto 0);
    cr_csr_we_o     : out std_logic;
    module_enable_i : in  std_logic;
128 129 130 131 132 133 134
    bar_i           : in  std_logic_vector( 4 downto 0);

    -- Interrupts
    INT_Level_i     : in  std_logic_vector( 2 downto 0);
    INT_Vector_i    : in  std_logic_vector( 7 downto 0);
    irq_pending_i   : in  std_logic;
    irq_ack_o       : out std_logic
Tom Levens's avatar
Tom Levens committed
135
  );
136
end vme_bus;
Tom Levens's avatar
Tom Levens committed
137

138
architecture rtl of vme_bus is
139
  -- Local data
140
  signal s_locDataIn                : std_logic_vector(63 downto 0);
141
  signal s_locDataOut               : std_logic_vector(63 downto 0);
142

143
  -- VME latched signals
144
  signal s_ADDRlatched              : std_logic_vector(31 downto 1);
145
  signal s_LWORDlatched_n           : std_logic;
Tristan Gingold's avatar
Tristan Gingold committed
146
  signal s_DSlatched_n              : std_logic_vector(1 downto 0);
147
  signal s_AMlatched                : std_logic_vector(5 downto 0);
Tristan Gingold's avatar
Tristan Gingold committed
148
  signal s_WRITElatched_n           : std_logic;
149

150 151
  -- Address and data from the VME bus.  There are two registers so that the
  -- first one can be placed in the IOBs.
152
  signal s_vme_addr_reg             : std_logic_vector(31 downto 1);
153
  signal s_vme_data_reg             : std_logic_vector(31 downto 0);
154
  signal s_vme_lword_n_reg          : std_logic;
155
  signal s_vme_addr_dir             : std_logic;
156

157 158 159 160 161 162 163 164 165
  type t_addressingType is (
    A24,
    A24_BLT,
    A24_MBLT,
    CR_CSR,
    A16,
    A32,
    A32_BLT,
    A32_MBLT,
166
    AM_ERROR
167
  );
168

169 170 171 172
  type t_transferType is (
    SINGLE,
    BLT,
    MBLT,
173
    TFR_ERROR
174
  );
dpedrett's avatar
dpedrett committed
175

176
  -- Addressing type (depending on VME_AM_i)
Tom Levens's avatar
Tom Levens committed
177 178
  signal s_addressingType           : t_addressingType;
  signal s_transferType             : t_transferType;
179 180 181 182 183 184 185

  type t_mainFSMstates is (
    -- Wait until AS is asserted.
    IDLE,

    -- Reformat address according to AM.
    REFORMAT_ADDRESS,
186

187
    -- Decoding ADDR and AM (selecting card or conf).
188
    DECODE_ACCESS,
189 190 191 192 193 194 195

    -- Wait until DS is asserted.
    WAIT_FOR_DS,

    -- Wait until DS is stable (and asserted).
    LATCH_DS,

196
    -- Decode DS, generate WB request
197 198 199 200 201 202 203 204 205 206
    CHECK_TRANSFER_TYPE,

    -- Wait for WB reply
    MEMORY_REQ,

    -- For read cycle, put data on the bus
    DATA_TO_BUS,

    -- Assert DTACK
    DTACK_LOW,
207

208
    -- Increment address for block transfers
209
    INCREMENT_ADDR,
210

211 212 213 214 215 216
    -- Check if IACK is for this slave
    IRQ_CHECK,

    -- Pass IACKIN to IACKOUT
    IRQ_PASS,

217 218 219
    --  Wait until AS is deasserted
    WAIT_END
  );
Tom Levens's avatar
Tom Levens committed
220 221 222

  -- Main FSM signals
  signal s_mainFSMstate             : t_mainFSMstates;
Tristan Gingold's avatar
Tristan Gingold committed
223
  signal s_conf_req                 : std_logic;   -- Global memory request
224
  signal s_dataPhase                : std_logic;   -- for MBLT
Tristan Gingold's avatar
Tristan Gingold committed
225
  signal s_MBLT_Data                : std_logic;   -- for MBLT: '1' in Addr
Tom Levens's avatar
Tom Levens committed
226

dpedrett's avatar
dpedrett committed
227
  -- Access decode signals
228 229
  signal s_conf_sel                 : std_logic;   -- CR or CSR is addressed
  signal s_card_sel                 : std_logic;   -- WB memory is addressed
230
  signal s_irq_sel                  : std_logic;   -- IACK transaction
dpedrett's avatar
dpedrett committed
231

Tom Levens's avatar
Tom Levens committed
232 233 234
  signal s_err                      : std_logic;

  -- Calculate the number of LATCH DS states necessary to match the timing
235
  -- rule 2.39 page 113 VMEbus specification ANSI/IEEE STD1014-1987.
236 237 238 239 240 241
  -- (max skew for the slave is 20 ns)
  constant num_latchDS              : natural range 1 to 8 :=
    (20 + g_CLOCK_PERIOD - 1) / g_CLOCK_PERIOD;

  signal s_DS_latch_count           : unsigned (2 downto 0);
begin
Tom Levens's avatar
Tom Levens committed
242
  -- These output signals are connected to the buffers on the board
243
  -- SN74VMEH22501A Function table:  (A is fpga, B is VME connector)
dpedrett's avatar
dpedrett committed
244 245 246 247 248 249
  --   OEn | DIR | OUTPUT                 OEAB   |   OEBYn   |   OUTPUT
  --    H  |  X  |   Z                      L    |     H     |     Z
  --    L  |  H  | A to B                   H    |     H     |   A to B
  --    L  |  L  | B to A                   L    |     L     |   B to Y
  --                                        H    |     L     |A to B, B to Y |

250 251
  VME_DATA_OE_N_o <= '0'; -- Driven IFF DIR = 1
  VME_ADDR_OE_N_o <= '0'; -- Driven IFF DIR = 1
Tom Levens's avatar
Tom Levens committed
252 253 254 255

  ------------------------------------------------------------------------------
  -- Access Mode Decoders
  ------------------------------------------------------------------------------
dpedrett's avatar
dpedrett committed
256 257 258
  -- Type of data transfer decoder
  -- VME64 ANSI/VITA 1-1994...Table 2-2 "Signal levels during data transfers"

Tom Levens's avatar
Tom Levens committed
259 260
  -- Bytes position on VMEbus:
  --
Tristan Gingold's avatar
Tristan Gingold committed
261 262 263 264 265 266 267 268 269
  -- A24-31 | A16-23 | A08-15 | A00-07 | D24-31 | D16-23 | D08-15 | D00-07
  --        |        |        |        |        |        | BYTE 0 |
  --        |        |        |        |        |        |        | BYTE 1
  --        |        |        |        |        |        | BYTE 2 |
  --        |        |        |        |        |        |        | BYTE 3
  --        |        |        |        |        |        | BYTE 0 | BYTE 1
  --        |        |        |        |        |        | BYTE 2 | BYTE 3
  --        |        |        |        | BYTE 0 | BYTE 1 | BYTE 2 | BYTE 3
  -- BYTE 0 | BYTE 1 | BYTE 2 | BYTE 3 | BYTE 4 | BYTE 5 | BYTE 6 | BYTE 7
270

Tom Levens's avatar
Tom Levens committed
271
  -- Address modifier decoder
Tristan Gingold's avatar
Tristan Gingold committed
272
  -- Both the supervisor and the user access modes are supported
273 274 275 276
  with s_AMlatched select s_addressingType <=
    A24      when c_AM_A24_S_SUP | c_AM_A24_S,
    A24_BLT  when c_AM_A24_BLT | c_AM_A24_BLT_SUP,
    A24_MBLT when c_AM_A24_MBLT | c_AM_A24_MBLT_SUP,
277
    CR_CSR   when c_AM_CR_CSR,
278 279 280 281
    A16      when c_AM_A16 | c_AM_A16_SUP,
    A32      when c_AM_A32 | c_AM_A32_SUP,
    A32_BLT  when c_AM_A32_BLT | c_AM_A32_BLT_SUP,
    A32_MBLT when c_AM_A32_MBLT | c_AM_A32_MBLT_SUP,
282
    AM_ERROR when others;
Tom Levens's avatar
Tom Levens committed
283 284 285

  -- Transfer type decoder
  with s_addressingType select s_transferType <=
286 287 288 289
    SINGLE    when A24 | CR_CSR | A16 | A32,
    BLT       when A24_BLT | A32_BLT,
    MBLT      when A24_MBLT | A32_MBLT,
    TFR_ERROR when others;
290

Tom Levens's avatar
Tom Levens committed
291 292 293
  ------------------------------------------------------------------------------
  -- MAIN FSM
  ------------------------------------------------------------------------------
294 295
  p_VMEmainFSM : process (clk_i) is
    variable addr_word_incr : natural range 0 to 7;
296 297
  begin
    if rising_edge(clk_i) then
298
      if rst_i = '1' or VME_AS_n_i = '1' then
Tom Levens's avatar
Tom Levens committed
299 300 301
        -- FSM resetted after power up,
        -- software reset, manually reset,
        -- on rising edge of AS.
Tristan Gingold's avatar
Tristan Gingold committed
302
        s_conf_req       <= '0';
303
        decode_start_o   <= '0';
304 305

        -- VME
306 307 308 309
        VME_DTACK_OE_o   <= '0';
        VME_DTACK_n_o    <= '1';
        VME_DATA_DIR_o   <= '0';
        VME_ADDR_DIR_o   <= '0';
310
        VME_BERR_n_o     <= '1';
311 312 313 314
        VME_ADDR_o       <= (others => '0');
        VME_LWORD_n_o    <= '1';
        VME_DATA_o       <= (others => '0');
        VME_IACKOUT_n_o  <= '1';
Tom Levens's avatar
Tom Levens committed
315
        s_dataPhase      <= '0';
Tristan Gingold's avatar
Tristan Gingold committed
316
        s_MBLT_Data      <= '0';
317
        s_mainFSMstate   <= IDLE;
318 319 320 321 322 323

        -- WB
        sel_o            <= "0000";
        cyc_o            <= '0';
        stb_o            <= '0';
        s_err            <= '0';
324

325
        s_ADDRlatched    <= (others => '0');
326
        s_AMlatched      <= (others => '0');
327

328
        s_vme_addr_reg   <= (others => '0');
329 330
        s_vme_addr_dir   <= '0';

331 332
        s_card_sel <= '0';
        s_conf_sel <= '0';
333 334
        s_irq_sel  <= '0';
        irq_ack_o  <= '0';
335
      else
Tristan Gingold's avatar
Tristan Gingold committed
336
        s_conf_req       <= '0';
337
        decode_start_o   <= '0';
338 339 340 341
        VME_DTACK_OE_o   <= '0';
        VME_DTACK_n_o    <= '1';
        VME_DATA_DIR_o   <= '0';
        VME_ADDR_DIR_o   <= '0';
342
        VME_BERR_n_o     <= '1';
343 344
        VME_IACKOUT_n_o  <= '1';
        irq_ack_o        <= '0';
Tom Levens's avatar
Tom Levens committed
345

346 347 348
        case s_mainFSMstate is

          when IDLE =>
349
            if VME_AS_n_i = '0' then
Tristan Gingold's avatar
Tristan Gingold committed
350 351
              -- if AS falling edge --> start access

352
              -- Store ADDR, AM and LWORD
353
              s_ADDRlatched    <= VME_ADDR_i;
354
              s_LWORDlatched_n <= VME_LWORD_n_i;
355 356
              s_AMlatched      <= VME_AM_i;

357 358 359 360 361
              if VME_IACK_n_i = '1' then
                -- VITA-1 Rule 2.11
                -- Slaves MUST NOT respond to DTB cycles when IACK* is low.
                s_mainFSMstate <= REFORMAT_ADDRESS;
              else
Tristan Gingold's avatar
Tristan Gingold committed
362
                -- IACK cycle.
363 364 365
                s_mainFSMstate <= IRQ_CHECK;
              end if;

366 367 368 369
            else
              s_mainFSMstate <= IDLE;
            end if;

370
          when REFORMAT_ADDRESS =>
371
            -- Reformat address according to the mode (A16, A24, A32)
372 373
            -- FIXME: not needed if ADEM are correctly reduced to not compare
            -- MSBs of A16 or A24 addresses.
374
            s_vme_addr_reg <= s_ADDRlatched;
375 376
            case s_addressingType is
              when A16 =>
377
                s_vme_addr_reg (31 downto 16) <= (others => '0');  -- A16
378
              when A24 | A24_BLT | A24_MBLT =>
379
                s_vme_addr_reg (31 downto 24) <= (others => '0');  -- A24
380 381
              when others =>
                null;  -- A32
382 383
            end case;

384 385
            s_vme_lword_n_reg <= s_LWORDlatched_n;

Tristan Gingold's avatar
Tristan Gingold committed
386 387 388
            -- Address is not yet decoded.
            s_card_sel <= '0';
            s_conf_sel <= '0';
389
            s_irq_sel <= '0';
Tristan Gingold's avatar
Tristan Gingold committed
390

391 392 393
            --  DS latch counter
            s_DS_latch_count <= to_unsigned (num_latchDS, 3);

394 395 396 397
            --  VITA-1 Rule 2.6
            --  A Slave MUST NOT respond with a falling edge on DTACK* during
            --  an unaligned transfer cycle, if it does not have UAT
            --  capability.
Tristan Gingold's avatar
Tristan Gingold committed
398
            if s_LWORDlatched_n = '0' and s_ADDRlatched(1) = '1' then
399 400
              -- unaligned.
              s_mainFSMstate <= WAIT_END;
401
            else
402 403 404 405 406 407 408 409 410 411
              if s_ADDRlatched(23 downto 19) = bar_i
                and s_AMlatched = c_AM_CR_CSR
              then
                -- conf_sel = '1' it means CR/CSR space addressed
                s_conf_sel <= '1';
                s_mainFSMstate <= WAIT_FOR_DS;
              else
                s_mainFSMstate <= DECODE_ACCESS;
                decode_start_o  <= '1';
              end if;
412
            end if;
413

414
          when DECODE_ACCESS =>
415
            -- check if this slave board is addressed.
416

417 418 419 420 421 422 423 424
            --  Wait for DS in parallel.
            if VME_DS_n_i /= "11" then
              s_WRITElatched_n <= VME_WRITE_n_i;
              if s_DS_latch_count /= 0 then
                s_DS_latch_count <= s_DS_latch_count - 1;
              end if;
            end if;

425 426 427 428
            if decode_done_i = '1' then
              if decode_sel_i = '1' and module_enable_i = '1' then
                -- card_sel = '1' it means WB application addressed
                s_card_sel <= '1';
Tristan Gingold's avatar
Tristan Gingold committed
429
                -- Keep only the local part of the address.
430
                s_vme_addr_reg <= addr_decoder_i (31 downto 1);
431 432 433 434 435 436

                if VME_DS_n_i = "11" then
                  s_mainFSMstate <= WAIT_FOR_DS;
                else
                  s_mainFSMstate <= LATCH_DS;
                end if;
437
              else
Tristan Gingold's avatar
Tristan Gingold committed
438
                -- Another board will answer; wait here the rising edge on
439 440 441
                -- VME_AS_i (done by top if).
                s_mainFSMstate <= WAIT_END;
              end if;
442
            else
443 444
              -- Not yet decoded.
              s_mainFSMstate <= DECODE_ACCESS;
445 446
            end if;

Tom Levens's avatar
Tom Levens committed
447 448
          when WAIT_FOR_DS =>
            -- wait until DS /= "11"
449
            -- Note: before entering this state, s_DS_latch_count must be set.
450 451

            if VME_DS_n_i /= "11" then
452 453
              -- VITAL-1 Table 4-1
              -- For interrupts ack, the handler MUST NOT drive WRITE* low
Tristan Gingold's avatar
Tristan Gingold committed
454
              s_WRITElatched_n <= VME_WRITE_n_i;
455
              s_DS_latch_count <= s_DS_latch_count - 1;
456
              s_mainFSMstate <= LATCH_DS;
457 458 459 460
            else
              s_mainFSMstate <= WAIT_FOR_DS;
            end if;

461
          when LATCH_DS =>
Tristan Gingold's avatar
Tristan Gingold committed
462 463
            -- This state is necessary indeed the VME master can assert the
            -- DS lines not at the same time.
Tristan Gingold's avatar
Tristan Gingold committed
464

465
            -- VITA-1 Rule 2.53a
Tristan Gingold's avatar
Tristan Gingold committed
466
            -- During all read cycles [...], the responding slave MUST NOT
467
            -- drive the D[] lines until DSA* goes low.
Tristan Gingold's avatar
Tristan Gingold committed
468
            VME_DATA_DIR_o   <= s_WRITElatched_n;
469
            VME_ADDR_DIR_o   <= '0';
Tristan Gingold's avatar
Tristan Gingold committed
470 471 472 473 474

            if s_transferType = MBLT then
              s_dataPhase <= '1';

              -- Start with D[31..0] when writing, but D[63..32] when reading.
475
              s_vme_addr_reg(2) <= not s_WRITElatched_n;
Tristan Gingold's avatar
Tristan Gingold committed
476 477 478 479
            else
              s_dataPhase <= '0';
            end if;

480
            if s_DS_latch_count = 0 or s_transferType = MBLT then
481 482 483
              if s_irq_sel = '1' then
                s_mainFSMstate <= DATA_TO_BUS;
              elsif s_transferType = MBLT and s_MBLT_Data = '0' then
Tristan Gingold's avatar
Tristan Gingold committed
484 485 486 487 488 489
                -- MBLT: ack address.
                -- (Data are also read but discarded).
                s_mainFSMstate <= DTACK_LOW;
              else
                s_mainFSMstate <= CHECK_TRANSFER_TYPE;
              end if;
490 491

              -- Read DS (which is delayed to avoid metastability).
Tristan Gingold's avatar
Tristan Gingold committed
492
              s_DSlatched_n  <= VME_DS_n_i;
493 494 495

              -- Read DATA (which are stable)
              s_locDataIn(63 downto 33) <= VME_ADDR_i;
496
              s_LWORDlatched_n          <= VME_LWORD_n_i;
497
              s_vme_data_reg            <= VME_DATA_i;
498
            else
499 500
              s_mainFSMstate   <= LATCH_DS;
              s_DS_latch_count <= s_DS_latch_count - 1;
501
            end if;
Tom Levens's avatar
Tom Levens committed
502

503
          when CHECK_TRANSFER_TYPE =>
Tristan Gingold's avatar
Tristan Gingold committed
504
            VME_DATA_DIR_o   <= s_WRITElatched_n;
505
            VME_ADDR_DIR_o   <= '0';
Tom Levens's avatar
Tom Levens committed
506
            s_dataPhase      <= s_dataPhase;
507

508 509 510 511 512 513 514
            --  VME_ADDR is an output during MBLT *read* data transfer.
            if s_transferType = MBLT and s_WRITElatched_n = '1' then
              s_vme_addr_dir  <= '1';
            else
              s_vme_addr_dir  <= '0';
            end if;

515
            s_locDataIn(32)          <= s_LWORDlatched_n;
516
            s_locDataIn(31 downto 0) <= s_vme_data_reg;
517
            if s_vme_lword_n_reg = '1' and s_vme_addr_reg(1) = '0' then
518 519
              -- Word/byte access with A1=0
              s_locDataIn(31 downto 16)  <= s_vme_data_reg(15 downto 0);
520 521
            end if;

522
            --  Translate DS+LWORD+ADDR to WB byte selects
523
            if s_vme_lword_n_reg = '0' then
524
              sel_o <= "1111";
525
            else
526
              sel_o <= "0000";
527
              case s_vme_addr_reg(1) is
528
                when '0' =>
Tristan Gingold's avatar
Tristan Gingold committed
529
                  sel_o (3 downto 2) <= not s_DSlatched_n;
530
                when '1' =>
Tristan Gingold's avatar
Tristan Gingold committed
531
                  sel_o (1 downto 0) <= not s_DSlatched_n;
532 533 534 535 536
                when others =>
                  null;
              end case;
            end if;

Tristan Gingold's avatar
Tristan Gingold committed
537 538 539 540
            --  VITA-1 Rule 2.6
            --  A Slave MUST NOT respond with a falling edge on DTACK* during
            --  an unaligned transfer cycle, if it does not have UAT
            --  capability.
541
            if s_vme_lword_n_reg = '0' and s_DSlatched_n /= "00" then
Tristan Gingold's avatar
Tristan Gingold committed
542 543 544 545 546
              -- unaligned.
              s_mainFSMstate <= WAIT_END;
            else
              s_mainFSMstate <= MEMORY_REQ;
              s_conf_req <= s_conf_sel;
Tristan Gingold's avatar
Tristan Gingold committed
547 548

              -- Start WB cycle.
Tristan Gingold's avatar
Tristan Gingold committed
549 550 551 552
              cyc_o <= s_card_sel;
              stb_o <= s_card_sel;
              s_err <= '0';
            end if;
553

554
          when MEMORY_REQ =>
Tom Levens's avatar
Tom Levens committed
555
            -- To request the memory CR/CSR or WB memory it is sufficient to
Tristan Gingold's avatar
Tristan Gingold committed
556
            -- generate a pulse on s_conf_req signal
557
            VME_DTACK_OE_o   <= '1';
Tristan Gingold's avatar
Tristan Gingold committed
558
            VME_DATA_DIR_o   <= s_WRITElatched_n;
559
            VME_ADDR_DIR_o   <= s_vme_addr_dir;
560

Tristan Gingold's avatar
Tristan Gingold committed
561 562
            -- Assert STB if stall was asserted.
            stb_o <= s_card_sel and stall_i;
563 564 565 566

            if s_conf_sel = '1'
              or (s_card_sel = '1' and (ack_i = '1' or err_i = '1'))
            then
567
              -- WB ack
568 569
              stb_o <= '0';
              s_err <= s_card_sel and err_i;
Tristan Gingold's avatar
Tristan Gingold committed
570 571
              if (s_card_sel and err_i) = '1' then
                -- Error
572
                s_mainFSMstate <= DTACK_LOW;
Tristan Gingold's avatar
Tristan Gingold committed
573 574 575 576 577
              elsif s_WRITElatched_n = '0' then
                -- Write cycle.
                if s_dataPhase = '1' then
                  -- MBLT
                  s_dataPhase <= '0';
578
                  s_vme_addr_reg(2) <= '0';
Tristan Gingold's avatar
Tristan Gingold committed
579 580 581

                  s_locDataIn(31 downto 0) <= s_locDataIn(63 downto 32);

582 583 584
                  stb_o <= s_card_sel;

                  s_mainFSMstate <= MEMORY_REQ;
Tristan Gingold's avatar
Tristan Gingold committed
585 586 587
                else
                  s_mainFSMstate <= DTACK_LOW;
                end if;
588
              else
589
                -- Read cycle
590 591

                -- Mux (CS-CSR or WB)
Tristan Gingold's avatar
Tristan Gingold committed
592 593
                s_locDataOut(63 downto 32) <= s_locDataOut(31 downto 0);
                s_locDataOut(31 downto 0) <= (others => '0');
594
                if s_card_sel = '1' then
595
                  if s_vme_lword_n_reg = '1' and s_vme_addr_reg(1) = '0' then
596
                    -- Word/byte access with A1 = 0
597
                    s_locDataOut(15 downto 0) <= dat_i(31 downto 16);
598
                  else
599
                    s_locDataOut(31 downto 0) <= dat_i;
600
                  end if;
Tristan Gingold's avatar
Tristan Gingold committed
601
                else
602
                  s_locDataOut(7 downto 0) <= cr_csr_data_i;
603
                end if;
604

Tristan Gingold's avatar
Tristan Gingold committed
605 606 607
                if s_dataPhase = '1' then
                  -- MBLT
                  s_dataPhase <= '0';
608
                  s_vme_addr_reg(2) <= '1';
Tristan Gingold's avatar
Tristan Gingold committed
609

610 611 612
                  stb_o <= s_card_sel;

                  s_mainFSMstate <= MEMORY_REQ;
Tristan Gingold's avatar
Tristan Gingold committed
613 614 615
                else
                  s_mainFSMstate <= DATA_TO_BUS;
                end if;
616 617 618 619 620 621
              end if;
            else
              s_mainFSMstate <= MEMORY_REQ;
            end if;

          when DATA_TO_BUS =>
622
            VME_DTACK_OE_o   <= '1';
Tristan Gingold's avatar
Tristan Gingold committed
623
            VME_DATA_DIR_o   <= s_WRITElatched_n;
624
            VME_ADDR_DIR_o   <= s_vme_addr_dir;
Tristan Gingold's avatar
Tristan Gingold committed
625 626 627 628

            VME_ADDR_o    <= s_locDataOut(63 downto 33);
            VME_LWORD_n_o <= s_locDataOut(32);
            VME_DATA_o    <= s_locDataOut(31 downto 0);
629

630 631 632
            -- VITA-1 Rule 2.54a
            -- During all read cycles, the responding Slave MUST NOT drive
            -- DTACK* low before it drives D[].
Tristan Gingold's avatar
Tristan Gingold committed
633
            s_mainFSMstate   <= DTACK_LOW;
634

635
          when DTACK_LOW =>
636
            VME_DTACK_OE_o   <= '1';
Tristan Gingold's avatar
Tristan Gingold committed
637
            VME_DATA_DIR_o   <= s_WRITElatched_n;
638
            VME_ADDR_DIR_o   <= s_vme_addr_dir;
639

640
            --  Set DTACK (or retry or berr)
641
            if s_card_sel = '1' and s_err = '1' then
642
              VME_BERR_n_o  <= '0';
643
            else
644
              VME_DTACK_n_o <= '0';
645 646
            end if;

647 648 649 650
            -- VITA-1 Rule 2.57
            -- Once the responding Slave has driven DTACK* or BERR* low, it
            -- MUST NOT release them or drive DTACK* high until it detects
            -- both DS0* and DS1* high.
651
            if VME_DS_n_i = "11" then
652 653
              VME_DATA_DIR_o  <= '0';
              VME_BERR_n_o    <= '1';
Tristan Gingold's avatar
Tristan Gingold committed
654 655 656

              -- Rescind DTACK.
              VME_DTACK_n_o <= '1';
657 658 659 660

              --  DS latch counter
              s_DS_latch_count <= to_unsigned (num_latchDS, 3);

661 662 663
              if s_irq_sel = '1' then
                s_mainFSMstate <= WAIT_END;
              elsif s_transferType = SINGLE then
Tristan Gingold's avatar
Tristan Gingold committed
664 665 666 667 668 669
                --  Cycle should be finished, but allow another access at
                --  the same address (RMW).
                s_mainFSMstate <= WAIT_FOR_DS;
              else
                if s_transferType = MBLT and s_MBLT_Data = '0' then
                  -- MBLT: end of address phase.
670
                  s_mainFSMstate <= WAIT_FOR_DS;
Tristan Gingold's avatar
Tristan Gingold committed
671 672 673
                  s_MBLT_Data <= '1';
                else
                  -- Block
674
                  s_mainFSMstate <= INCREMENT_ADDR;
Tristan Gingold's avatar
Tristan Gingold committed
675 676
                end if;
              end if;
677 678 679 680 681
            else
              s_mainFSMstate <= DTACK_LOW;
            end if;

          when INCREMENT_ADDR =>
682
            VME_DTACK_OE_o   <= '1';
683
            VME_ADDR_DIR_o   <= s_vme_addr_dir;
684

685
            if s_vme_lword_n_reg = '0' then
686
              if s_transferType = MBLT then
Tristan Gingold's avatar
Tristan Gingold committed
687
                -- 64 bit
688 689
                addr_word_incr := 4;
              else
Tristan Gingold's avatar
Tristan Gingold committed
690
                -- 32 bit
691 692 693
                addr_word_incr := 2;
              end if;
            else
Tristan Gingold's avatar
Tristan Gingold committed
694
              if s_DSlatched_n (0) = '0' then
695 696 697 698 699 700 701 702 703
                -- Next word for D16 or D08(O)
                addr_word_incr := 1;
              else
                addr_word_incr := 0;
              end if;
            end if;
            -- Only increment within the window, don't check the limit.
            -- BLT  --> limit = 256 bytes  (rule 2.12a ANSI/VITA 1-1994)
            -- MBLT --> limit = 2048 bytes (rule 2.78  ANSI/VITA 1-1994)
704 705
            s_vme_addr_reg (11 downto 1) <= std_logic_vector
              (unsigned(s_vme_addr_reg (11 downto 1)) + addr_word_incr);
Tom Levens's avatar
Tom Levens committed
706
            s_mainFSMstate   <= WAIT_FOR_DS;
707

708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733
          when IRQ_CHECK =>
            if VME_IACKIN_n_i = '0' then
              if s_ADDRlatched(3 downto 1) = INT_Level_i
                and irq_pending_i = '1'
              then
                -- That's for us
                s_locDataOut <= (others => '0');
                s_locDataOut (7 downto 0) <= INT_Vector_i;
                s_irq_sel <= '1';
                irq_ack_o <= '1';

                s_mainFSMstate <= WAIT_FOR_DS;
              else
                -- Pass
                VME_IACKOUT_n_o <= '0';
                s_mainFSMstate <= IRQ_PASS;
              end if;
            else
              s_mainFSMstate <= IRQ_CHECK;
            end if;

          when IRQ_PASS =>
            -- Will stay here until AS is released.
            VME_IACKOUT_n_o <= '0';
            s_mainFSMstate <= IRQ_PASS;

734
          when WAIT_END =>
735 736
            -- Will stay here until AS is released.
            s_mainFSMstate <= WAIT_END;
737

738 739 740 741
          when others =>
            s_mainFSMstate <= IDLE;

        end case;
dpedrett's avatar
dpedrett committed
742
      end if;
743 744
    end if;
  end process;
dpedrett's avatar
dpedrett committed
745

746 747 748
  -- Retry is not supported
  VME_RETRY_n_o  <= '1';
  VME_RETRY_OE_o <= '0';
749

Tom Levens's avatar
Tom Levens committed
750
  -- WB Master
751
  adr_o <= "00" & s_vme_addr_reg(31 downto 2);
Tristan Gingold's avatar
Tristan Gingold committed
752
  we_o <= not s_WRITElatched_n;
753
  dat_o <= s_locDataIn(31 downto 0);
Tristan Gingold's avatar
Tristan Gingold committed
754

Tom Levens's avatar
Tom Levens committed
755
  -- Function Decoder
756
  addr_decoder_o <= s_vme_addr_reg & '0';
757
  am_o           <= s_AMlatched;
Tom Levens's avatar
Tom Levens committed
758 759

  -- CR/CSR In/Out
760
  cr_csr_data_o <= s_locDataIn(7 downto 0);
761
  cr_csr_addr_o <= s_vme_addr_reg(18 downto 2);
762

Tristan Gingold's avatar
Tristan Gingold committed
763
  cr_csr_we_o   <= '1' when s_conf_req = '1' and
Tristan Gingold's avatar
Tristan Gingold committed
764
                            s_WRITElatched_n = '0'
Tom Levens's avatar
Tom Levens committed
765
                            else '0';
766
end rtl;