--------------------------------------------------------------------------------
-- CERN BE-CO-HT
-- White Rabbit Trigger Distribution
-- https://ohwr-gitlab.cern.ch/projects/wrtd
--------------------------------------------------------------------------------
--
-- unit name:   wrtd_ref_svec_tdc_fd
--
-- description: Top entity for WRTD reference design
--
-- Top level design of the SVEC-based WRTD node, with
-- an FMC TDC in slot 1 and an FMC Fine Delay in slot 2.
--
-- This is the standard pulse-in/pulse-out WRTD node, with the FMC TDC
-- injecting pulses into the WR network in the form of WRTD messages and
-- the FMC Fine Delay converting those messages back to pulses at the
-- destination.
--
--------------------------------------------------------------------------------
-- Copyright CERN 2014-2019
--------------------------------------------------------------------------------
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
--------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library work;
use work.gencores_pkg.all;
use work.wishbone_pkg.all;
use work.mt_mqueue_pkg.all;
use work.mock_turtle_pkg.all;
use work.wr_board_pkg.all;
use work.wr_fabric_pkg.all;

library unisim;
use unisim.vcomponents.all;

entity wrtd_ref_svec_tdc_x2 is
  generic (
    g_WRPC_INITF    : string  := "../../../dependencies/wr-cores/bin/wrpc/wrc_phy8.bram";
    g_MT_CPU0_INITF : string  := "../../../software/firmware/tdc-x2/wrtd-rt-tdc-x2.bram";
    -- Simulation-mode enable parameter. Set by default (synthesis) to 0, and
    -- changed to non-zero in the instantiation of the top level DUT in the
    -- testbench. Its purpose is to reduce some internal counters/timeouts
    -- to speed up simulations.
    g_SIMULATION     : integer := 0);
  port (
    ---------------------------------------------------------------------------
    -- Clocks/resets
    ---------------------------------------------------------------------------

    -- Reset from system fpga
    rst_n_i : in std_logic;

    -- Local oscillators
    clk_20m_vcxo_i : in std_logic;  -- 20MHz VCXO clock

    clk_125m_pllref_p_i : in std_logic;  -- 125 MHz PLL reference
    clk_125m_pllref_n_i : in std_logic;

    clk_125m_gtp_n_i : in std_logic;  -- 125 MHz GTP reference
    clk_125m_gtp_p_i : in std_logic;

    ---------------------------------------------------------------------------
    -- VME interface
    ---------------------------------------------------------------------------

    vme_write_n_i    : in    std_logic;
    vme_sysreset_n_i : in    std_logic;
    vme_retry_oe_o   : out   std_logic;
    vme_retry_n_o    : out   std_logic;
    vme_lword_n_b    : inout std_logic;
    vme_iackout_n_o  : out   std_logic;
    vme_iackin_n_i   : in    std_logic;
    vme_iack_n_i     : in    std_logic;
    vme_gap_i        : in    std_logic;
    vme_dtack_oe_o   : out   std_logic;
    vme_dtack_n_o    : out   std_logic;
    vme_ds_n_i       : in    std_logic_vector(1 downto 0);
    vme_data_oe_n_o  : out   std_logic;
    vme_data_dir_o   : out   std_logic;
    vme_berr_o       : out   std_logic;
    vme_as_n_i       : in    std_logic;
    vme_addr_oe_n_o  : out   std_logic;
    vme_addr_dir_o   : out   std_logic;
    vme_irq_o        : out   std_logic_vector(7 downto 1);
    vme_ga_i         : in    std_logic_vector(4 downto 0);
    vme_data_b       : inout std_logic_vector(31 downto 0);
    vme_am_i         : in    std_logic_vector(5 downto 0);
    vme_addr_b       : inout std_logic_vector(31 downto 1);

    ---------------------------------------------------------------------------
    -- SPI interfaces to DACs
    ---------------------------------------------------------------------------

    pll20dac_din_o    : out std_logic;
    pll20dac_sclk_o   : out std_logic;
    pll20dac_sync_n_o : out std_logic;
    pll25dac_din_o    : out std_logic;
    pll25dac_sclk_o   : out std_logic;
    pll25dac_sync_n_o : out std_logic;

    ---------------------------------------------------------------------------
    -- SFP I/O for transceiver
    ---------------------------------------------------------------------------

    sfp_txp_o         : out   std_logic;
    sfp_txn_o         : out   std_logic;
    sfp_rxp_i         : in    std_logic;
    sfp_rxn_i         : in    std_logic;
    sfp_mod_def0_i    : in    std_logic;  -- sfp detect
    sfp_mod_def1_b    : inout std_logic;  -- scl
    sfp_mod_def2_b    : inout std_logic;  -- sda
    sfp_rate_select_o : out   std_logic;
    sfp_tx_fault_i    : in    std_logic;
    sfp_tx_disable_o  : out   std_logic;
    sfp_los_i         : in    std_logic;

    ---------------------------------------------------------------------------
    -- Carrier I2C EEPROM
    ---------------------------------------------------------------------------

    carrier_scl_b : inout std_logic;
    carrier_sda_b : inout std_logic;

    ---------------------------------------------------------------------------
    -- PCB version
    ---------------------------------------------------------------------------
    pcbrev_i : in std_logic_vector(4 downto 0);

    ---------------------------------------------------------------------------
    -- Onewire interface
    ---------------------------------------------------------------------------

    onewire_b : inout std_logic;

    ---------------------------------------------------------------------------
    -- UART
    ---------------------------------------------------------------------------

    uart_rxd_i : in  std_logic;
    uart_txd_o : out std_logic;

    ---------------------------------------------------------------------------
    -- SPI (flash is connected to SFPGA and routed to AFPGA
    -- once the boot process is complete)
    ---------------------------------------------------------------------------

    spi_sclk_o : out std_logic;
    spi_ncs_o  : out std_logic;
    spi_mosi_o : out std_logic;
    spi_miso_i : in  std_logic;

    ---------------------------------------------------------------------------
    -- Carrier front panel LEDs and IOs
    ---------------------------------------------------------------------------

    fp_led_line_oen_o : out std_logic_vector(1 downto 0);
    fp_led_line_o     : out std_logic_vector(1 downto 0);
    fp_led_column_o   : out std_logic_vector(3 downto 0);

    fp_gpio1_b      : out std_logic;  -- PPS output
    fp_gpio2_b      : out std_logic;  -- not used
    fp_gpio3_b      : in  std_logic;  -- ext 10MHz clock input
    fp_gpio4_b      : in  std_logic;  -- ext PPS input
    fp_term_en_o    : out std_logic_vector(4 downto 1);
    fp_gpio1_a2b_o  : out std_logic;
    fp_gpio2_a2b_o  : out std_logic;
    fp_gpio34_a2b_o : out std_logic;

    ---------------------------------------------------------------------------
    -- FMC slot 1 pins (TDC mezzanine)
    ---------------------------------------------------------------------------

    -- TDC1 PLL AD9516 and DAC AD5662 interface
    fmc0_tdc_pll_sclk_o       : out std_logic;
    fmc0_tdc_pll_sdi_o        : out std_logic;
    fmc0_tdc_pll_cs_n_o       : out std_logic;
    fmc0_tdc_pll_dac_sync_o   : out std_logic;
    fmc0_tdc_pll_sdo_i        : in  std_logic;
    fmc0_tdc_pll_status_i     : in  std_logic;
    fmc0_tdc_clk_125m_p_i     : in  std_logic;
    fmc0_tdc_clk_125m_n_i     : in  std_logic;
    fmc0_tdc_acam_refclk_p_i  : in  std_logic;
    fmc0_tdc_acam_refclk_n_i  : in  std_logic;

    -- TDC1 ACAM timing interface
    fmc0_tdc_start_from_fpga_o : out std_logic;
    fmc0_tdc_err_flag_i        : in  std_logic;
    fmc0_tdc_int_flag_i        : in  std_logic;
    fmc0_tdc_start_dis_o       : out std_logic;
    fmc0_tdc_stop_dis_o        : out std_logic;

    -- TDC1 ACAM data interface
    fmc0_tdc_data_bus_io : inout std_logic_vector(27 downto 0);
    fmc0_tdc_address_o   : out   std_logic_vector(3 downto 0);
    fmc0_tdc_cs_n_o      : out   std_logic;
    fmc0_tdc_oe_n_o      : out   std_logic;
    fmc0_tdc_rd_n_o      : out   std_logic;
    fmc0_tdc_wr_n_o      : out   std_logic;
    fmc0_tdc_ef1_i       : in    std_logic;
    fmc0_tdc_ef2_i       : in    std_logic;

    -- TDC1 Input Logic
    fmc0_tdc_enable_inputs_o : out std_logic;
    fmc0_tdc_term_en_1_o     : out std_logic;
    fmc0_tdc_term_en_2_o     : out std_logic;
    fmc0_tdc_term_en_3_o     : out std_logic;
    fmc0_tdc_term_en_4_o     : out std_logic;
    fmc0_tdc_term_en_5_o     : out std_logic;

    -- TDC1 1-wire UniqueID & Thermometer
    fmc0_onewire_b           : inout std_logic;

    -- TDC1 EEPROM I2C
    fmc0_tdc_scl_b : inout std_logic;
    fmc0_tdc_sda_b : inout std_logic;

    -- TDC1 LEDs
    fmc0_tdc_led_status_o : out std_logic;
    fmc0_tdc_led_trig1_o  : out std_logic;
    fmc0_tdc_led_trig2_o  : out std_logic;
    fmc0_tdc_led_trig3_o  : out std_logic;
    fmc0_tdc_led_trig4_o  : out std_logic;
    fmc0_tdc_led_trig5_o  : out std_logic;

    fmc0_prsnt_m2c_n_i : in std_logic;

    fmc0_scl_b : inout std_logic;
    fmc0_sda_b : inout std_logic;

    ---------------------------------------------------------------------------
    -- FMC slot 2 pins (TDC mezzanine)
    ---------------------------------------------------------------------------

    -- TDC1 PLL AD9516 and DAC AD5662 interface
    fmc1_tdc_pll_sclk_o       : out std_logic;
    fmc1_tdc_pll_sdi_o        : out std_logic;
    fmc1_tdc_pll_cs_n_o       : out std_logic;
    fmc1_tdc_pll_dac_sync_o   : out std_logic;
    fmc1_tdc_pll_sdo_i        : in  std_logic;
    fmc1_tdc_pll_status_i     : in  std_logic;
    fmc1_tdc_clk_125m_p_i     : in  std_logic;
    fmc1_tdc_clk_125m_n_i     : in  std_logic;
    fmc1_tdc_acam_refclk_p_i  : in  std_logic;
    fmc1_tdc_acam_refclk_n_i  : in  std_logic;

    -- TDC1 ACAM timing interface
    fmc1_tdc_start_from_fpga_o : out std_logic;
    fmc1_tdc_err_flag_i        : in  std_logic;
    fmc1_tdc_int_flag_i        : in  std_logic;
    fmc1_tdc_start_dis_o       : out std_logic;
    fmc1_tdc_stop_dis_o        : out std_logic;

    -- TDC1 ACAM data interface
    fmc1_tdc_data_bus_io : inout std_logic_vector(27 downto 0);
    fmc1_tdc_address_o   : out   std_logic_vector(3 downto 0);
    fmc1_tdc_cs_n_o      : out   std_logic;
    fmc1_tdc_oe_n_o      : out   std_logic;
    fmc1_tdc_rd_n_o      : out   std_logic;
    fmc1_tdc_wr_n_o      : out   std_logic;
    fmc1_tdc_ef1_i       : in    std_logic;
    fmc1_tdc_ef2_i       : in    std_logic;

    -- TDC1 Input Logic
    fmc1_tdc_enable_inputs_o : out std_logic;
    fmc1_tdc_term_en_1_o     : out std_logic;
    fmc1_tdc_term_en_2_o     : out std_logic;
    fmc1_tdc_term_en_3_o     : out std_logic;
    fmc1_tdc_term_en_4_o     : out std_logic;
    fmc1_tdc_term_en_5_o     : out std_logic;

    -- TDC1 1-wire UniqueID & Thermometer
    fmc1_onewire_b : inout std_logic;

    -- TDC1 EEPROM I2C
    fmc1_tdc_scl_b : inout std_logic;
    fmc1_tdc_sda_b : inout std_logic;

    -- TDC1 LEDs
    fmc1_tdc_led_status_o : out std_logic;
    fmc1_tdc_led_trig1_o  : out std_logic;
    fmc1_tdc_led_trig2_o  : out std_logic;
    fmc1_tdc_led_trig3_o  : out std_logic;
    fmc1_tdc_led_trig4_o  : out std_logic;
    fmc1_tdc_led_trig5_o  : out std_logic;

    fmc1_prsnt_m2c_n_i : in std_logic;

    fmc1_scl_b : inout std_logic;
    fmc1_sda_b : inout std_logic);

