-------------------------------------------------------------------------------
--
-- Project name: UDP_100G
--
-- (C) Copyright 2020 DFC Design, s.r.o., Brno, Czech Republic
-- Author: Jakub Hadamek (j.hadamek@dfcdesign.cz)
--
-------------------------------------------------------------------------------
-- This is top level of ADC data capture design using 100G Ethernet and PCIe
-------------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
library UNISIM;
use UNISIM.VComponents.all;

Library xpm;
use xpm.vcomponents.all;

entity top is
   Port (
      -- Free running clocks
      DDR4_0_CLK_P   : in  std_logic;
      DDR4_0_CLK_N   : in  std_logic;
      DDR4_1_CLK_P   : in  std_logic;
      DDR4_1_CLK_N   : in  std_logic;
      -- Clocks from synthesizer
      FPGA_CLKIN0_P  : in  std_logic;
      FPGA_CLKIN0_N  : in  std_logic;
      -- QSFP0 Ports
      QSFP0_REFCLK_P : in  std_logic;
      QSFP0_REFCLK_N : in  std_logic;
      QSFP0_TX_P     : out std_logic_vector(3 downto 0);
      QSFP0_TX_N     : out std_logic_vector(3 downto 0);
      QSFP0_RX_P     : in  std_logic_vector(3 downto 0);
      QSFP0_RX_N     : in  std_logic_vector(3 downto 0);
      -- QSFP1 Ports
      QSFP1_REFCLK_P : in  std_logic;
      QSFP1_REFCLK_N : in  std_logic;
      QSFP1_TX_P     : out std_logic_vector(3 downto 0);
      QSFP1_TX_N     : out std_logic_vector(3 downto 0);
      QSFP1_RX_P     : in  std_logic_vector(3 downto 0);
      QSFP1_RX_N     : in  std_logic_vector(3 downto 0);      
      -- IIC Ports
      FPGA_I2C_SDA   : inout std_logic;
      FPGA_I2C_SCL   : inout std_logic;
      -- LEDs
      GPIO_LEDS      : out std_logic_vector(3 downto 0);
      -- PCI express
      PCIE_CLK_P        : in std_logic;
      PCIE_CLK_N        : in std_logic;
--      PCIE_PRSNTN       : in std_logic;
      PCIE_PERSTN       : in std_logic;
      PCIE_RX_P         : in std_logic_vector(15 downto 0);
      PCIE_RX_N         : in std_logic_vector(15 downto 0);
      PCIE_TX_P         : out std_logic_vector(15 downto 0);
      PCIE_TX_N         : out std_logic_vector(15 downto 0);
      -- ADC and HMC      -- ADJ voltage selector
      FMC_VADJ_MUX               : out std_logic_vector(1 downto 0);
      FMC_VADJ_MUX_EN            : out std_logic;
      -- ADC reference clock
      FMC_ADC_REFCLK_P           : in  std_logic;
      FMC_ADC_REFCLK_N           : in  std_logic;
      -- HMC reset
      FMC_HMC_RESET              : out std_logic;
      FMC_HMC_SYNC               : out std_logic;
      -- HMC SPI
      FMC_HMC_SLEN               : out std_logic;
      FMC_HMC_SCLK               : out std_logic;
      FMC_HMC_SDATA              : inout std_logic;
      -- ADC SPI
      FCM_ADC_SPI_CSB            : out std_logic;
      FCM_ADC_SPI_SCLK           : out std_logic;
      FCM_ADC_SPI_SDIO           : inout std_logic;
      -- JESD204B lanes
      FMC_ADC_RX_P               : in  std_logic_vector(7 downto 0);
      FMC_ADC_RX_N               : in  std_logic_vector(7 downto 0);
      -- JESD204B SYNC
      FMC_ADC_SYNC_P             : out std_logic;
      FMC_ADC_SYNC_N             : out std_logic;
      -- gpios
      GPIO                       : out std_logic_vector(15 downto 0)
      
      );
end top;

