-- SPDX-FileCopyrightText: 2016, MEN Mikro Elektronik GmbH
-- SPDX-License-Identifier: CERN-OHL-S-2.0+

--------------------------------------------------------------------------------
-- Title         : Toplevel File of A25 FPGA
-- Project       : 1614_CERN_A25
--------------------------------------------------------------------------------
-- File          : A25_top.vhd
-- Author        : michael.miehling@men.de
-- Organization  : MEN Mikro Elektronik GmbH
-- Created       : 2016-06-03
--------------------------------------------------------------------------------
-- Simulator     : Modelsim PE 6.6
-- Synthesis     : Quartus 15.1
--------------------------------------------------------------------------------
-- Description :
--
--------------------------------------------------------------------------------
-- Hierarchy:
--
-- A25_top
--    wbb2vme_top
--    sram
--    ip_16z091_01_top
--    iram_wb
--    pll_pcie
--    z126_01_top
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
-- History:
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;
USE ieee.numeric_std.ALL;
USE work.wb_pkg.ALL;
USE work.fpga_pkg_2.ALL;
USE work.z126_01_pkg.ALL;
USE work.vme_pkg.ALL;

ENTITY A25_top IS
GENERIC (
   SIMULATION        : boolean                        := FALSE;
   FPGA_FAMILY       : family_type := CYCLONE4;
   sets              : std_logic_vector(3 DOWNTO 0) := "1110";
   timeout           : integer := 5000 );
PORT (
   clk_16mhz         : IN std_logic;
   led_green_n       : OUT std_logic;
   led_red_n         : OUT std_logic;                                                   
   hreset_n          : IN std_logic;                        -- reset
   v2p_rstn          : OUT std_logic;                       -- connected to hreset_req1_n
   fpga_test         : INOUT std_logic_vector(5 DOWNTO 1);

   -- pcie
   refclk            : IN std_logic;                        -- 100 MHz pcie clock
   pcie_rx           : IN    std_logic_vector(3 DOWNTO 0);                     -- PCIe receive line
   pcie_tx           : OUT   std_logic_vector(3 DOWNTO 0);                     -- PCIe transmit line

   -- sram
   sr_clk            : OUT std_logic;
   sr_a              : OUT std_logic_vector(18 DOWNTO 0);
   sr_d              : INOUT std_logic_vector(15 DOWNTO 0);
   sr_bwa_n          : OUT std_logic;
   sr_bwb_n          : OUT std_logic;
   sr_bw_n           : OUT std_logic;
   sr_cs1_n          : OUT std_logic;
   sr_adsc_n         : OUT std_logic;
   sr_oe_n           : OUT std_logic;
   
   -- vmebus
   vme_ga            : IN std_logic_vector(4 DOWNTO 0);     -- geographical addresses
   vme_gap           : IN std_logic;     -- geographical addresses
   vme_a             : INOUT std_logic_vector(31 DOWNTO 0);
   vme_a_dir         : OUT std_logic;
   vme_a_oe_n        : OUT std_logic; 
   vme_d             : INOUT std_logic_vector(31 DOWNTO 0);
   vme_d_dir         : OUT std_logic;
   vme_d_oe_n        : OUT std_logic;
   vme_am_dir        : OUT std_logic;
   vme_am            : INOUT std_logic_vector(5 DOWNTO 0);
   vme_am_oe_n       : OUT std_logic;
   vme_write_n       : INOUT std_logic;
   vme_iack_n        : INOUT std_logic;
   vme_irq_i_n       : IN std_logic_vector(7 DOWNTO 1);
   vme_irq_o         : OUT std_logic_vector(7 DOWNTO 1); -- high active on A25
   vme_as_i_n        : IN std_logic;
   vme_as_o_n        : OUT std_logic;
   vme_as_oe         : OUT std_logic;                    -- high active on A25
   vme_retry_o_n     : OUT std_logic;
   vme_retry_oe      : OUT std_logic;                    -- high active on A25
   vme_retry_i_n     : IN std_logic;
   vme_sysres_i_n    : IN std_logic;
   vme_sysres_o      : OUT std_logic;                    -- high active on A25
   vme_ds_i_n        : IN std_logic_vector(1 DOWNTO 0);
   vme_ds_o_n        : OUT std_logic_vector(1 DOWNTO 0);
   vme_ds_oe         : OUT std_logic;                    -- high active on A25
   vme_berr_i_n      : IN std_logic;
   vme_berr_o        : OUT std_logic;                    -- high active on A25
   vme_dtack_i_n     : IN std_logic;
   vme_dtack_o       : OUT std_logic;                    -- high active on A25
   vme_scon          : OUT std_logic;                    -- high active on A25
   vme_sysfail_i_n   : IN std_logic;
   vme_sysfail_o     : OUT std_logic;                    -- high active on A25
   vme_bbsy_i_n      : IN std_logic;
   vme_bbsy_o        : OUT std_logic;                    -- high active on A25
   vme_bclr_i_n      : IN std_logic;                           -- bus clear input
   vme_bclr_o_n      : OUT std_logic;                          -- bus clear output
   vme_br_i_n        : IN std_logic_vector(3 DOWNTO 0);
   vme_br_o          : OUT std_logic_vector(3 DOWNTO 0); -- high active on A25
   vme_iack_i_n      : IN std_logic;
   vme_iack_o_n      : OUT std_logic;
   vme_acfail_i_n    : IN std_logic;
   vme_sysclk        : OUT std_logic;
   vme_bg_i_n        : IN std_logic_vector(3 DOWNTO 0);
   vme_bg_o_n        : OUT std_logic_vector(3 DOWNTO 0)
   );