end entity wrtd_ref_svec_tdc_x2;

architecture arch of wrtd_ref_svec_tdc_x2 is
  -- WRTD Node identification (WTN2)
  constant c_WRTD_NODE_ID : std_logic_vector(31 downto 0) := x"5754_4E03";

  -- Convention metadata base address
  constant c_METADATA_ADDR : t_wishbone_address := x"0000_4000";

  constant c_MT_CONFIG : t_mt_config :=
    (
      app_id                        => c_WRTD_NODE_ID,
      cpu_count                     => 1,
      cpu_config                    => (
        0                           => (
          memsize                   => 8192,
          hmq_config                => (
            slot_count              => 1,
            slot_config             => (
              0                     => (
                entries_bits        => 4,
                width_bits          => 7,
                header_bits         => 2,
                endpoint_id         => x"0000_0000",
                enable_config_space => FALSE),
              others                => c_DUMMY_MT_MQUEUE_SLOT)),
          rmq_config                => (
            slot_count              => 1,
            slot_config             => (
              0                     => (
                entries_bits        => 4,
                width_bits          => 7,
                header_bits         => 4,
                endpoint_id         => x"0000_0000",
                enable_config_space => TRUE),
              others                => c_DUMMY_MT_MQUEUE_SLOT))),
        others                      => (
          0, c_MT_DEFAULT_MQUEUE_CONFIG, c_MT_DEFAULT_MQUEUE_CONFIG)),
      shared_mem_size               => 256
      );

  -----------------------------------------------------------------------------
  -- Signals
  -----------------------------------------------------------------------------

  signal master_wb_out : t_wishbone_master_out;
  signal master_wb_in  : t_wishbone_master_in;

  signal metadata_wb_out : t_wishbone_slave_out;
  signal metadata_wb_in  : t_wishbone_slave_in;
  signal tdc0_wb_out : t_wishbone_slave_out;
  signal tdc0_wb_in  : t_wishbone_slave_in;
  signal tdc1_wb_out : t_wishbone_slave_out;
  signal tdc1_wb_in  : t_wishbone_slave_in;
  signal mt_wb_out : t_wishbone_slave_out;
  signal mt_wb_in  : t_wishbone_slave_in;

  -- clock and reset
  signal areset_n         : std_logic;
  signal clk_sys_62m5     : std_logic;
  signal rst_sys_62m5_n   : std_logic;
  signal clk_ref_125m     : std_logic;
  signal clk_ext_ref      : std_logic;
  signal tdc0_clk_125m     : std_logic;
  signal tdc1_clk_125m     : std_logic;

  attribute keep                   : string;
  attribute keep of tdc0_clk_125m   : signal is "TRUE";
  attribute keep of tdc1_clk_125m   : signal is "TRUE";

  -- VME
  signal vme_access_led    : std_logic;

  -- LEDs and GPIO
  signal pps         : std_logic;
  signal pps_led     : std_logic;
  signal pps_ext_in  : std_logic;
  signal svec_led    : std_logic_vector(15 downto 0);
  signal wr_led_link : std_logic;
  signal wr_led_act  : std_logic;

  -- Interrupts
  signal irq_vector : std_logic_vector(5 downto 0);

  --  MT endpoints
  signal rmq_endpoint_out : t_mt_rmq_endpoint_iface_out;
  signal rmq_endpoint_in  : t_mt_rmq_endpoint_iface_in;
  signal rmq_src_in       : t_mt_stream_source_in;
  signal rmq_src_out      : t_mt_stream_source_out;
  signal rmq_src_cfg_in   : t_mt_stream_config_in;
  signal rmq_src_cfg_out  : t_mt_stream_config_out;
  signal rmq_snk_in       : t_mt_stream_sink_in;
  signal rmq_snk_out      : t_mt_stream_sink_out;
  signal rmq_snk_cfg_in   : t_mt_stream_config_in;
  signal rmq_snk_cfg_out  : t_mt_stream_config_out;

  --  MT fabric.
  signal eth_tx_out : t_wrf_source_out;
  signal eth_tx_in  : t_wrf_source_in;
  signal eth_rx_out : t_wrf_sink_out;
  signal eth_rx_in  : t_wrf_sink_in;

  -- MT Dedicated WB interfaces to FMCs
  signal fmc_dp_wb_out : t_wishbone_master_out;
  signal fmc_dp_wb_in  : t_wishbone_master_in;

  signal tdc0_dp_wb_out : t_wishbone_slave_out;
  signal tdc0_dp_wb_in  : t_wishbone_slave_in;
  signal tdc1_dp_wb_out : t_wishbone_slave_out;
  signal tdc1_dp_wb_in  : t_wishbone_slave_in;

  -- WRPC TM interface and aux clocks
  signal tm_link_up         : std_logic;
  signal tm_tai             : std_logic_vector(39 downto 0);
  signal tm_cycles          : std_logic_vector(27 downto 0);
  signal tm_time_valid      : std_logic;
  signal tm_clk_aux_lock_en : std_logic_vector(1 downto 0);
  signal tm_clk_aux_locked  : std_logic_vector(1 downto 0);
  signal tm_dac_value       : std_logic_vector(23 downto 0);
  signal tm_dac_wr          : std_logic_vector(1 downto 0);

  -- MT TM interface
  signal tm : t_mt_timing_if;

  attribute iob        : string;
  attribute iob of pps : signal is "FORCE";