architecture Behavioral of top is

   constant LC_LOW               : std_logic := '0';
   constant LC_HIGH              : std_logic := '1';
   constant LC_CNT_MAX           : std_logic_vector(31 downto 0) := (others => '1');

   signal ddr4_0_clk             : std_logic; 
   signal ddr4_1_clk             : std_logic; 
   signal clk_250m               : std_logic; 

   signal fpga_clk0_cnt          : std_logic_vector(LC_CNT_MAX'range);
  
   constant LC_PREAMBLE          : std_logic_vector(55 downto 0) := x"555555555555D5";

   signal fpga_clkin0            : std_logic := '0'; 
   signal fpga_i2c_sda_o         : std_logic := '0';
   signal fpga_i2c_sda_i         : std_logic := '0';
   signal fpga_i2c_sda_t         : std_logic := '0';
   signal fpga_i2c_scl_o         : std_logic := '0';
   signal fpga_i2c_scl_i         : std_logic := '0';
   signal fpga_i2c_scl_t         : std_logic := '0';
   
   signal core_clk_cnt           : std_logic_vector(LC_CNT_MAX'range) := (others => '0'); 

------------------------------------------------------------------------------------
--                               ADC signals                                
------------------------------------------------------------------------------------
   signal adc_clk                : std_logic;
   signal adc_reset              : std_logic;
   signal adc_resetn              : std_logic;
   signal adc_cnt                : std_logic_vector(19 downto 0);
   signal rdma_reset             : std_logic;
   constant LC_ADC_CNT_MAX       : std_logic_vector(adc_cnt'range) := (others => '1'); 

   signal s_axis_adc_tvalid      : std_logic;
   signal s_axis_adc_tready      : std_logic;
   signal s_axis_adc_tlast       : std_logic;
   signal s_axis_adc_tkeep       : std_logic_vector(63 downto 0);
   signal s_axis_adc_tdata       : std_logic_vector(511 downto 0);
   
   signal m_axis_adc_ch0_tvalid  : std_logic;
   signal m_axis_adc_ch0_tready  : std_logic;
   signal m_axis_adc_ch0_tlast   : std_logic;
   signal m_axis_adc_ch0_tkeep   : std_logic_vector(63 downto 0);
   signal m_axis_adc_ch0_tdata   : std_logic_vector(511 downto 0);
  
   signal m_axis_adc_ch1_tvalid  : std_logic;
   signal m_axis_adc_ch1_tready  : std_logic;
   signal m_axis_adc_ch1_tlast   : std_logic;
   signal m_axis_adc_ch1_tkeep   : std_logic_vector(63 downto 0);
   signal m_axis_adc_ch1_tdata   : std_logic_vector(511 downto 0);

------------------------------------------------------------------------------------
--                               RDMA app signals                                
------------------------------------------------------------------------------------
   signal rdma_clk               : std_logic;
   
   -- RDMA app 0
   signal rdma0_reset             : std_logic;
   signal rdma0_resetn            : std_logic;
   
   signal m_axis_udp0_tvalid      : std_logic;
   signal m_axis_udp0_tready      : std_logic;
   signal m_axis_udp0_tlast       : std_logic;
   signal m_axis_udp0_tkeep       : std_logic_vector(63 downto 0);
   signal m_axis_udp0_tdata       : std_logic_vector(511 downto 0);
   
   signal tx0_src_udp             : std_logic_vector(15 downto 0);    
   signal tx0_dst_udp             : std_logic_vector(15 downto 0);    
   signal tx0_dst_ip              : std_logic_vector(31 downto 0);    
   signal tx0_dst_mac             : std_logic_vector(47 downto 0);       

   -- RDMA app 1
   signal rdma1_reset             : std_logic;
   signal rdma1_resetn            : std_logic;
   
   signal m_axis_udp1_tvalid      : std_logic;
   signal m_axis_udp1_tready      : std_logic;
   signal m_axis_udp1_tlast       : std_logic;
   signal m_axis_udp1_tkeep       : std_logic_vector(63 downto 0);
   signal m_axis_udp1_tdata       : std_logic_vector(511 downto 0);
   
   signal tx1_src_udp             : std_logic_vector(15 downto 0);    
   signal tx1_dst_udp             : std_logic_vector(15 downto 0);    
   signal tx1_dst_ip              : std_logic_vector(31 downto 0);    
   signal tx1_dst_mac             : std_logic_vector(47 downto 0);       

------------------------------------------------------------------------------------
--                               100G UDP                                
------------------------------------------------------------------------------------

   constant LC_HOST_MASK         : std_logic_vector(31 downto 0) := x"FFFFFF00";
   
   -- UDP 0
   constant LC_HOST0_IP          : std_logic_vector(31 downto 0) := x"C0A888CD";
   signal udp0_clk               : std_logic;
   signal udp0_reset             : std_logic;
   signal udp0_resetn            : std_logic;
   
   signal host0_mac              : std_logic_vector(47 downto 0);
   signal host0_mac_cdc          : std_logic_vector(47 downto 0);
   
   signal s_axis_udp0_tvalid      : std_logic;
   signal s_axis_udp0_tready      : std_logic;
   signal s_axis_udp0_tlast       : std_logic;
   signal s_axis_udp0_tkeep       : std_logic_vector(63 downto 0);
   signal s_axis_udp0_tdata       : std_logic_vector(511 downto 0);

   signal rx0_dst_udp             : std_logic_vector(15 downto 0) := (others => '0');    
   signal rx0_src_udp             : std_logic_vector(15 downto 0) := (others => '0');    
   signal rx0_src_ip              : std_logic_vector(31 downto 0) := (others => '0');    
   signal rx0_src_mac             : std_logic_vector(47 downto 0) := (others => '0');    
   signal rx0_packet_length       : std_logic_vector(15 downto 0) := (others => '0');      
   
   -- UDP 1
   constant LC_HOST1_IP          : std_logic_vector(31 downto 0) := x"C0A887CD";
   signal udp1_clk               : std_logic;
   signal udp1_reset             : std_logic;
   signal udp1_resetn            : std_logic;
   signal host1_mac              : std_logic_vector(47 downto 0);
   signal host1_mac_cdc          : std_logic_vector(47 downto 0);
   
   
   signal s_axis_udp1_tvalid      : std_logic;
   signal s_axis_udp1_tready      : std_logic;
   signal s_axis_udp1_tlast       : std_logic;
   signal s_axis_udp1_tkeep       : std_logic_vector(63 downto 0);
   signal s_axis_udp1_tdata       : std_logic_vector(511 downto 0);

   signal rx1_dst_udp             : std_logic_vector(15 downto 0) := (others => '0');    
   signal rx1_src_udp             : std_logic_vector(15 downto 0) := (others => '0');    
   signal rx1_src_ip              : std_logic_vector(31 downto 0) := (others => '0');    
   signal rx1_src_mac             : std_logic_vector(47 downto 0) := (others => '0');    
   signal rx1_packet_length       : std_logic_vector(15 downto 0) := (others => '0');   
   
------------------------------------------------------------------------------------
--                               CMAC WRAPPER                                 
------------------------------------------------------------------------------------
   
   -- CMAC 0
   signal m_axis_tx0_tvalid    : std_logic := '0';                        
   signal m_axis_tx0_tready    : std_logic := '0';                         
   signal m_axis_tx0_tuser     : std_logic := '0';                        
   signal m_axis_tx0_tlast     : std_logic := '0';                        
   signal m_axis_tx0_tkeep     : std_logic_vector(63 downto 0) := (others => '0');    
   signal m_axis_tx0_tdata     : std_logic_vector(511 downto 0) := (others => '0');   
   signal s_axis_rx0_tvalid    : std_logic := '0';                         
   signal s_axis_rx0_tready    : std_logic := '0';                        
   signal s_axis_rx0_tuser     : std_logic := '0';                         
   signal s_axis_rx0_tlast     : std_logic := '0';                         
   signal s_axis_rx0_tkeep     : std_logic_vector(63 downto 0) := (others => '0');     
   signal s_axis_rx0_tdata     : std_logic_vector(511 downto 0) := (others => '0');    
   signal rx0_rfi              : std_logic := '0';
   signal rx0_enable           : std_logic := '0';                        
   signal tx0_enable           : std_logic := '0';                        
   signal tx0_send_rfi         : std_logic := '0';                        
   signal tx0_send_lfi         : std_logic := '0';                        
   signal tx0_send_idle        : std_logic := '0';                        
   signal tx0_preamble         : std_logic_vector(55 downto 0) := (others => '0');    
   signal gt0_powergood        : std_logic := '0';                         
   signal rx0_aligned          : std_logic := '0';                         
   signal tx0_overflow         : std_logic := '0';                         
   signal tx0_underflow        : std_logic := '0';                         
   signal usr_rx0_reset        : std_logic := '0';                         
   signal usr_tx0_reset        : std_logic := '0';                         
   signal cmac0_reset          : std_logic := '0';                        
   signal rx0_reset            : std_logic := '0';                        
   signal tx0_reset            : std_logic := '0';                        
 
   signal init0_done           : std_logic := '0';                        
   signal rx0_overflow         : std_logic := '0';                         
   signal cmac0_rst            : std_logic := '0';

   -- CMAC 1
   signal m_axis_tx1_tvalid    : std_logic := '0';                        
   signal m_axis_tx1_tready    : std_logic := '0';                         
   signal m_axis_tx1_tuser     : std_logic := '0';                        
   signal m_axis_tx1_tlast     : std_logic := '0';                        
   signal m_axis_tx1_tkeep     : std_logic_vector(63 downto 0) := (others => '0');    
   signal m_axis_tx1_tdata     : std_logic_vector(511 downto 0) := (others => '0');   
   signal s_axis_rx1_tvalid    : std_logic := '0';                         
   signal s_axis_rx1_tready    : std_logic := '0';                        
   signal s_axis_rx1_tuser     : std_logic := '0';                         
   signal s_axis_rx1_tlast     : std_logic := '0';                         
   signal s_axis_rx1_tkeep     : std_logic_vector(63 downto 0) := (others => '0');     
   signal s_axis_rx1_tdata     : std_logic_vector(511 downto 0) := (others => '0');    
   signal rx1_rfi              : std_logic := '0';
   signal rx1_enable           : std_logic := '0';                        
   signal tx1_enable           : std_logic := '0';                        
   signal tx1_send_rfi         : std_logic := '0';                        
   signal tx1_send_lfi         : std_logic := '0';                        
   signal tx1_send_idle        : std_logic := '0';                        
   signal tx1_preamble         : std_logic_vector(55 downto 0) := (others => '0');    
   signal gt1_powergood        : std_logic := '0';                         
   signal rx1_aligned          : std_logic := '0';                         
   signal tx1_overflow         : std_logic := '0';                         
   signal tx1_underflow        : std_logic := '0';                         
   signal usr_rx1_reset        : std_logic := '0';                         
   signal usr_tx1_reset        : std_logic := '0';                         
   signal cmac1_reset          : std_logic := '0';                        
   signal rx1_reset            : std_logic := '0';                        
   signal tx1_reset            : std_logic := '0';                        
 
   signal init1_done           : std_logic := '0';                        
   signal rx1_overflow         : std_logic := '0';                         
   signal cmac1_rst            : std_logic := '0';
   
------------------------------------------------------------------------------------
--                               PCIE                                
------------------------------------------------------------------------------------
   signal pcie_reset               : std_logic;
   signal pcie_clk                 : std_logic;
   signal pcie_data_rxn            : std_logic_vector ( 15 downto 0 );   
   signal pcie_data_rxp            : std_logic_vector ( 15 downto 0 );   
   signal pcie_data_txn            : std_logic_vector ( 15 downto 0 );  
   signal pcie_data_txp            : std_logic_vector ( 15 downto 0 );  
   signal pcie_linkup              : std_logic;                         
   signal pcie_ref_clk_clk_n       : std_logic_vector ( 0 to 0 );        
   signal pcie_ref_clk_clk_p       : std_logic_vector ( 0 to 0 );        
   signal s_axis_pcie_ch0_tdata    : std_logic_vector ( 511 downto 0 );  
   signal s_axis_pcie_ch0_tkeep    : std_logic_vector ( 63 downto 0 );   
   signal s_axis_pcie_ch0_tlast    : std_logic;                          
   signal s_axis_pcie_ch0_tready   : std_logic;                         
   signal s_axis_pcie_ch0_tvalid   : std_logic;                          
   signal s_axis_pcie_ch1_tdata    : std_logic_vector ( 511 downto 0 );  
   signal s_axis_pcie_ch1_tkeep    : std_logic_vector ( 63 downto 0 );   
   signal s_axis_pcie_ch1_tlast    : std_logic;                          
   signal s_axis_pcie_ch1_tready   : std_logic;                         
   signal s_axis_pcie_ch1_tvalid   : std_logic;   
   signal s_axis_pcie_ch2_tdata    : std_logic_vector ( 511 downto 0 );  
   signal s_axis_pcie_ch2_tkeep    : std_logic_vector ( 63 downto 0 );   
   signal s_axis_pcie_ch2_tlast    : std_logic;                          
   signal s_axis_pcie_ch2_tready   : std_logic;                         
   signal s_axis_pcie_ch2_tvalid   : std_logic;                          
   signal s_axis_pcie_ch3_tdata    : std_logic_vector ( 511 downto 0 );  
   signal s_axis_pcie_ch3_tkeep    : std_logic_vector ( 63 downto 0 );   
   signal s_axis_pcie_ch3_tlast    : std_logic;                          
   signal s_axis_pcie_ch3_tready   : std_logic;                         
   signal s_axis_pcie_ch3_tvalid   : std_logic;   
      
   signal clk_locked                   : std_logic;
   
   --- ADC and HMC
   signal axi_clk                      : std_logic;
   signal clk_300m                     : std_logic;
   signal clk_300m_cnt                 : std_logic_vector(LC_CNT_MAX'range);

   signal fcm_adc_spi_csb_i            : std_logic;   
   signal fcm_adc_spi_sclk_i           : std_logic;   
   signal fcm_adc_spi_sdi_i            : std_logic;   
   signal fcm_adc_spi_sdo_i            : std_logic;

   signal fmc_hmc_slen_i               : std_logic;
   signal fmc_hmc_sclk_i               : std_logic;
   signal fmc_hmc_sdata_i              : std_logic;
   
   signal jesd_refclk0                 : std_logic;
   signal jesd_core_clk_cnt            : std_logic_vector(LC_CNT_MAX'range);
   constant LC_JESD_CORE_CLK_CNT_MAX   : std_logic_vector(clk_300m_cnt'range) := (others => '1');
   
   signal jesd_core_clk          : std_logic := '0';
   signal axi_gpio               : std_logic_vector(31 downto 0);

   signal jesd_sync              : std_logic; 
   signal not_jesd_sync          : std_logic;                                 
   signal jesd_sysref            : std_logic;                                 
   signal m_axis_jesd_tdata      : std_logic_vector (255 downto 0);  
   signal m_axis_jesd_tvalid     : std_logic;                         
   
   signal udp_axi_reset          : std_logic;
     
   type std_logic_array is array (integer range <>) of std_logic_vector(15 downto 0);
   signal ch0_array              : std_logic_array(31 downto 0);
   signal ch1_array              : std_logic_array(31 downto 0);
begin
------------------------------------------------------------------------------------
--                      CLOCK BUFFERS                                  
------------------------------------------------------------------------------------


   ddr4_0_clk_buffer: IBUFGDS
      generic map(
         DIFF_TERM => FALSE,
         IBUF_LOW_PWR => FALSE,
         IOSTANDARD => "DEFAULT")
      port map(
         O  => clk_300m,
         I  => DDR4_0_CLK_P,
         IB => DDR4_0_CLK_N
         );

   ddr4_1_clk_buffer: IBUFGDS
      generic map(
         DIFF_TERM => FALSE,
         IBUF_LOW_PWR => FALSE,
         IOSTANDARD => "DEFAULT")
      port map(
         O  => ddr4_1_clk,
         I  => DDR4_1_CLK_P,
         IB => DDR4_1_CLK_N
         );
         
------------------------------------------------------------------------------------
--                      CLOCK SYTHESIZER                                  
------------------------------------------------------------------------------------   

FPGA_I2C_scl_iobuf: component IOBUF
     port map (
      I => fpga_i2c_scl_o,
      IO => FPGA_I2C_SCL,
      O => fpga_i2c_scl_i,
      T => fpga_i2c_scl_t
    );
FPGA_I2C_sda_iobuf: component IOBUF
     port map (
      I => fpga_i2c_sda_o,
      IO => FPGA_I2C_SDA,
      O => fpga_i2c_sda_i,
      T => fpga_i2c_sda_t
    );

    fpga_clkin0_ibufds_inst: IBUFGDS
    generic map(
      DIFF_TERM => FALSE,
      IBUF_LOW_PWR => FALSE,
      IOSTANDARD => "DEFAULT")
    port map(
      O  => fpga_clkin0,
      I  => FPGA_CLKIN0_P,
      IB => FPGA_CLKIN0_N
      );


------------------------------------------------------------------------------------
--                         HMC & ADC                                  
------------------------------------------------------------------------------------
      
   FMC_HMC_RESET <= axi_gpio(0);

   -- 1.8 V
   FMC_VADJ_MUX <= "11";
   FMC_VADJ_MUX_EN <= '1';
   
   FMC_HMC_SYNC <= '0';

   jesd_refclk_ibufds: IBUFDS_GTE4
   generic map(
      REFCLK_HROW_CK_SEL   => "00"
   )
   port map(
      O                    => jesd_refclk0,
      ODIV2                => open,
      CEB                  => '0',
      I                    => FMC_ADC_REFCLK_P,
      IB                   => FMC_ADC_REFCLK_N    
   );

   -- sync P and N switched - input has to be inverted
   OBUFDS_inst : OBUFDS
      generic map (
         IOSTANDARD => "DEFAULT", -- Specify the output I/O standard
         SLEW => "FAST") -- Specify the output slew rate
      port map (
         O  => FMC_ADC_SYNC_P,
         OB => FMC_ADC_SYNC_N,
         I  => not_jesd_sync -- Buffer input
      );

   not_jesd_sync <= not jesd_sync;
      
------------------------------------------------------------------------------------
--                         Counters nad LEDs                                  
------------------------------------------------------------------------------------
         
   clk_300m_cnt_proc: process(clk_300m) 
      begin
         if rising_edge(clk_300m) then
            if clk_300m_cnt < LC_CNT_MAX then 
               clk_300m_cnt <= std_logic_vector(unsigned(clk_300m_cnt) + 1);
            else
               clk_300m_cnt <= (others => '0');
            end if;
         end if;
      end process;
         
   fpga_clk0_cnt_proc: process(fpga_clkin0) 
      begin
         if rising_edge(fpga_clkin0) then
            if fpga_clk0_cnt < LC_CNT_MAX then 
               fpga_clk0_cnt <= std_logic_vector(unsigned(fpga_clk0_cnt) + 1);
            else
               fpga_clk0_cnt <= (others => '0');
            end if;
         end if;
      end process;

   udp0_clk_cnt_proc: process(udp0_clk)
      begin
         if rising_edge(udp0_clk) then 
            if core_clk_cnt < LC_CNT_MAX then 
               core_clk_cnt <= core_clk_cnt + 1;
            else
               core_clk_cnt <= (others => '0');
            end if;
         end if;
      end process;

   jesd_core_clk_cnt_proc: process(jesd_core_clk)
      begin
         if rising_edge(jesd_core_clk) then
            if jesd_core_clk_cnt < LC_CNT_MAX then
               jesd_core_clk_cnt <= jesd_core_clk_cnt + 1;
            else
               jesd_core_clk_cnt <= (others => '0');
            end if;
         end if;
      end process;
      
   -- Alive counter
   GPIO_LEDS(0) <= clk_300m_cnt(27);     
   -- Clock synthesiser alive counter
   GPIO_LEDS(1) <= core_clk_cnt(27); 
   -- UDP core alive counter
   GPIO_LEDS(2) <= jesd_core_clk_cnt(27);   
   -- JESD PHY alive counter
   GPIO_LEDS(3) <= pcie_linkup;


------------------------------------------------------------------------------------
--                         Block design                                  
------------------------------------------------------------------------------------

   main_bd_inst: entity work.main_bd
   port map(
      -- synthesizer
      IIC_FPGA_scl_i       => fpga_i2c_scl_i,
      IIC_FPGA_scl_o       => fpga_i2c_scl_o,
      IIC_FPGA_scl_t       => fpga_i2c_scl_t,
      IIC_FPGA_sda_i       => fpga_i2c_sda_i,
      IIC_FPGA_sda_o       => fpga_i2c_sda_o,
      IIC_FPGA_sda_t       => fpga_i2c_sda_t,
      MAIN_BD_RST          => '1',
      SYS_300M_CLK         => clk_300m,
      CLK_250M             => clk_250m,
      CLK_LOCKED           => clk_locked,
      MAC0_HIGH_tri_o      => host0_mac(host0_mac'left downto 16),
      MAC0_LOW_tri_o       => host0_mac(15 downto 0),
      MAC1_HIGH_tri_o      => host1_mac(host1_mac'left downto 16),
      MAC1_LOW_tri_o       => host1_mac(15 downto 0),
      -- HMC SPI
      HMC_CSB(0)           => FMC_HMC_SLEN,
      HMC_SCLK             => FMC_HMC_SCLK,
      HMC_SDIO             => FMC_HMC_SDATA,
      -- ADC SPI
      ADC_CSB(0)           => FCM_ADC_SPI_CSB,
      ADC_SCLK             => FCM_ADC_SPI_SCLK,
      ADC_SDIO             => FCM_ADC_SPI_SDIO,
      AXI_GPIO             => axi_gpio,
      -- JESD inputs
      JESD_RESETN          => axi_gpio(1),
      JESD_REFCLK          => jesd_refclk0,
      JESD_RXP             => FMC_ADC_RX_P,
      JESD_RXN             => FMC_ADC_RX_N,
      JESD_SYSREF          => '0',
      -- JESD outputs
      JESD_CORE_CLK(0)     => jesd_core_clk,
      JESD_SYNC            => jesd_sync,
      M_AXIS_JESD_TDATA    => m_axis_jesd_tdata,
      M_AXIS_JESD_TVALID   => m_axis_jesd_tvalid,
      -- PCI Express
      PCIE_DATA_rxp        => PCIE_RX_P,
      PCIE_DATA_rxn        => PCIE_RX_N,
      PCIE_DATA_txp        => PCIE_TX_P,
      PCIE_DATA_txn        => PCIE_TX_N,
      PCIE_REFCLK_clk_n(0) => PCIE_CLK_N,
      PCIE_REFCLK_clk_p(0) => PCIE_CLK_P,
      PCIE_LINKUP          => pcie_linkup,
      PCIE_PERSTN          => PCIE_PERSTN,
      
      PCIE_CLK                   => pcie_clk,
      PCIE_TRANSFORM_ADC_RESET(0) => pcie_reset,
      S_AXIS_CH0_TVALID          => s_axis_pcie_ch0_tvalid,                      
      S_AXIS_CH0_TREADY          => s_axis_pcie_ch0_tready,                      
      S_AXIS_CH0_TLAST           => s_axis_pcie_ch0_tlast,                       
      S_AXIS_CH0_TKEEP           => s_axis_pcie_ch0_tkeep,   
      S_AXIS_CH0_TDATA           => s_axis_pcie_ch0_tdata,
      S_AXIS_CH1_TVALID          => s_axis_pcie_ch1_tvalid,                      
      S_AXIS_CH1_TREADY          => s_axis_pcie_ch1_tready,                      
      S_AXIS_CH1_TLAST           => s_axis_pcie_ch1_tlast,                       
      S_AXIS_CH1_TKEEP           => s_axis_pcie_ch1_tkeep,   
      S_AXIS_CH1_TDATA           => s_axis_pcie_ch1_tdata
   );
  
   rdma_clk <= clk_250m;
  
                      
------------------------------------------------------------------------------------
--                               ILA INSTANCIES                                   
------------------------------------------------------------------------------------

--   rdma_tx_0_ila: entity work.axis_ila
--   port map (
--      clk         => rdma_clk,
--      probe0(0)   => m_axis_udp0_tvalid,
--      probe1      => m_axis_udp0_tdata, 
--      probe2      => m_axis_udp0_tkeep, 
--      probe3(0)   => m_axis_udp0_tready,
--      probe4(0)   => m_axis_udp0_tlast, 
--      probe5      => tx0_dst_mac,
--      probe6      => x"000000000000" & tx0_dst_udp,
--      probe7      => tx0_dst_ip,
--      probe8      => x"0000" & tx0_src_udp
--   );


--   rdma_rx_0_ila: entity work.axis_ila
--   port map (
--      clk         => rdma_clk,
--      probe0(0)   => s_axis_udp0_tvalid,
--      probe1      => s_axis_udp0_tdata, 
--      probe2      => s_axis_udp0_tkeep, 
--      probe3(0)   => s_axis_udp0_tready,
--      probe4(0)   => s_axis_udp0_tlast, 
--      probe5      => rx0_src_mac,
--      probe6      => x"000000000000" & rx0_dst_udp,
--      probe7      => rx0_src_ip,
--      probe8      => x"0000" & rx0_src_udp
--   );

--   udp_tx_0_ila: entity work.axis_ila
--   port map (
--      clk         => udp0_clk,
--      probe0(0)   => m_axis_tx0_tvalid,
--      probe1      => m_axis_tx0_tdata, 
--      probe2      => m_axis_tx0_tkeep, 
--      probe3(0)   => m_axis_tx0_tready,
--      probe4(0)   => m_axis_tx0_tlast, 
--      probe5      => x"000000000000",
--      probe6      => x"0000000000000000",
--      probe7      => x"00000000",
--      probe8      => x"00000000"
--   );

--   udp_rx_0_ila: entity work.axis_ila
--   port map (
--      clk         => udp0_clk,
--      probe0(0)   => s_axis_rx0_tvalid,
--      probe1      => s_axis_rx0_tdata, 
--      probe2      => s_axis_rx0_tkeep, 
--      probe3(0)   => s_axis_rx0_tready,
--      probe4(0)   => s_axis_rx0_tlast, 
--      probe5      => x"00000000000" & "000" & cmac0_reset,
--      probe6      => x"000000000000000" & "000" & tx0_send_rfi,
--      probe7      => x"0000000" & "000" & rx0_enable,
--      probe8      => x"0000000" & "000" & rx0_aligned
--   );

--   ch_0_ila: entity work.axis_ila
--   port map (
--      clk         => rdma_clk,
--      probe0(0)   => m_axis_adc_ch0_tvalid,
--      probe1      => m_axis_adc_ch0_tdata,
--      probe2      => m_axis_adc_ch0_tkeep, 
--      probe3(0)   => m_axis_adc_ch0_tready,
--      probe4(0)   => m_axis_adc_ch0_tlast, 
--      probe5      => x"00000000000" & "000" & init0_done, 
--      probe6      => x"000000000000000" & "000" & init1_done,
--      probe7      => x"0000000" & "000" & cmac0_rst,
--      probe8      => x"0000000" & "000" & cmac1_rst 
--   );
   
------------------------------------------------------------------------------------
--                               ADC data                                 
------------------------------------------------------------------------------------

   transform_adc_stream_pcie_inst: entity work.transform_adc_stream
     port map(
         -- Input clock and reset
         S_CLK                => jesd_core_clk,
         S_RESET              => '0',
         -- input stream
         S_AXIS_TVALID        => m_axis_jesd_tvalid,
         S_AXIS_TDATA         => m_axis_jesd_tdata,
         -- Output clock and reset
         M_CLK                => pcie_clk,
         M_RESET              => pcie_reset,
         -- output stream channel 0
         M_AXIS_CH0_TVALID    => s_axis_pcie_ch0_tvalid,
         M_AXIS_CH0_TREADY    => '1', --m_axis_adc_ch0_tready,
         M_AXIS_CH0_TDATA     => s_axis_pcie_ch0_tdata,
         -- output stream channel 1
         M_AXIS_CH1_TVALID    => s_axis_pcie_ch1_tvalid,
         M_AXIS_CH1_TREADY    => '1', --m_axis_adc_ch1_tready,
         M_AXIS_CH1_TDATA     => s_axis_pcie_ch1_tdata 
      );
             
   s_axis_pcie_ch0_tkeep <= (others => '1');
   s_axis_pcie_ch1_tkeep <= (others => '1');
   s_axis_pcie_ch0_tlast <= '0';
   s_axis_pcie_ch1_tlast <= '0';


   transform_adc_stream_eth_inst: entity work.transform_adc_stream
     port map(
         -- Input clock and reset
         S_CLK                => jesd_core_clk,
         S_RESET              => '0',
         -- input stream
         S_AXIS_TVALID        => m_axis_jesd_tvalid,
         S_AXIS_TDATA         => m_axis_jesd_tdata,
         -- Output clock and reset
         M_CLK                => rdma_clk,
         M_RESET              => rdma_reset,
         -- output stream channel 0
         M_AXIS_CH0_TVALID    => m_axis_adc_ch0_tvalid,
         M_AXIS_CH0_TREADY    => '1', --m_axis_adc_ch0_tready,
         M_AXIS_CH0_TDATA     => m_axis_adc_ch0_tdata,
         -- output stream channel 1
         M_AXIS_CH1_TVALID    => m_axis_adc_ch1_tvalid,
         M_AXIS_CH1_TREADY    => '1', --m_axis_adc_ch1_tready,
         M_AXIS_CH1_TDATA     => m_axis_adc_ch1_tdata 
      );
    
   rdma_reset <= rdma0_reset and rdma1_reset;
         
   m_axis_adc_ch0_tkeep <= (others => '1');
   m_axis_adc_ch1_tkeep <= (others => '1');
   m_axis_adc_ch0_tlast <= '0';
   m_axis_adc_ch1_tlast <= '0';

   array_loop: for i in 0 to 31 generate
      ch0_array(i) <= m_axis_adc_ch0_tdata((i+1)*16-1 downto i*16);
      ch1_array(i) <= m_axis_adc_ch1_tdata((i+1)*16-1 downto i*16);
   end generate;


--   transformed_data_ch0_ila: entity work.ila_0
--   port map(
--      clk         => rdma_clk,
--      probe0(0)   => m_axis_adc_ch0_tvalid,
--      probe1      => m_axis_adc_ch0_tdata,
--      probe2(0)   => m_axis_adc_ch0_tready,
--      probe3(0)   => m_axis_adc_ch1_tvalid,
--      probe4      => m_axis_adc_ch1_tdata,
--      probe5(0)   => m_axis_adc_ch1_tready
--   );

--   data_test_ila_part1: entity work.data_test_ila
--   port map(
--      clk         => rdma_clk,
--      probe0      => ch0_array(0 ),
--      probe1      => ch0_array(1 ),
--      probe2      => ch0_array(2 ),
--      probe3      => ch0_array(3 ),
--      probe4      => ch0_array(4 ),
--      probe5      => ch0_array(5 ),
--      probe6      => ch0_array(6 ),
--      probe7      => ch0_array(7 ),
--      probe8      => ch0_array(8 ),
--      probe9      => ch0_array(9 ),
--      probe10     => ch0_array(10),
--      probe11     => ch0_array(11),
--      probe12     => ch0_array(12),
--      probe13     => ch0_array(13),
--      probe14     => ch0_array(14),
--      probe15     => ch0_array(15),
--      probe16     => ch0_array(16),
--      probe17     => ch0_array(17),
--      probe18     => ch0_array(18),
--      probe19     => ch0_array(19),
--      probe20     => ch0_array(20),
--      probe21     => ch0_array(21),
--      probe22     => ch0_array(22),
--      probe23     => ch0_array(23),
--      probe24     => ch0_array(24),
--      probe25     => ch0_array(25),
--      probe26     => ch0_array(26),
--      probe27     => ch0_array(27),
--      probe28     => ch0_array(28),
--      probe29     => ch0_array(29),
--      probe30     => ch0_array(30),
--      probe31     => ch0_array(31),
--      probe32     => ch1_array(0 ),
--      probe33     => ch1_array(1 ),
--      probe34     => ch1_array(2 ),
--      probe35     => ch1_array(3 ),
--      probe36     => ch1_array(4 ),
--      probe37     => ch1_array(5 ),
--      probe38     => ch1_array(6 ),
--      probe39     => ch1_array(7 ),
--      probe40     => ch1_array(8 ),
--      probe41     => ch1_array(9 ),
--      probe42     => ch1_array(10),
--      probe43     => ch1_array(11),
--      probe44     => ch1_array(12),
--      probe45     => ch1_array(13),
--      probe46     => ch1_array(14),
--      probe47     => ch1_array(15),
--      probe48     => ch1_array(16),
--      probe49     => ch1_array(17),
--      probe50     => ch1_array(18),
--      probe51     => ch1_array(19),
--      probe52     => ch1_array(20),
--      probe53     => ch1_array(21),
--      probe54     => ch1_array(22),
--      probe55     => ch1_array(23),
--      probe56     => ch1_array(24),
--      probe57     => ch1_array(25),
--      probe58     => ch1_array(26),
--      probe59     => ch1_array(27),
--      probe60     => ch1_array(28),
--      probe61     => ch1_array(29),
--      probe62     => ch1_array(30),
--      probe63     => ch1_array(31)
--   );

------------------------------------------------------------------------------------
--                               RDMA application 0                            
------------------------------------------------------------------------------------

   host_mac0_rdma_clk_cdc: entity work.xcdc
   generic map(
      g_data_width   => 48
           )
   port map(
      RSTN           => '1',
      DCLK           => rdma_clk,
      DATA_IN        => host0_mac,
      DATA_OUT       => host0_mac_cdc
        );

   
   rdma_adc_app0_inst: entity work.rdma_adc_app_0
   port map(                   
      ETH_RESET         => rdma0_reset, 
      ETH_CLK           => rdma_clk,                     
      HOST_MAC          => host0_mac_cdc,   
      HOST_IP           => LC_HOST0_IP,   
      HOST_NET_MASK     => LC_HOST_MASK,   
      S_AXIS_UDP_TVALID => s_axis_udp0_tvalid,  
      S_AXIS_UDP_TREADY => s_axis_udp0_tready,  
      S_AXIS_UDP_TLAST  => s_axis_udp0_tlast,  
      S_AXIS_UDP_TKEEP  => s_axis_udp0_tkeep,  
      S_AXIS_UDP_TDATA  => s_axis_udp0_tdata,  
      RX_DST_UDP        => rx0_dst_udp,   
      RX_SRC_UDP        => rx0_src_udp,   
      RX_SRC_IP         => rx0_src_ip,   
      RX_SRC_MAC        => rx0_src_mac,   
      RX_PACKET_LENGTH  => rx0_packet_length,   
      M_AXIS_UDP_TVALID => m_axis_udp0_tvalid, 
      M_AXIS_UDP_TREADY => m_axis_udp0_tready, 
      M_AXIS_UDP_TLAST  => m_axis_udp0_tlast,  
      M_AXIS_UDP_TKEEP  => m_axis_udp0_tkeep,  
      M_AXIS_UDP_TDATA  => m_axis_udp0_tdata,  
      TX_SRC_UDP        => tx0_src_udp,  
      TX_DST_UDP        => tx0_dst_udp,  
      TX_DST_IP         => tx0_dst_ip,  
      TX_DST_MAC        => tx0_dst_mac,  
      PACKET_DIVIDED    => LC_LOW,
      ADC_RESET         => rdma0_reset, 
      ADC_CLK           => rdma_clk,
      S_AXIS_ADC_TVALID => m_axis_adc_ch0_tvalid,                      
      S_AXIS_ADC_TREADY => m_axis_adc_ch0_tready,                      
      S_AXIS_ADC_TLAST  => m_axis_adc_ch0_tlast,                       
      S_AXIS_ADC_TKEEP  => m_axis_adc_ch0_tkeep,   
      S_AXIS_ADC_TDATA  => m_axis_adc_ch0_tdata
   );

   rdma0_resetn <= not rdma0_reset;
   rdma0_reset <= not init0_done;


------------------------------------------------------------------------------------
--                               RDMA application 1                        
------------------------------------------------------------------------------------

   host_mac1_rdma_clk_cdc: entity work.xcdc
   generic map(
      g_data_width   => 48
           )
   port map(
      RSTN           => '1',
      DCLK           => rdma_clk,
      DATA_IN        => host1_mac,
      DATA_OUT       => host1_mac_cdc
        );

   
   rdma_adc_app1_inst: entity work.rdma_adc_app_0
   port map(                   
      ETH_RESET         => rdma1_reset, 
      ETH_CLK           => rdma_clk,                     
      HOST_MAC          => host1_mac_cdc,   
      HOST_IP           => LC_HOST1_IP,   
      HOST_NET_MASK     => LC_HOST_MASK,   
      S_AXIS_UDP_TVALID => s_axis_udp1_tvalid,  
      S_AXIS_UDP_TREADY => s_axis_udp1_tready,  
      S_AXIS_UDP_TLAST  => s_axis_udp1_tlast,  
      S_AXIS_UDP_TKEEP  => s_axis_udp1_tkeep,  
      S_AXIS_UDP_TDATA  => s_axis_udp1_tdata,  
      RX_DST_UDP        => rx1_dst_udp,   
      RX_SRC_UDP        => rx1_src_udp,   
      RX_SRC_IP         => rx1_src_ip,   
      RX_SRC_MAC        => rx1_src_mac,   
      RX_PACKET_LENGTH  => rx1_packet_length,   
      M_AXIS_UDP_TVALID => m_axis_udp1_tvalid, 
      M_AXIS_UDP_TREADY => m_axis_udp1_tready, 
      M_AXIS_UDP_TLAST  => m_axis_udp1_tlast,  
      M_AXIS_UDP_TKEEP  => m_axis_udp1_tkeep,  
      M_AXIS_UDP_TDATA  => m_axis_udp1_tdata,  
      TX_SRC_UDP        => tx1_src_udp,  
      TX_DST_UDP        => tx1_dst_udp,  
      TX_DST_IP         => tx1_dst_ip,  
      TX_DST_MAC        => tx1_dst_mac,  
      PACKET_DIVIDED    => LC_LOW,
      ADC_RESET         => rdma1_reset, 
      ADC_CLK           => rdma_clk,
      S_AXIS_ADC_TVALID => m_axis_adc_ch1_tvalid,                      
      S_AXIS_ADC_TREADY => m_axis_adc_ch1_tready,                      
      S_AXIS_ADC_TLAST  => m_axis_adc_ch1_tlast,                       
      S_AXIS_ADC_TKEEP  => m_axis_adc_ch1_tkeep,   
      S_AXIS_ADC_TDATA  => m_axis_adc_ch1_tdata   
   );

   rdma1_resetn <= not rdma1_reset;
   rdma1_reset <= not init1_done;

------------------------------------------------------------------------------------
--                               100g UDP/IP 0                                
------------------------------------------------------------------------------------
   
   udp_axi_rst_xcdc: entity work.xcdc_bit port map( '1', rdma_clk, axi_gpio(2), udp_axi_reset);
   
   udp0_reset <= udp_axi_reset or not clk_locked;
      
   udp_100g0_inst: entity work.udp_100g_0
   port map (
    RESET                  => udp0_reset,                     
    CLK                    => rdma_clk,                        
    CMAC_CLK               => udp0_clk,         
    -- AXI Stream towards CMAC              
    M_AXIS_TX_TVALID       => m_axis_tx0_tvalid,    
    M_AXIS_TX_TREADY       => m_axis_tx0_tready,    
    M_AXIS_TX_TUSER        => m_axis_tx0_tuser,     
    M_AXIS_TX_TLAST        => m_axis_tx0_tlast,     
    M_AXIS_TX_TKEEP        => m_axis_tx0_tkeep,     
    M_AXIS_TX_TDATA        => m_axis_tx0_tdata,         
    -- AXI Stream from CMAC              
    S_AXIS_RX_TVALID       => s_axis_rx0_tvalid,    
    S_AXIS_RX_TREADY       => s_axis_rx0_tready,    
    S_AXIS_RX_TUSER        => s_axis_rx0_tuser,     
    S_AXIS_RX_TLAST        => s_axis_rx0_tlast,     
    S_AXIS_RX_TKEEP        => s_axis_rx0_tkeep,     
    S_AXIS_RX_TDATA        => s_axis_rx0_tdata,     
    -- CMAC control
    CTL_RX_ENABLE          => rx0_enable,           
    CTL_TX_ENABLE          => tx0_enable,           
    CTL_TX_SEND_RFI        => tx0_send_rfi,         
    CTL_TX_SEND_LFI        => tx0_send_lfi,         
    CTL_TX_SEND_IDLE       => tx0_send_idle,        
    -- CMAC status      
    STAT_RX_ALIGNED        => rx0_aligned,       
    STAT_RX_REMOTE_FAULT   => rx0_rfi,         
    STAT_TX_OVERFLOW       => tx0_overflow,         
    STAT_TX_UNDERFLOW      => tx0_underflow,     
    -- CMAC user reset (output from CMAC to control logic)   
    USR_RX_RESET           => usr_rx0_reset,        
    USR_TX_RESET           => usr_tx0_reset,        
    -- CMAC reset (input to CMAC from control logic)
    CMAC_RESET             => cmac0_reset,          
    RX_RESET               => rx0_reset,            
    TX_RESET               => tx0_reset,        
    -- AXI Stream from user    
    S_AXIS_TX_TVALID       => m_axis_udp0_tvalid,    
    S_AXIS_TX_TREADY       => m_axis_udp0_tready,    
    S_AXIS_TX_TLAST        => m_axis_udp0_tlast,     
    S_AXIS_TX_TKEEP        => m_axis_udp0_tkeep,     
    S_AXIS_TX_TDATA        => m_axis_udp0_tdata,     
    -- AXI Stream to user
    M_AXIS_RX_TVALID       => s_axis_udp0_tvalid,    
    M_AXIS_RX_TREADY       => s_axis_udp0_tready,
    M_AXIS_RX_TLAST        => s_axis_udp0_tlast,     
    M_AXIS_RX_TKEEP        => s_axis_udp0_tkeep,     
    M_AXIS_RX_TDATA        => s_axis_udp0_tdata,  
    -- Host network informations
    HOST_MAC               => host0_mac_cdc,            
    HOST_IP                => LC_HOST0_IP,             
    HOST_NET_MASK          => LC_HOST_MASK,       
    -- Received packet network informations
    RX_DST_UDP             => rx0_dst_udp,          
    RX_SRC_UDP             => rx0_src_udp,          
    RX_SRC_IP              => rx0_src_ip,           
    RX_SRC_MAC             => rx0_src_mac,          
    RX_PACKET_LENGTH       => rx0_packet_length,    
    RX_OVERFLOW            => rx0_overflow,   
    -- Transmit packet network informations
    TX_SRC_UDP             => tx0_src_udp,          
    TX_DST_UDP             => tx0_dst_udp,          
    TX_DST_IP              => tx0_dst_ip,          
    TX_DST_MAC             => tx0_dst_mac,  
    -- Initialization done - ready to send and receive   
    PACKET_DIVIDED         => open,
    INIT_DONE              => init0_done 
  );

------------------------------------------------------------------------------------
--                               100g UDP/IP 1                                
------------------------------------------------------------------------------------

   udp1_reset <= udp_axi_reset or not clk_locked;
         
   udp_100g1_inst: entity work.udp_100g_0
   port map (
    RESET                  => udp1_reset,                     
    CLK                    => rdma_clk,                        
    CMAC_CLK               => udp1_clk,         
    -- AXI Stream towards CMAC              
    M_AXIS_TX_TVALID       => m_axis_tx1_tvalid,    
    M_AXIS_TX_TREADY       => m_axis_tx1_tready,    
    M_AXIS_TX_TUSER        => m_axis_tx1_tuser,     
    M_AXIS_TX_TLAST        => m_axis_tx1_tlast,     
    M_AXIS_TX_TKEEP        => m_axis_tx1_tkeep,     
    M_AXIS_TX_TDATA        => m_axis_tx1_tdata,         
    -- AXI Stream from CMAC              
    S_AXIS_RX_TVALID       => s_axis_rx1_tvalid,    
    S_AXIS_RX_TREADY       => s_axis_rx1_tready,    
    S_AXIS_RX_TUSER        => s_axis_rx1_tuser,     
    S_AXIS_RX_TLAST        => s_axis_rx1_tlast,     
    S_AXIS_RX_TKEEP        => s_axis_rx1_tkeep,     
    S_AXIS_RX_TDATA        => s_axis_rx1_tdata,     
    -- CMAC control
    CTL_RX_ENABLE          => rx1_enable,           
    CTL_TX_ENABLE          => tx1_enable,           
    CTL_TX_SEND_RFI        => tx1_send_rfi,         
    CTL_TX_SEND_LFI        => tx1_send_lfi,         
    CTL_TX_SEND_IDLE       => tx1_send_idle,        
    -- CMAC status      
    STAT_RX_ALIGNED        => rx1_aligned,       
    STAT_RX_REMOTE_FAULT   => rx1_rfi,         
    STAT_TX_OVERFLOW       => tx1_overflow,         
    STAT_TX_UNDERFLOW      => tx1_underflow,     
    -- CMAC user reset (output from CMAC to control logic)   
    USR_RX_RESET           => usr_rx1_reset,        
    USR_TX_RESET           => usr_tx1_reset,        
    -- CMAC reset (input to CMAC from control logic)
    CMAC_RESET             => cmac1_reset,          
    RX_RESET               => rx1_reset,            
    TX_RESET               => tx1_reset,        
    -- AXI Stream from user    
    S_AXIS_TX_TVALID       => m_axis_udp1_tvalid,    
    S_AXIS_TX_TREADY       => m_axis_udp1_tready,    
    S_AXIS_TX_TLAST        => m_axis_udp1_tlast,     
    S_AXIS_TX_TKEEP        => m_axis_udp1_tkeep,     
    S_AXIS_TX_TDATA        => m_axis_udp1_tdata,     
    -- AXI Stream to user
    M_AXIS_RX_TVALID       => s_axis_udp1_tvalid,    
    M_AXIS_RX_TREADY       => s_axis_udp1_tready,
    M_AXIS_RX_TLAST        => s_axis_udp1_tlast,     
    M_AXIS_RX_TKEEP        => s_axis_udp1_tkeep,     
    M_AXIS_RX_TDATA        => s_axis_udp1_tdata,  
    -- Host network informations
    HOST_MAC               => host1_mac_cdc,            
    HOST_IP                => LC_HOST1_IP,             
    HOST_NET_MASK          => LC_HOST_MASK,       
    -- Received packet network informations
    RX_DST_UDP             => rx1_dst_udp,          
    RX_SRC_UDP             => rx1_src_udp,          
    RX_SRC_IP              => rx1_src_ip,           
    RX_SRC_MAC             => rx1_src_mac,          
    RX_PACKET_LENGTH       => rx1_packet_length,    
    RX_OVERFLOW            => rx1_overflow,   
    -- Transmit packet network informations
    TX_SRC_UDP             => tx1_src_udp,          
    TX_DST_UDP             => tx1_dst_udp,          
    TX_DST_IP              => tx1_dst_ip,          
    TX_DST_MAC             => tx1_dst_mac,  
    -- Initialization done - ready to send and receive   
    PACKET_DIVIDED         => open,
    INIT_DONE              => init1_done 
  );

------------------------------------------------------------------------------------
--                               CMAC 0                               
------------------------------------------------------------------------------------

 cmac_usplus_0_inst: entity work.cmac_usplus_wrapper0
   generic map(
      g_data_width         => 512
   )
   port map( 
      RESET                => cmac0_reset,
      TX_RESET             => tx0_reset,
      RX_RESET             => rx0_reset,
      REF_CLK_P            => QSFP0_REFCLK_P,
      REF_CLK_N            => QSFP0_REFCLK_N,
      INIT_CLK             => clk_300m,
      CORE_CLK             => udp0_clk,
      -- MGTs
      RX_P                 => QSFP0_RX_P,
      RX_N                 => QSFP0_RX_N,
      TX_P                 => QSFP0_TX_P,
      TX_N                 => QSFP0_TX_N,
      -- Master axis
      M_AXIS_TREADY        => s_axis_rx0_tready,
      M_AXIS_TVALID        => s_axis_rx0_tvalid,
      M_AXIS_TDATA         => s_axis_rx0_tdata, 
      M_AXIS_TUSER         => s_axis_rx0_tuser, 
      M_AXIS_TKEEP         => s_axis_rx0_tkeep, 
      M_AXIS_TLAST         => s_axis_rx0_tlast, 
      -- Slave axis
      S_AXIS_TREADY        => m_axis_tx0_tready,
      S_AXIS_TVALID        => m_axis_tx0_tvalid,
      S_AXIS_TDATA         => m_axis_tx0_tdata, 
      S_AXIS_TUSER         => m_axis_tx0_tuser, 
      S_AXIS_TKEEP         => m_axis_tx0_tkeep, 
      S_AXIS_TLAST         => m_axis_tx0_tlast, 
      -- RX control signals
      RX_ENABLE            => rx0_enable,
      RX_ALIGNED           => rx0_aligned,
      RX_RFI               => rx0_rfi,
      USR_RX_RESET         => usr_rx0_reset,
      -- TX control signals
      TX_ENABLE            => tx0_enable,  
      TX_SEND_RFI          => tx0_send_rfi,
      TX_SEND_LFI          => tx0_send_lfi,
      TX_SEND_IDLE         => tx0_send_idle,
      USR_TX_RESET         => usr_tx0_reset,
      TX_OVERFLOW          => tx0_overflow,
      TX_UNDERFLOW         => tx0_underflow   
   );


------------------------------------------------------------------------------------
--                               CMAC 1                               
------------------------------------------------------------------------------------

 cmac_usplus_1_inst: entity work.cmac_usplus_wrapper1
   generic map(
      g_data_width         => 512
   )
   port map( 
      RESET                => cmac1_reset,
      TX_RESET             => tx1_reset,
      RX_RESET             => rx1_reset,
      REF_CLK_P            => QSFP1_REFCLK_P,
      REF_CLK_N            => QSFP1_REFCLK_N,
      INIT_CLK             => clk_300m,
      CORE_CLK             => udp1_clk,
      -- MGTs
      RX_P                 => QSFP1_RX_P,
      RX_N                 => QSFP1_RX_N,
      TX_P                 => QSFP1_TX_P,
      TX_N                 => QSFP1_TX_N,
      -- Master axis
      M_AXIS_TREADY        => s_axis_rx1_tready,
      M_AXIS_TVALID        => s_axis_rx1_tvalid,
      M_AXIS_TDATA         => s_axis_rx1_tdata, 
      M_AXIS_TUSER         => s_axis_rx1_tuser, 
      M_AXIS_TKEEP         => s_axis_rx1_tkeep, 
      M_AXIS_TLAST         => s_axis_rx1_tlast, 
      -- Slave axis
      S_AXIS_TREADY        => m_axis_tx1_tready,
      S_AXIS_TVALID        => m_axis_tx1_tvalid,
      S_AXIS_TDATA         => m_axis_tx1_tdata, 
      S_AXIS_TUSER         => m_axis_tx1_tuser, 
      S_AXIS_TKEEP         => m_axis_tx1_tkeep, 
      S_AXIS_TLAST         => m_axis_tx1_tlast, 
      -- RX control signals
      RX_ENABLE            => rx1_enable,
      RX_ALIGNED           => rx1_aligned,
      RX_RFI               => rx1_rfi,
      USR_RX_RESET         => usr_rx1_reset,
      -- TX control signals
      TX_ENABLE            => tx1_enable,  
      TX_SEND_RFI          => tx1_send_rfi,
      TX_SEND_LFI          => tx1_send_lfi,
      TX_SEND_IDLE         => tx1_send_idle,
      USR_TX_RESET         => usr_tx1_reset,
      TX_OVERFLOW          => tx1_overflow,
      TX_UNDERFLOW         => tx1_underflow   
   );

end Behavioral;