END A25_top;


ARCHITECTURE A25_top_arch OF A25_top IS 
COMPONENT pll_pcie
   PORT
   (
      areset      : IN STD_LOGIC  := '0';
      inclk0      : IN STD_LOGIC  := '0';
      c0      : OUT STD_LOGIC ;
      c1      : OUT STD_LOGIC ;
      c2      : OUT STD_LOGIC ;
      c3      : OUT STD_LOGIC ;
      c4      : OUT STD_LOGIC ;
      locked      : OUT STD_LOGIC 
   );
END COMPONENT;

   function f_sel_pcie_lanes(simulation : boolean)
     return std_logic_vector is
   begin
     if (simulation) then
       return "001"; -- x1 for simulation
     else
       return "100"; -- x4 for synthesis
     end if;
   end function;

   function f_sel_cham_hex(simulation : boolean)
     return string is
   begin
     if (simulation) then
       return "../../A25_VME/Source/chameleon.hex";
     else
       return "../top/chameleon.hex";
     end if;
   end function;
   
   function f_sel_sim_bool(simulation : boolean)
     return std_logic is
   begin
     if (simulation) then
       return '1';
     else
       return '0';
     end if;
   end function;
   
   
   CONSTANT CONST_500HZ : integer := 66667; -- half 500Hz clock period counter value at 66MHz

   SIGNAL sys_clk       : std_logic;                        -- system clock 66 MHz
   SIGNAL sys_rst       : std_logic;                        -- system async reset                  
   SIGNAL rst_33        : std_logic;                        -- reset synchronized to clk_33
   SIGNAL clk_33        : std_logic;                        -- 33 MHz clock for 16z066
   SIGNAL clk_50        : std_logic;                        -- 50 MHz clock for reconfig_clk and cal_blk_clk
   SIGNAL clk_125       : std_logic;                        -- 125 MHz clock for fixed_clk
   SIGNAL clk_500       : std_logic;                        -- 500 Hz clock
   SIGNAL cnt_500hz     : unsigned(16 downto 0);

   -- MASTER SIGNALS
   SIGNAL wbmo_0       : wbo_type;
   SIGNAL wbmi_0       : wbi_type;
   SIGNAL wbmo_0_cyc   : std_logic_vector(3 DOWNTO 0);
   SIGNAL wbmo_0_cyc_bar   : std_logic_vector(6 downto 0);
   signal wbmo_0_adr   : std_logic_vector(31 downto 0);
   SIGNAL wbmo_2       : wbo_type;
   SIGNAL wbmi_2       : wbi_type;
   SIGNAL wbmo_2_cyc   : std_logic_vector(1 DOWNTO 0);
   signal wbmo_3       : wbo_type;
   signal wbmo_3_cyc   : std_logic;
   signal wbmi_3       : wbi_type;
   -- SLAVE SIGNALS
   SIGNAL wbso_0       : wbi_type;
   SIGNAL wbsi_0       : wbo_type;
   SIGNAL wbsi_0_cyc      : std_logic;
   SIGNAL wbso_1       : wbi_type;
   SIGNAL wbsi_1       : wbo_type;
   SIGNAL wbsi_1_cyc      : std_logic;
   SIGNAL wbso_2       : wbi_type;
   SIGNAL wbsi_2       : wbo_type;
   SIGNAL wbsi_2_cyc      : std_logic;
   SIGNAL wbso_3       : wbi_type;
   SIGNAL wbsi_3       : wbo_type;
   SIGNAL wbsi_3_cyc      : std_logic;
   SIGNAL wbso_4       : wbi_type;
   SIGNAL wbsi_4       : wbo_type;
   SIGNAL wbsi_4_cyc      : std_logic;
   
   SIGNAL pll_locked    : std_logic;

   SIGNAL vme_a_out        : std_logic_vector(31 downto 0);
   SIGNAL vme_a_oe_n_int   : std_logic;
   SIGNAL vme_a_dir_int    : std_logic;
   SIGNAL vme_d_out        : std_logic_vector(31 downto 0);
   SIGNAL vme_d_oe_n_int   : std_logic;
   SIGNAL vme_d_dir_int    : std_logic;
   SIGNAL vme_write_n_out  : std_logic;
   SIGNAL vme_am_out       : std_logic_vector(5 downto 0);
   SIGNAL vme_iack_n_out   : std_logic;
   SIGNAL vme_am_oe_n_int   : std_logic;
   SIGNAL vme_am_dir_int    : std_logic;
   SIGNAL vme_irq          : std_logic_vector(7 DOWNTO 0);  -- interrupt request to pci-bus
   SIGNAL berr_irq         : std_logic;                     -- signal berrn interrupt request
   SIGNAL locmon_irq       : std_logic_vector(1 DOWNTO 0);  -- interrupt request location monitor to pci-bus
   SIGNAL mailbox_irq      : std_logic_vector(1 DOWNTO 0);  -- interrupt request mailbox to pci-bus
   SIGNAL mailbox_irq_i    : std_logic;
   SIGNAL dma_irq          : std_logic;
   SIGNAL slot01n          : std_logic;      
   SIGNAL pll_locked_inv   : std_logic;
   SIGNAL startup_rst      : std_logic:='1';
   SIGNAL porst            : std_logic;
   SIGNAL porst_n_q        : std_logic:='0';
   SIGNAL porst_n          : std_logic:='0';
   SIGNAL vme_berr         : std_logic;     
   SIGNAL vme_mstr_busy    : std_logic; 
   SIGNAL led_cnt          : std_logic_vector(17 DOWNTO 0);    -- 2^18 = 3.9 ms
   SIGNAL v2p_rst          : std_logic;
   
   -- high active signals on A25
   SIGNAL vme_irq_o_n       : std_logic_vector(7 DOWNTO 1);
   SIGNAL vme_as_oe_n       : std_logic;
   SIGNAL vme_retry_oe_n    : std_logic;
   SIGNAL vme_sysres_o_n    : std_logic;
   SIGNAL vme_ds_oe_n       : std_logic;
   SIGNAL vme_scon_n        : std_logic;
   SIGNAL vme_sysfail_o_n   : std_logic;
   SIGNAL vme_bbsy_o_n      : std_logic;
   SIGNAL vme_dtack_o_n     : std_logic;
   SIGNAL vme_berr_o_n      : std_logic;
   SIGNAL vme_br_o_n        : std_logic_vector(3 DOWNTO 0);