begin  -- architecture arch

  areset_n <= vme_sysreset_n_i and rst_n_i;

  cmp_xwb_metadata : entity work.xwb_metadata
    generic map (
      g_VENDOR_ID    => x"0000_10DC",
      g_DEVICE_ID    => c_WRTD_NODE_ID,
      g_VERSION      => x"0100_0001",
      g_CAPABILITIES => x"0000_0000",
      g_COMMIT_ID    => (others => '0'))
    port map (
      clk_i   => clk_sys_62m5,
      rst_n_i => rst_sys_62m5_n,
      wb_i    => metadata_wb_in,
      wb_o    => metadata_wb_out);

  inst_svec_base : entity work.svec_base_wr
    generic map (
      g_WITH_VIC           => TRUE,
      g_WITH_ONEWIRE       => FALSE,
      g_WITH_SPI           => FALSE,
      g_WITH_WR            => TRUE,
      g_WITH_DDR4          => FALSE,
      g_WITH_DDR5          => FALSE,
      g_APP_OFFSET         => c_METADATA_ADDR,
      g_NUM_USER_IRQ       => 6,
      g_DPRAM_INITF        => g_WRPC_INITF,
      g_AUX_CLKS           => 2,
      g_FABRIC_IFACE       => plain,
      g_SIMULATION         => g_SIMULATION,
      g_VERBOSE            => FALSE)
    port map (
      rst_n_i              => areset_n,
      clk_125m_pllref_p_i  => clk_125m_pllref_p_i,
      clk_125m_pllref_n_i  => clk_125m_pllref_n_i,
      clk_20m_vcxo_i       => clk_20m_vcxo_i,
      clk_125m_gtp_n_i     => clk_125m_gtp_n_i,
      clk_125m_gtp_p_i     => clk_125m_gtp_p_i,
      clk_aux_i(0)         => tdc0_clk_125m,
      clk_aux_i(1)         => tdc1_clk_125m,
      clk_10m_ext_i        => clk_ext_ref,
      pps_ext_i            => pps_ext_in,
      vme_write_n_i        => vme_write_n_i,
      vme_sysreset_n_i     => vme_sysreset_n_i,
      vme_retry_oe_o       => vme_retry_oe_o,
      vme_retry_n_o        => vme_retry_n_o,
      vme_lword_n_b        => vme_lword_n_b,
      vme_iackout_n_o      => vme_iackout_n_o,
      vme_iackin_n_i       => vme_iackin_n_i,
      vme_iack_n_i         => vme_iack_n_i,
      vme_gap_i            => vme_gap_i,
      vme_dtack_oe_o       => vme_dtack_oe_o,
      vme_dtack_n_o        => vme_dtack_n_o,
      vme_ds_n_i           => vme_ds_n_i,
      vme_data_oe_n_o      => vme_data_oe_n_o,
      vme_data_dir_o       => vme_data_dir_o,
      vme_berr_o           => vme_berr_o,
      vme_as_n_i           => vme_as_n_i,
      vme_addr_oe_n_o      => vme_addr_oe_n_o,
      vme_addr_dir_o       => vme_addr_dir_o,
      vme_irq_o            => vme_irq_o,
      vme_ga_i             => vme_ga_i,
      vme_data_b           => vme_data_b,
      vme_am_i             => vme_am_i,
      vme_addr_b           => vme_addr_b,
      fmc0_scl_b           => fmc0_scl_b,
      fmc0_sda_b           => fmc0_sda_b,
      fmc1_scl_b           => fmc1_scl_b,
      fmc1_sda_b           => fmc1_sda_b,
      fmc0_prsnt_m2c_n_i   => fmc0_prsnt_m2c_n_i,
      fmc1_prsnt_m2c_n_i   => fmc1_prsnt_m2c_n_i,
      onewire_b            => onewire_b,
      carrier_scl_b        => carrier_scl_b,
      carrier_sda_b        => carrier_sda_b,
      spi_sclk_o           => spi_sclk_o,
      spi_ncs_o            => spi_ncs_o,
      spi_mosi_o           => spi_mosi_o,
      spi_miso_i           => spi_miso_i,
      uart_rxd_i           => uart_rxd_i,
      uart_txd_o           => uart_txd_o,
      plldac_sclk_o        => pll20dac_sclk_o,
      plldac_din_o         => pll20dac_din_o,
      pll20dac_din_o       => pll20dac_din_o,
      pll20dac_sclk_o      => pll20dac_sclk_o,
      pll20dac_sync_n_o    => pll20dac_sync_n_o,
      pll25dac_din_o       => pll25dac_din_o,
      pll25dac_sclk_o      => pll25dac_sclk_o,
      pll25dac_sync_n_o    => pll25dac_sync_n_o,
      sfp_txp_o            => sfp_txp_o,
      sfp_txn_o            => sfp_txn_o,
      sfp_rxp_i            => sfp_rxp_i,
      sfp_rxn_i            => sfp_rxn_i,
      sfp_mod_def0_i       => sfp_mod_def0_i,
      sfp_mod_def1_b       => sfp_mod_def1_b,
      sfp_mod_def2_b       => sfp_mod_def2_b,
      sfp_rate_select_o    => sfp_rate_select_o,
      sfp_tx_fault_i       => sfp_tx_fault_i,
      sfp_tx_disable_o     => sfp_tx_disable_o,
      sfp_los_i            => sfp_los_i,
      pcbrev_i             => pcbrev_i,
      clk_sys_62m5_o       => clk_sys_62m5,
      rst_sys_62m5_n_o     => rst_sys_62m5_n,
      clk_ref_125m_o       => clk_ref_125m,
      rst_ref_125m_n_o     => open,
      irq_user_i           => irq_vector,
      wrf_src_o            => eth_rx_in,
      wrf_src_i            => eth_rx_out,
      wrf_snk_o            => eth_tx_in,
      wrf_snk_i            => eth_tx_out,
      tm_link_up_o         => tm_link_up,
      tm_time_valid_o      => tm_time_valid,
      tm_tai_o             => tm_tai,
      tm_cycles_o          => tm_cycles,
      tm_dac_value_o       => tm_dac_value,
      tm_dac_wr_o          => tm_dac_wr,
      tm_clk_aux_lock_en_i => tm_clk_aux_lock_en,
      tm_clk_aux_locked_o  => tm_clk_aux_locked,
      pps_p_o              => pps,
      pps_led_o            => pps_led,
      link_ok_o            => open,
      led_link_o           => wr_led_link,
      led_act_o            => wr_led_act,
      app_wb_o             => master_wb_out,
      app_wb_i             => master_wb_in);

  -----------------------------------------------------------------------------
  -- Primary wishbone Crossbar
  -----------------------------------------------------------------------------

  inst_host_memmap: entity work.wrtd_tdc_x2_host_map
    port map (
      rst_n_i => rst_sys_62m5_n,
      clk_i => clk_sys_62m5,
      wb_i => master_wb_out,
      wb_o => master_wb_in,
      metadata_i => metadata_wb_out,
      metadata_o => metadata_wb_in,
      tdc0_i => tdc0_wb_out,
      tdc0_o => tdc0_wb_in,
      tdc1_i => tdc1_wb_out,
      tdc1_o => tdc1_wb_in,
      mt_i => mt_wb_out,
      mt_o => mt_wb_in);

  cmp_vme_led_extend : gc_extend_pulse
    generic map (
      g_width => 5000000)
    port map (
      clk_i      => clk_sys_62m5,
      rst_n_i    => rst_sys_62m5_n,
      pulse_i    => master_wb_out.cyc,
      extended_o => vme_access_led);

  -----------------------------------------------------------------------------
  -- Mock Turtle (WB Slave)
  -----------------------------------------------------------------------------

  inst_mock_turtle : entity work.mock_turtle_core
    generic map (
      g_CONFIG            => c_MT_CONFIG,
      g_CPU0_IRAM_INITF   => g_MT_CPU0_INITF,
      g_WITH_WHITE_RABBIT => TRUE)
    port map (
      clk_i          => clk_sys_62m5,
      rst_n_i        => rst_sys_62m5_n,
      sp_master_o    => open,
      sp_master_i    => c_DUMMY_WB_MASTER_IN,
      dp_master_o(0) => fmc_dp_wb_out,
      dp_master_i(0) => fmc_dp_wb_in,
      rmq_endpoint_o => rmq_endpoint_out,
      rmq_endpoint_i => rmq_endpoint_in,
      host_slave_i   => mt_wb_in,
      host_slave_o   => mt_wb_out,
      clk_ref_i      => clk_ref_125m,
      tm_i           => tm,
      hmq_in_irq_o   => irq_vector(2),
      hmq_out_irq_o  => irq_vector(3),
      notify_irq_o   => irq_vector(5),
      console_irq_o  => irq_vector(4));

  tm.cycles                 <= tm_cycles;
  tm.tai                    <= tm_tai;
  tm.time_valid             <= tm_time_valid;
  tm.link_up                <= tm_link_up;
  tm.aux_locked(1 downto 0) <= tm_clk_aux_locked;
  tm.aux_locked(7 downto 2) <= (others => '0');

  cmp_eth_endpoint : entity work.mt_ep_ethernet_single
    port map (
      clk_i            => clk_sys_62m5,
      rst_n_i          => rst_sys_62m5_n,
      rmq_src_i        => rmq_src_in,
      rmq_src_o        => rmq_src_out,
      rmq_src_config_i => rmq_snk_cfg_out,
      rmq_src_config_o => rmq_snk_cfg_in,
      rmq_snk_i        => rmq_snk_in,
      rmq_snk_o        => rmq_snk_out,
      rmq_snk_config_i => rmq_src_cfg_out,
      rmq_snk_config_o => rmq_src_cfg_in,
      eth_src_o        => eth_tx_out,
      eth_src_i        => eth_tx_in,
      eth_snk_o        => eth_rx_out,
      eth_snk_i        => eth_rx_in);

  p_rmq_assign : process (rmq_endpoint_out, rmq_snk_cfg_in, rmq_snk_out,
                          rmq_src_cfg_in, rmq_src_out) is
  begin

    rmq_endpoint_in <= c_MT_RMQ_ENDPOINT_IFACE_IN_DEFAULT_VALUE;

    -- WR->MT (RX, to MT CPU1)
    rmq_src_in                          <= rmq_endpoint_out.snk_out(1)(0);
    rmq_endpoint_in.snk_in(1)(0)        <= rmq_src_out;
    rmq_snk_cfg_out                     <= rmq_endpoint_out.snk_config_out(1)(0);
    rmq_endpoint_in.snk_config_in(1)(0) <= rmq_snk_cfg_in;

    -- MT->WR (TX, from MT CPU0)
    rmq_snk_in                          <= rmq_endpoint_out.src_out(0)(0);
    rmq_endpoint_in.src_in(0)(0)        <= rmq_snk_out;
    rmq_src_cfg_out                     <= rmq_endpoint_out.src_config_out(0)(0);
    rmq_endpoint_in.src_config_in(0)(0) <= rmq_src_cfg_in;

  end process p_rmq_assign;

  my_inst: entity work.wrtd_tdc_x2_fmc_map
    port map (
      rst_n_i => rst_sys_62m5_n,
      clk_i => clk_sys_62m5,
      wb_i => fmc_dp_wb_out,
      wb_o => fmc_dp_wb_in,
      tdc0_i => tdc0_dp_wb_out,
      tdc0_o => tdc0_dp_wb_in,
      tdc1_i => tdc1_dp_wb_out,
      tdc1_o => tdc1_dp_wb_in
    );
  -----------------------------------------------------------------------------
  -- FMC TDC (SVEC slot #1)
  -----------------------------------------------------------------------------

  U_TDC_Core0 : entity work.fmc_tdc_wrapper
    generic map (
      g_SIMULATION          => f_int2bool(g_SIMULATION),
      g_PULSE_WIDTH_FILTER  => FALSE,
      g_USE_FIFO_READOUT    => FALSE,
      g_USE_DMA_READOUT     => FALSE,
      g_WITH_DIRECT_READOUT => TRUE)
    port map (
      clk_sys_i            => clk_sys_62m5,
      rst_sys_n_i          => rst_sys_62m5_n,
      rst_n_a_i            => rst_sys_62m5_n,
      fmc_id_i             => '0',
      fmc_present_n_i      => fmc0_prsnt_m2c_n_i,
      pll_sclk_o           => fmc0_tdc_pll_sclk_o,
      pll_sdi_o            => fmc0_tdc_pll_sdi_o,
      pll_cs_o             => fmc0_tdc_pll_cs_n_o,
      pll_dac_sync_o       => fmc0_tdc_pll_dac_sync_o,
      pll_sdo_i            => fmc0_tdc_pll_sdo_i,
      pll_status_i         => fmc0_tdc_pll_status_i,
      tdc_clk_125m_p_i     => fmc0_tdc_clk_125m_p_i,
      tdc_clk_125m_n_i     => fmc0_tdc_clk_125m_n_i,
      acam_refclk_p_i      => fmc0_tdc_acam_refclk_p_i,
      acam_refclk_n_i      => fmc0_tdc_acam_refclk_n_i,
      start_from_fpga_o    => fmc0_tdc_start_from_fpga_o,
      err_flag_i           => fmc0_tdc_err_flag_i,
      int_flag_i           => fmc0_tdc_int_flag_i,
      start_dis_o          => fmc0_tdc_start_dis_o,
      stop_dis_o           => fmc0_tdc_stop_dis_o,
      data_bus_io          => fmc0_tdc_data_bus_io,
      address_o            => fmc0_tdc_address_o,
      cs_n_o               => fmc0_tdc_cs_n_o,
      oe_n_o               => fmc0_tdc_oe_n_o,
      rd_n_o               => fmc0_tdc_rd_n_o,
      wr_n_o               => fmc0_tdc_wr_n_o,
      ef1_i                => fmc0_tdc_ef1_i,
      ef2_i                => fmc0_tdc_ef2_i,
      enable_inputs_o      => fmc0_tdc_enable_inputs_o,
      term_en_1_o          => fmc0_tdc_term_en_1_o,
      term_en_2_o          => fmc0_tdc_term_en_2_o,
      term_en_3_o          => fmc0_tdc_term_en_3_o,
      term_en_4_o          => fmc0_tdc_term_en_4_o,
      term_en_5_o          => fmc0_tdc_term_en_5_o,
      tdc_led_stat_o       => fmc0_tdc_led_status_o,
      tdc_led_trig_o(0)    => fmc0_tdc_led_trig1_o,
      tdc_led_trig_o(1)    => fmc0_tdc_led_trig2_o,
      tdc_led_trig_o(2)    => fmc0_tdc_led_trig3_o,
      tdc_led_trig_o(3)    => fmc0_tdc_led_trig4_o,
      tdc_led_trig_o(4)    => fmc0_tdc_led_trig5_o,
      mezz_scl_i           => '0',
      mezz_sda_i           => '0',
      mezz_scl_o           => open,
      mezz_sda_o           => open,
      mezz_one_wire_b      => fmc0_onewire_b,
      tm_link_up_i         => tm_link_up,
      tm_time_valid_i      => tm_time_valid,
      tm_cycles_i          => tm_cycles,
      tm_tai_i             => tm_tai,
      tm_clk_aux_lock_en_o => tm_clk_aux_lock_en(0),
      tm_clk_aux_locked_i  => tm_clk_aux_locked(0),
      tm_clk_dmtd_locked_i => '1',
      tm_dac_value_i       => tm_dac_value,
      tm_dac_wr_i          => tm_dac_wr(0),
      direct_slave_i       => tdc0_dp_wb_in,
      direct_slave_o       => tdc0_dp_wb_out,
      slave_i              => tdc0_wb_in,
      slave_o              => tdc0_wb_out,
      irq_o                => irq_vector(0),
      clk_125m_tdc_o       => tdc0_clk_125m);

  -----------------------------------------------------------------------------
  -- FMC TDC (SVEC slot #2)
  -----------------------------------------------------------------------------

  U_TDC_Core1 : entity work.fmc_tdc_wrapper
    generic map (
      g_SIMULATION          => f_int2bool(g_SIMULATION),
      g_PULSE_WIDTH_FILTER  => FALSE,
      g_USE_FIFO_READOUT    => FALSE,
      g_USE_DMA_READOUT     => FALSE,
      g_WITH_DIRECT_READOUT => TRUE)
    port map (
      clk_sys_i            => clk_sys_62m5,
      rst_sys_n_i          => rst_sys_62m5_n,
      rst_n_a_i            => rst_sys_62m5_n,
      fmc_id_i             => '1',
      fmc_present_n_i      => fmc1_prsnt_m2c_n_i,
      pll_sclk_o           => fmc1_tdc_pll_sclk_o,
      pll_sdi_o            => fmc1_tdc_pll_sdi_o,
      pll_cs_o             => fmc1_tdc_pll_cs_n_o,
      pll_dac_sync_o       => fmc1_tdc_pll_dac_sync_o,
      pll_sdo_i            => fmc1_tdc_pll_sdo_i,
      pll_status_i         => fmc1_tdc_pll_status_i,
      tdc_clk_125m_p_i     => fmc1_tdc_clk_125m_p_i,
      tdc_clk_125m_n_i     => fmc1_tdc_clk_125m_n_i,
      acam_refclk_p_i      => fmc1_tdc_acam_refclk_p_i,
      acam_refclk_n_i      => fmc1_tdc_acam_refclk_n_i,
      start_from_fpga_o    => fmc1_tdc_start_from_fpga_o,
      err_flag_i           => fmc1_tdc_err_flag_i,
      int_flag_i           => fmc1_tdc_int_flag_i,
      start_dis_o          => fmc1_tdc_start_dis_o,
      stop_dis_o           => fmc1_tdc_stop_dis_o,
      data_bus_io          => fmc1_tdc_data_bus_io,
      address_o            => fmc1_tdc_address_o,
      cs_n_o               => fmc1_tdc_cs_n_o,
      oe_n_o               => fmc1_tdc_oe_n_o,
      rd_n_o               => fmc1_tdc_rd_n_o,
      wr_n_o               => fmc1_tdc_wr_n_o,
      ef1_i                => fmc1_tdc_ef1_i,
      ef2_i                => fmc1_tdc_ef2_i,
      enable_inputs_o      => fmc1_tdc_enable_inputs_o,
      term_en_1_o          => fmc1_tdc_term_en_1_o,
      term_en_2_o          => fmc1_tdc_term_en_2_o,
      term_en_3_o          => fmc1_tdc_term_en_3_o,
      term_en_4_o          => fmc1_tdc_term_en_4_o,
      term_en_5_o          => fmc1_tdc_term_en_5_o,
      tdc_led_stat_o       => fmc1_tdc_led_status_o,
      tdc_led_trig_o(0)    => fmc1_tdc_led_trig1_o,
      tdc_led_trig_o(1)    => fmc1_tdc_led_trig2_o,
      tdc_led_trig_o(2)    => fmc1_tdc_led_trig3_o,
      tdc_led_trig_o(3)    => fmc1_tdc_led_trig4_o,
      tdc_led_trig_o(4)    => fmc1_tdc_led_trig5_o,
      mezz_scl_i           => '0',
      mezz_sda_i           => '0',
      mezz_scl_o           => open,
      mezz_sda_o           => open,
      mezz_one_wire_b      => fmc1_onewire_b,
      tm_link_up_i         => tm_link_up,
      tm_time_valid_i      => tm_time_valid,
      tm_cycles_i          => tm_cycles,
      tm_tai_i             => tm_tai,
      tm_clk_aux_lock_en_o => tm_clk_aux_lock_en(1),
      tm_clk_aux_locked_i  => tm_clk_aux_locked(1),
      tm_clk_dmtd_locked_i => '1',
      tm_dac_value_i       => tm_dac_value,
      tm_dac_wr_i          => tm_dac_wr(1),
      direct_slave_i       => tdc1_dp_wb_in,
      direct_slave_o       => tdc1_dp_wb_out,
      slave_i              => tdc1_wb_in,
      slave_o              => tdc1_wb_out,
      irq_o                => irq_vector(1),
      clk_125m_tdc_o       => tdc1_clk_125m);

  -----------------------------------------------------------------------------
  -- Carrier front panel LEDs and LEMOs
  -----------------------------------------------------------------------------

  cmp_led_controller : gc_bicolor_led_ctrl
    generic map(
      g_NB_COLUMN    => 4,
      g_NB_LINE      => 2,
      g_CLK_FREQ     => 62500000,  -- in Hz
      g_REFRESH_RATE => 250        -- in Hz
      )
    port map(
      rst_n_i => rst_sys_62m5_n,
      clk_i   => clk_sys_62m5,

      led_intensity_i => "1100100",  -- in %

      led_state_i => svec_led,

      column_o   => fp_led_column_o,
      line_o     => fp_led_line_o,
      line_oen_o => fp_led_line_oen_o);

  -- LED 4
  svec_led(1 downto 0)   <= c_LED_GREEN     when wr_led_link = '1'          else c_LED_RED;
  -- LED 3
  svec_led(3 downto 2)   <= c_LED_GREEN     when tm_clk_aux_locked(1) = '1' else c_LED_RED;
  -- LED 2
  svec_led(5 downto 4)   <= c_LED_GREEN     when tm_time_valid = '1'        else c_LED_RED;
  -- LED 1
  svec_led(7 downto 6)   <= c_LED_RED_GREEN when vme_access_led = '1'       else c_LED_OFF;
  -- LED 8
  svec_led(9 downto 8)   <= c_LED_RED_GREEN when wr_led_act = '1'           else c_LED_OFF;
  -- LED 7
  svec_led(11 downto 10) <= c_LED_GREEN     when tm_clk_aux_locked(0) = '1' else c_LED_RED;
  -- LED 6
  svec_led(13 downto 12) <= c_LED_OFF;
  -- LED 5
  svec_led(15 downto 14) <= c_LED_GREEN     when pps_led = '1'              else c_LED_OFF;

  -- Front panel IO configuration
  fp_gpio1_b      <= pps;
  fp_gpio2_b      <= '0';
  clk_ext_ref     <= fp_gpio3_b;
  pps_ext_in      <= fp_gpio4_b;
  fp_term_en_o    <= (others => '0');
  fp_gpio1_a2b_o  <= '1';
  fp_gpio2_a2b_o  <= '1';
  fp_gpio34_a2b_o <= '0';

end architecture arch;
