vme_bus.vhd 27.1 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;
76
    rst_n_i         : in  std_logic;
Tom Levens's avatar
Tom Levens committed
77

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
103 104 105 106 107 108 109 110 111 112
    wb_stb_o        : out std_logic;
    wb_ack_i        : in  std_logic;
    wb_dat_o        : out std_logic_vector(31 downto 0);
    wb_dat_i        : in  std_logic_vector(31 downto 0);
    wb_adr_o        : out std_logic_vector(31 downto 0);
    wb_sel_o        : out std_logic_vector(3 downto 0);
    wb_we_o         : out std_logic;
    wb_cyc_o        : out std_logic;
    wb_err_i        : in  std_logic;
    wb_stall_i      : in  std_logic;
113

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
  -- (max skew for the slave is 20 ns)
237
  constant c_num_latchDS            : natural range 1 to 8 :=
238 239 240 241
    (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_n_i = '0' 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

        -- WB
320 321 322
        wb_sel_o            <= "0000";
        wb_cyc_o            <= '0';
        wb_stb_o            <= '0';
323
        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
            --  DS latch counter
392
            s_DS_latch_count <= to_unsigned (c_num_latchDS, 3);
393

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 456 457
              if s_DS_latch_count /= 0 then
                s_DS_latch_count <= s_DS_latch_count - 1;
              end if;
458
              s_mainFSMstate <= LATCH_DS;
459 460 461 462
            else
              s_mainFSMstate <= WAIT_FOR_DS;
            end if;

463
          when LATCH_DS =>
Tristan Gingold's avatar
Tristan Gingold committed
464 465
            -- 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
466

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

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

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

482
            if s_DS_latch_count = 0 or s_transferType = MBLT then
483 484 485
              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
486 487 488 489 490 491
                -- MBLT: ack address.
                -- (Data are also read but discarded).
                s_mainFSMstate <= DTACK_LOW;
              else
                s_mainFSMstate <= CHECK_TRANSFER_TYPE;
              end if;
492 493

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

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

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

510 511 512 513 514 515 516
            --  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;

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

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

Tristan Gingold's avatar
Tristan Gingold committed
539 540 541 542
            --  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.
543
            if s_vme_lword_n_reg = '0' and s_DSlatched_n /= "00" then
Tristan Gingold's avatar
Tristan Gingold committed
544 545 546 547 548
              -- unaligned.
              s_mainFSMstate <= WAIT_END;
            else
              s_mainFSMstate <= MEMORY_REQ;
              s_conf_req <= s_conf_sel;
Tristan Gingold's avatar
Tristan Gingold committed
549 550

              -- Start WB cycle.
551 552
              wb_cyc_o <= s_card_sel;
              wb_stb_o <= s_card_sel;
Tristan Gingold's avatar
Tristan Gingold committed
553 554
              s_err <= '0';
            end if;
555

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

Tristan Gingold's avatar
Tristan Gingold committed
563
            -- Assert STB if stall was asserted.
564
            wb_stb_o <= s_card_sel and wb_stall_i;
565 566

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

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

584
                  wb_stb_o <= s_card_sel;
585 586

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

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

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

612
                  wb_stb_o <= s_card_sel;
613 614

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

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

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

632 633 634
            -- 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
635
            s_mainFSMstate   <= DTACK_LOW;
636

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

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

649 650 651 652
            -- 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.
653
            if VME_DS_n_i = "11" then
654 655
              VME_DATA_DIR_o  <= '0';
              VME_BERR_n_o    <= '1';
Tristan Gingold's avatar
Tristan Gingold committed
656 657 658

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

              --  DS latch counter
661
              s_DS_latch_count <= to_unsigned (c_num_latchDS, 3);
662

663 664 665
              if s_irq_sel = '1' then
                s_mainFSMstate <= WAIT_END;
              elsif s_transferType = SINGLE then
Tristan Gingold's avatar
Tristan Gingold committed
666 667 668 669 670 671
                --  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.
672
                  s_mainFSMstate <= WAIT_FOR_DS;
Tristan Gingold's avatar
Tristan Gingold committed
673 674 675
                  s_MBLT_Data <= '1';
                else
                  -- Block
676
                  s_mainFSMstate <= INCREMENT_ADDR;
Tristan Gingold's avatar
Tristan Gingold committed
677 678
                end if;
              end if;
679 680 681 682 683
            else
              s_mainFSMstate <= DTACK_LOW;
            end if;

          when INCREMENT_ADDR =>
684
            VME_DTACK_OE_o   <= '1';
685
            VME_ADDR_DIR_o   <= s_vme_addr_dir;
686

687
            if s_vme_lword_n_reg = '0' then
688
              if s_transferType = MBLT then
Tristan Gingold's avatar
Tristan Gingold committed
689
                -- 64 bit
690 691
                addr_word_incr := 4;
              else
Tristan Gingold's avatar
Tristan Gingold committed
692
                -- 32 bit
693 694 695
                addr_word_incr := 2;
              end if;
            else
Tristan Gingold's avatar
Tristan Gingold committed
696
              if s_DSlatched_n (0) = '0' then
697 698 699 700 701 702 703 704 705
                -- 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)
706 707
            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
708
            s_mainFSMstate   <= WAIT_FOR_DS;
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 734 735
          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;

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

740 741 742 743
          when others =>
            s_mainFSMstate <= IDLE;

        end case;
dpedrett's avatar
dpedrett committed
744
      end if;
745 746
    end if;
  end process;
dpedrett's avatar
dpedrett committed
747

748 749 750
  -- Retry is not supported
  VME_RETRY_n_o  <= '1';
  VME_RETRY_OE_o <= '0';
751

Tom Levens's avatar
Tom Levens committed
752
  -- WB Master
753 754 755
  wb_adr_o <= "00" & s_vme_addr_reg(31 downto 2);
  wb_we_o <= not s_WRITElatched_n;
  wb_dat_o <= s_locDataIn(31 downto 0);
Tristan Gingold's avatar
Tristan Gingold committed
756

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

  -- CR/CSR In/Out
762 763 764 765 766
  cr_csr_data_o  <= s_locDataIn(7 downto 0);
  cr_csr_addr_o  <= s_vme_addr_reg(18 downto 2);
  cr_csr_we_o    <= '1' when s_conf_req = '1' and
                             s_WRITElatched_n = '0'
                             else '0';
767
end rtl;