BEGIN             
   vme_irq_o     <= NOT vme_irq_o_n    ;
   vme_as_oe     <= NOT vme_as_oe_n     ;
   vme_retry_oe  <= NOT vme_retry_oe_n ;
   vme_sysres_o  <= NOT vme_sysres_o_n ;
   vme_ds_oe     <= NOT vme_ds_oe_n    ;
   vme_scon      <= NOT vme_scon_n     ;
   vme_sysfail_o <= NOT vme_sysfail_o_n;
   vme_bbsy_o    <= NOT vme_bbsy_o_n   ;
   vme_br_o      <= NOT vme_br_o_n     ;
   vme_berr_o    <= NOT vme_berr_o_n;
   vme_dtack_o    <= NOT vme_dtack_o_n;
   
   led_red_n <= NOT vme_berr;
--   led_green_n <= slot01;
   vme_sysclk <= clk_16mhz;
   vme_scon_n <= slot01n;
   
   v2p_rstn <= '0' WHEN v2p_rst = '1' ELSE 'Z';

   -- counter for extending vme master active pulses to at least 3 ms
   PROCESS(sys_clk, sys_rst)
   BEGIN
      IF sys_rst = '1' THEN
         led_cnt <= (OTHERS => '0');
         led_green_n <= '1';
      ELSIF sys_clk'event AND sys_clk = '1' THEN
         IF vme_mstr_busy = '1' THEN      -- if master is active, start counter to extend pulse for 3 ms
            led_cnt <= (OTHERS => '1');
            led_green_n <= '0';           -- switch on LED
         ELSIF led_cnt = 0 THEN           -- is 3 ms over?
            led_cnt <= (OTHERS => '0');
            led_green_n <= '1';           -- switch off LED
         ELSE
            led_cnt <= led_cnt - '1';     -- count for 3 ms
            led_green_n <= '0';
         END IF;
      END IF;
   END PROCESS;

   pll_locked_inv <= NOT pll_locked;
   startup_rst <= pll_locked_inv; 
   
   wbso_4.err <= '0';

   fpga_test(1) <= 'Z';
   fpga_test(2) <= 'Z';
   fpga_test(3) <= 'Z';
   fpga_test(4) <= 'Z';
   fpga_test(5) <= 'Z';
  
   -- generate power on reset in order to start application fpga load as early as possible
   PROCESS (clk_16mhz)
   BEGIN
      IF clk_16mhz'EVENT AND clk_16mhz = '1' THEN
         porst_n_q <= '1';
         porst_n <= porst_n_q;
      END IF;
   END PROCESS;
   
   porst <= NOT porst_n;

  -- synchronize reset to 33 MHz clock
   PROCESS(clk_33, pll_locked)
   BEGIN
      IF pll_locked = '0' THEN
         rst_33 <= '1';
      ELSIF clk_33'EVENT AND clk_33 = '1' THEN
         rst_33 <= '0';
      END IF;
   END PROCESS;

   
   PROCESS(sys_clk, hreset_n, pll_locked)
   BEGIN
      IF hreset_n = '0' OR pll_locked = '0' THEN
         sys_rst <= '1';
      ELSIF sys_clk'EVENT AND sys_clk = '1' THEN
         sys_rst <= '0';
      END IF;
   END PROCESS;

   PROCESS(sys_clk, sys_rst)
   BEGIN
      IF sys_rst = '1' THEN
         cnt_500hz <= (others => '0');
         clk_500 <= '0';
      ELSIF sys_clk'EVENT AND sys_clk = '1' THEN
         IF cnt_500hz = to_unsigned(0, cnt_500hz'length) THEN 
            cnt_500hz <= to_unsigned(CONST_500HZ, cnt_500hz'length);
            clk_500 <= NOT clk_500;
         ELSE
            cnt_500hz <= cnt_500hz - 1;
         END IF;
      END IF;
   END PROCESS;
   

pll: pll_pcie
   PORT MAP (
      areset      => porst,
      inclk0      => clk_16mhz,     -- 16 MHz
      c0          => clk_125,       -- 125 MHz
      c1          => clk_50,        -- 50 MHz
      c2          => sys_clk,       -- 66 MHz
      c3          => sr_clk,        -- 66 MHz phase shifted to sys_clk
      c4          => clk_33,        -- 33 MHz
      locked      => pll_locked
   );

   -- +-Module Name--------------+-dst-+---offset-+------size-+-bar-+
   -- |     Chameleon Table      | cam |        0 |       200 |   0 |
   -- |     16Z126_SERFLASH      | flh |      200 |        20 |   0 |
   -- |16z002-01 VME REGS        | vme |    10000 |       200 |   0 |
   -- |16z002-01 VME IACK        | vme |    10200 |       200 |   0 |
   -- |16z002-01 VME A16D16      | vme |    20000 |    1_0000 |   0 |
   -- |16z002-01 VME A16D32      | vme |    30000 |    1_0000 |   0 |
   -- |  16z002-01 VME SRAM      | ram |        0 |   10_0000 |   1 |
   -- |16z002-01 VME A24D16      | vme |        0 |  100_0000 |   2 |
   -- |16z002-01 VME A24D32      | vme |  1000000 |  100_0000 |   2 |
   -- |   16z002-01 VME A32      | vme |        0 | 2000_0000 |   3 |
   -- |16z002-01 VME CR/CSR      | vme |        0 |  100_0000 |   4 |
   -- +--------------------------+-----+----------+-----------+-----+
   process (wbmo_0_cyc_bar, wbmo_0_adr, wbmo_0)
   begin
      wbmo_0_cyc <= "0000";
      wbmo_0.tga(6 DOWNTO 0) <= (others => 'X');
      wbmo_0.adr <= wbmo_0_adr;
      if wbmo_0_cyc_bar(0) = '1' then
        case wbmo_0_adr(17 DOWNTO 16) is
          when "00" =>
            if wbmo_0_adr(15 DOWNTO 9) = "0000000" then
               -- Chameleon Table - cycle 0 - offset 0 - size 200 --
               wbmo_0_cyc <= "0001";
            elsif wbmo_0_adr(15 DOWNTO 5) = "00000010000" then
               -- 16Z126_SERFLASH - cycle 1 - offset 200 - size 20 --
               wbmo_0_cyc <= "0010";
            end if;
          when "01" =>
            if wbmo_0_adr(8) = '1' then
               wbmo_0_cyc <= "0100";
               wbmo_0.tga(6 DOWNTO 0) <= CONST_VME_IACK;
            else
               -- 16z002-01 VME regs - cycle 2 - offset 10000 - size 10000 --
               wbmo_0_cyc <= "1000";
               wbmo_0.adr(31 downto 10) <= (others => '0');
               wbmo_0.adr(9) <= '0';
            end if;
          when "10" =>
            -- 16z002-01 VME A16D16 - cycle 3 - offset 20000 - size 10000 --
            wbmo_0_cyc <= "0100";
            wbmo_0.tga(6 DOWNTO 0) <= CONST_VME_A16D16;
          when "11" =>
            -- 16z002-01 VME A16D32 - cycle 4 - offset 30000 - size 10000 --
            wbmo_0_cyc <= "0100";
            wbmo_0.tga(6 DOWNTO 0) <= CONST_VME_A16D32;
         when others =>
            null;
         end case;
      elsif wbmo_0_cyc_bar (1) = '1' then
         -- 16z002-01 VME SRAM - cycle 5 - offset 0 - size 100000 --
         wbmo_0_cyc <= "1000";
         wbmo_0.adr(31 downto 10) <= (others => '0');
         wbmo_0.adr(9) <= '1';
      elsif wbmo_0_cyc_bar (2) = '1' then
         wbmo_0_cyc <= "0100";
         if wbmo_0_adr(24) = '0' then
           -- 16z002-01 VME A24D16 - cycle 6 - offset 0 - size 1000000 --
           wbmo_0.tga(6 DOWNTO 0) <= CONST_VME_A24D16;
         else
           -- 16z002-01 VME A24D32 - cycle 7 - offset 1000000 - size 1000000 --
           wbmo_0.tga(6 DOWNTO 0) <= CONST_VME_A24D32;
         end if;
       elsif wbmo_0_cyc_bar (3) = '1' then
         -- 16z002-01 VME A32 - cycle 8 - offset 0 - size 20000000 --
         wbmo_0_cyc <= "0100";
         wbmo_0.tga(6 DOWNTO 0) <= CONST_VME_A32D32;
       elsif wbmo_0_cyc_bar (4) = '1' then
         -- 16z002-01 VME CRCSR - cycle 9 - offset 0 - size 1000000 --
         wbmo_0_cyc <= "0100";
         wbmo_0.tga(6 DOWNTO 0) <= CONST_VME_CRCSR;
      end if;
   end process;


   wbmo_0.tga(7) <= '0'; -- indicate access from PCIE
   wbmo_0.tga(8) <= '0'; -- unused
                                                                                                                               
pcie: entity work.ip_16z091_01_top
   GENERIC MAP (
      SIMULATION           => f_sel_sim_bool(SIMULATION),
      FPGA_FAMILY          => CYCLONE4,
      IRQ_WIDTH            => 13,
      USE_LANES            => f_sel_pcie_lanes(SIMULATION),
      PCIE_REQUEST_LENGTH  => "0001000000",    -- 64DW = 256Byte
      RX_LPM_WIDTHU        => 10,
      TX_HEADER_LPM_WIDTHU => 5,
      TX_DATA_LPM_WIDTHU   => 7
   )
   PORT MAP (
   -- Hard IP ports:
      clk_50             => clk_50,
      clk_125            => clk_125,
      ref_clk            => refclk,
      clk_500            => clk_500,
      ext_rst_n          => hreset_n,

      rx_0               => pcie_rx(0),
      rx_1               => pcie_rx(1),
      rx_2               => pcie_rx(2),
      rx_3               => pcie_rx(3),

      tx_0               => pcie_tx(0),
      tx_1               => pcie_tx(1),
      tx_2               => pcie_tx(2),
      tx_3               => pcie_tx(3),

      wb_clk             => sys_clk,
      wb_rst             => sys_rst,

      wbm_ack            => wbmi_0.ack,
      wbm_dat_i          => wbmi_0.dat,
      wbm_stb            => wbmo_0.stb,
      wbm_cyc_bar_o      => wbmo_0_cyc_bar,
      wbm_we             => wbmo_0.we ,
      wbm_sel            => wbmo_0.sel,
      wbm_adr            => wbmo_0_adr,
      wbm_dat_o          => wbmo_0.dat,
      wbm_cti            => wbmo_0.cti,
      wbm_tga            => open,

      wbs_cyc            => wbsi_4_cyc,
      wbs_stb            => wbsi_4.stb,
      wbs_we             => wbsi_4.we ,
      wbs_sel            => wbsi_4.sel,
      wbs_adr            => wbsi_4.adr,
      wbs_dat_i          => wbsi_4.dat,
      wbs_cti            => wbsi_4.cti,
      wbs_tga            => wbsi_4.tga(0),
      wbs_ack            => wbso_4.ack,
      wbs_err            => open,
      wbs_dat_o          => wbso_4.dat,
      
      irq_req_i(7 downto 0)      => vme_irq,
      irq_req_i(8)      => berr_irq,
      irq_req_i(9)      => dma_irq,
      irq_req_i(10)     => locmon_irq(0),
      irq_req_i(11)     => locmon_irq(1),
      irq_req_i(12)     => mailbox_irq_i,

      error_timeout      => open,
      error_cor_ext_rcv  => open,
      error_cor_ext_rpl  => open,
      error_rpl          => open,
      error_r2c0         => open,
      error_msi_num      => open,

      link_train_active  => open
   );
      
 
   mailbox_irq_i <= mailbox_irq(0) OR mailbox_irq(1);
   
   cham: entity work.iram_wb
   GENERIC MAP (
      FPGA_FAMILY    => FPGA_FAMILY,
      read_only      => 1,
      USEDW_WIDTH    => 9, -- 0x200 = 512
      LOCATION       => f_sel_cham_hex(SIMULATION)
   )
   PORT MAP (
      clk            => sys_clk,
      rst            => sys_rst,
      stb_i          => wbsi_0.stb,
      cyc_i          => wbsi_0_cyc,
      ack_o          => wbso_0.ack,
      err_o          => wbso_0.err,
      we_i           => wbsi_0.we,
      sel_i          => wbsi_0.sel,
      adr_i          => wbsi_0.adr(10 DOWNTO 2),
      dat_i          => wbsi_0.dat,
      dat_o          => wbso_0.dat
      );

   sr_oe_n <= '1';
   sr_cs1_n <= '1'; --sys_rst;      -- selected if FPGA reset is released

sflash: entity work.z126_01_top
   GENERIC MAP (
      SIMULATION              => SIMULATION,
      FPGA_FAMILY             => CYCLONE4,
      FLASH_TYPE              => M25P32,
      USE_DIRECT_INTERFACE    => FALSE,
      USE_REMOTE_UPDATE       => TRUE,
      LOAD_FPGA_IMAGE         => TRUE,
      LOAD_FPGA_IMAGE_ADR     => X"200100"
   )
   PORT MAP (
      clk_40mhz               => clk_33,
      rst_clk_40mhz           => rst_33,                                                                   
      clk_dir                 => sys_clk,
      rst_dir                 => sys_rst,      
      clk_indi                => sys_clk, 
      rst_indi                => sys_rst, 
      board_status            => open,
      wbs_stb_dir             => '0',            
      wbs_ack_dir             => OPEN,           
      wbs_we_dir              => '0',            
      wbs_sel_dir             => (OTHERS => '0'),
      wbs_cyc_dir             => '0',            
      wbs_dat_o_dir           => OPEN,           
      wbs_dat_i_dir           => (OTHERS => '0'),
      wbs_adr_dir             => (OTHERS => '0'),
      wbs_err_dir             => OPEN,           
      
      -- wishbone signals slave interface 1 (indirect addressing)
      wbs_stb_indi            => wbsi_1.stb,
      wbs_ack_indi            => wbso_1.ack,
      wbs_we_indi             => wbsi_1.we, 
      wbs_sel_indi            => wbsi_1.sel,
      wbs_cyc_indi            => wbsi_1_cyc,
      wbs_dat_o_indi          => wbso_1.dat,
      wbs_dat_i_indi          => wbsi_1.dat,
      wbs_adr_indi            => wbsi_1.adr,
      wbs_err_indi            => wbso_1.err 
   );


vme: entity work.wbb2vme_top
GENERIC MAP(
   A16_REG_MAPPING   => true,
   LONGADD_SIZE      => 3,
   USE_LONGADD       => TRUE                        
   )
PORT MAP (
   clk               => sys_clk,
   rst               => sys_rst,
   startup_rst       => startup_rst,
   postwr            => open,
   vme_irq           => vme_irq ,
   berr_irq          => berr_irq,
   locmon_irq        => locmon_irq ,
   mailbox_irq       => mailbox_irq,
   dma_irq           => dma_irq ,
   prevent_sysrst    => '0',

   --  Registers
   wbr_stb_i          => wbsi_3.stb,
   wbr_cyc_i          => wbsi_3_cyc,
   wbr_ack_o          => wbso_3.ack,
   wbr_err_o          => wbso_3.err,
   wbr_we_i           => wbsi_3.we,
   wbr_sel_i          => wbsi_3.sel,
   wbr_adr_i          => wbsi_3.adr,
   wbr_dat_i          => wbsi_3.dat,
   wbr_dat_o          => wbso_3.dat,

   -- vmectrl slave
   wbs_stb_i         => wbsi_2.stb,
   wbs_ack_o         => wbso_2.ack,
   wbs_err_o         => wbso_2.err,
   wbs_we_i          => wbsi_2.we,
   wbs_sel_i         => wbsi_2.sel,
   wbs_cyc_i         => wbsi_2_cyc,
   wbs_adr_i         => wbsi_2.adr,
   wbs_dat_o         => wbso_2.dat,
   wbs_dat_i         => wbsi_2.dat,
   wbs_tga_i         => wbsi_2.tga,

   wbm_dma_stb_o     => wbmo_2.stb,
   wbm_dma_ack_i     => wbmi_2.ack,
   wbm_dma_we_o      => wbmo_2.we,
   wbm_dma_cti       => wbmo_2.cti,
   wbm_dma_tga_o     => wbmo_2.tga,
   wbm_dma_err_i     => wbmi_2.err,
   wbm_dma_sel_o     => wbmo_2.sel,
   wbm_dma_cyc_vme   => wbmo_2_cyc(0),
   wbm_dma_cyc_pci   => wbmo_2_cyc(1),
   wbm_dma_adr_o     => wbmo_2.adr,
   wbm_dma_dat_o     => wbmo_2.dat,
   wbm_dma_dat_i     => wbmi_2.dat,

   pci_cyc_o         => wbmo_3_cyc,
   pci_stb_o         => wbmo_3.stb,
   pci_we_o          => wbmo_3.we,
   pci_sel_o         => wbmo_3.sel,
   pci_tga_o         => wbmo_3.tga,
   pci_cti_o         => wbmo_3.cti,
   pci_adr_o         => wbmo_3.adr,
   pci_dat_o         => wbmo_3.dat,
   pci_dat_i         => wbmi_3.dat,
   pci_ack_i         => wbmi_3.ack,
   pci_err_i         => wbmi_3.err,

   va_o              => vme_a_out,
   va_i              => vme_a,
   vd_o              => vme_d_out,
   vd_i              => vme_d,
   vam_o             => vme_am_out,
   vam_i             => vme_am,
   writen_o          => vme_write_n_out,
   writen_i          => vme_write_n,
   iackn_o           => vme_iack_n_out,
   iackn_i           => vme_iack_n,
   irq_i_n           => vme_irq_i_n,
   irq_o_n           => vme_irq_o_n,
   as_o_n            => vme_as_o_n,
   as_oe_n           => vme_as_oe_n,
   as_i_n            => vme_as_i_n,
   sysresn           => vme_sysres_o_n,
   sysresin          => vme_sysres_i_n,
   ds_o_n            => vme_ds_o_n,
   ds_i_n            => vme_ds_i_n,
   ds_oe_n           => vme_ds_oe_n,
   berrn             => vme_berr_o_n,
   berrin            => vme_berr_i_n,
   dtackn            => vme_dtack_o_n,
   dtackin           => vme_dtack_i_n,
   slot01n           => slot01n,
   sysfail_i_n       => vme_sysfail_i_n,
   sysfail_o_n       => vme_sysfail_o_n,
   bbsyn             => vme_bbsy_o_n,
   bbsyin            => vme_bbsy_i_n,
   bclr_i_n          => vme_bclr_i_n,
   bclr_o_n          => vme_bclr_o_n,
   retry_i_n         => vme_retry_i_n  ,
   retry_o_n         => vme_retry_o_n  ,
   retry_oe_n        => vme_retry_oe_n ,
   br_i_n            => vme_br_i_n,
   br_o_n            => vme_br_o_n,
   iackin            => vme_iack_i_n,
   iackoutn          => vme_iack_o_n,
   acfailn           => vme_acfail_i_n,
   bg_i_n            => vme_bg_i_n,
   bg_o_n            => vme_bg_o_n,
   ga                => vme_ga,
   gap               => vme_gap,
   vme_berr          => vme_berr,         
   vme_mstr_busy     => vme_mstr_busy,
   d_dir             => vme_d_dir_int,
   d_oe_n            => vme_d_oe_n_int,
   am_dir            => vme_am_dir_int,
   am_oe_n           => vme_am_oe_n_int,
   a_dir             => vme_a_dir_int,
   a_oe_n            => vme_a_oe_n_int,
   v2p_rst           => v2p_rst 
   );

  vme_a_oe_n <= vme_a_oe_n_int;
  vme_a_dir <= vme_a_dir_int;
  vme_a <= vme_a_out when vme_a_oe_n_int = '0' and vme_a_dir_int = '1' else (others => 'Z');

  vme_d_oe_n <= vme_d_oe_n_int;
  vme_d_dir <= vme_d_dir_int;
  vme_d <= vme_d_out when vme_d_oe_n_int = '0' and vme_d_dir_int = '1' else (others => 'Z');

  vme_am_oe_n <= vme_am_oe_n_int;
  vme_am_dir <= vme_am_dir_int;
  vme_write_n <= vme_write_n_out when vme_am_oe_n_int = '0' and vme_am_dir_int = '1' else 'Z';
  vme_am <= vme_am_out  when vme_am_oe_n_int = '0' and vme_am_dir_int = '1' else (others => 'Z');
  vme_iack_n <= vme_iack_n_out when vme_am_oe_n_int = '0' and vme_am_dir_int = '1' else 'Z';

wbb : entity work.wb_bus
GENERIC MAP (
   sets           => sets,
   timeout        => timeout
)
PORT MAP (
   clk            => sys_clk,
   rst            => sys_rst,

   wbmo_0        => wbmo_0,
   wbmi_0        => wbmi_0,
   wbmo_0_cyc    => wbmo_0_cyc,
   wbmo_2        => wbmo_2,
   wbmi_2        => wbmi_2,
   wbmo_2_cyc    => wbmo_2_cyc,
   wbmo_3        => wbmo_3,
   wbmi_3        => wbmi_3,
   wbmo_3_cyc    => wbmo_3_cyc,
   wbso_0        => wbso_0,
   wbsi_0        => wbsi_0,
   wbsi_0_cyc    => wbsi_0_cyc,
   wbso_1        => wbso_1,
   wbsi_1        => wbsi_1,
   wbsi_1_cyc    => wbsi_1_cyc,
   wbso_2        => wbso_2,
   wbsi_2        => wbsi_2,
   wbsi_2_cyc    => wbsi_2_cyc,
   wbso_3        => wbso_3,
   wbsi_3        => wbsi_3,
   wbsi_3_cyc    => wbsi_3_cyc,
   wbso_4        => wbso_4,
   wbsi_4        => wbsi_4,
   wbsi_4_cyc    => wbsi_4_cyc
);
      

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

END A25_top_arch;
