// ***************************************************************************
// ***************************************************************************
// Copyright (C) 2020-2023 Analog Devices, Inc. All rights reserved.
//
// In this HDL repository, there are many different and unique modules, consisting
// of various HDL (Verilog or VHDL) components. The individual modules are
// developed independently, and may be accompanied by separate and unique license
// terms.
//
// The user should read each of these license terms, and understand the
// freedoms and responsibilities that he or she has by using this source/core.
//
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE.
//
// Redistribution and use of source or resulting binaries, with or without modification
// of this file, are permitted under one of the following two license terms:
//
//   1. The GNU General Public License version 2 as published by the
//      Free Software Foundation, which can be found in the top level directory
//      of this repository (LICENSE_GPL2), and also online at:
//      <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// OR
//
//   2. An ADI specific BSD license, which can be found in the top level directory
//      of this repository (LICENSE_ADIBSD), and also on-line at:
//      https://github.com/analogdevicesinc/hdl/blob/main/LICENSE_ADIBSD
//      This will allow to generate bit files and not release the source code,
//      as long as it attaches to an ADI device.
//
// ***************************************************************************
// ***************************************************************************

`timescale 1ns/100ps

module system_raw_eth_top  #(
  parameter FPGA_REVISION_DATE = 32'h05212026, 
  parameter MINOR_REV = 8'h02,  
  parameter TX_JESD_L = 8,
  parameter TX_NUM_LINKS = 1,
  parameter RX_JESD_L = 8,
  parameter RX_NUM_LINKS = 1,
  parameter SHARED_DEVCLK = 0,
  parameter JESD_MODE = "8B10B"
) (
//  input  [12:0] gpio_bd_i,
//  output [ 7:0] gpio_bd_o,
  input                               QSFP1_INTL_LS,
  input                               QSFP1_MODPRSL_LS,
  output                              QSFP1_RESETL_LS,
  input                               QSFP1_RX1_N,
  input                               QSFP1_RX1_P,
  input                               QSFP1_RX2_N,
  input                               QSFP1_RX2_P,
  input                               QSFP1_RX3_N,
  input                               QSFP1_RX3_P,
  input                               QSFP1_RX4_N,
  input                               QSFP1_RX4_P,
  input                               QSFP1_SI570_CLOCK_N,  //CLK2_N  
  input                               QSFP1_SI570_CLOCK_P,
  output                              QSFP1_TX1_N,
  output                              QSFP1_TX1_P,
  output                              QSFP1_TX2_N,
  output                              QSFP1_TX2_P,
  output                              QSFP1_TX3_N,
  output                              QSFP1_TX3_P,
  output                              QSFP1_TX4_N,
  output                              QSFP1_TX4_P,

  input                               QSFP2_INTL_LS,
  input                               QSFP2_MODPRSL_LS,
  output                              QSFP2_RESETL_LS,
//  input                               QSFP2_RX1_N,
//  input                               QSFP2_RX1_P,
//  input                               QSFP2_RX2_N,
//  input                               QSFP2_RX2_P,
//  input                               QSFP2_RX3_N,
//  input                               QSFP2_RX3_P,
//  input                               QSFP2_RX4_N,
//  input                               QSFP2_RX4_P,
//  input                               QSFP2_SI570_CLOCK_N,//CLK3_N  
//  input                               QSFP2_SI570_CLOCK_P,
//  output                              QSFP2_TX1_N,
//  output                              QSFP2_TX1_P,
//  output                              QSFP2_TX2_N,
//  output                              QSFP2_TX2_P,
//  output                              QSFP2_TX3_N,
//  output                              QSFP2_TX3_P,
//  output                              QSFP2_TX4_N,
//  output                              QSFP2_TX4_P,

  input                               QSFP3_INTL_LS,
  input                               QSFP3_MODPRSL_LS,
  output                              QSFP3_RESETL_LS,
//  input                               QSFP3_RX1_N,
//  input                               QSFP3_RX1_P,
//  input                               QSFP3_RX2_N,
//  input                               QSFP3_RX2_P,
//  input                               QSFP3_RX3_N,
//  input                               QSFP3_RX3_P,
//  input                               QSFP3_RX4_N,
//  input                               QSFP3_RX4_P,
//  input                               QSFP3_SI570_CLOCK_N,//CLK1_N  
//  input                               QSFP3_SI570_CLOCK_P,
//  output                              QSFP3_TX1_N,
//  output                              QSFP3_TX1_P,
//  output                              QSFP3_TX2_N,
//  output                              QSFP3_TX2_P,
//  output                              QSFP3_TX3_N,
//  output                              QSFP3_TX3_P,
//  output                              QSFP3_TX4_N,
//  output                              QSFP3_TX4_P,

  input                               QSFP4_INTL_LS,
  input                               QSFP4_MODPRSL_LS,
  output                              QSFP4_RESETL_LS,
  input                               QSFP4_RX1_N,
  input                               QSFP4_RX1_P,
  input                               QSFP4_RX2_N,
  input                               QSFP4_RX2_P,
  input                               QSFP4_RX3_N,
  input                               QSFP4_RX3_P,
  input                               QSFP4_RX4_N,
  input                               QSFP4_RX4_P,
  input                               QSFP4_SI570_CLOCK_N,//CLK0_N  
  input                               QSFP4_SI570_CLOCK_P,
  output                              QSFP4_TX1_N,
  output                              QSFP4_TX1_P,
  output                              QSFP4_TX2_N,
  output                              QSFP4_TX2_P,
  output                              QSFP4_TX3_N,
  output                              QSFP4_TX3_P,
  output                              QSFP4_TX4_N,
  output                              QSFP4_TX4_P,

  inout                               pll_scl,
  inout                               pll_sda,

  // FMC HPC IOs
  input  [1:0]  agc0,
  input  [1:0]  agc1,
  input  [1:0]  agc2,
  input  [1:0]  agc3,
  input         clkin6_n,
  input         clkin6_p,
  input         clkin10_n,
  input         clkin10_p,
  input                               clkin8_n,
  input                               clkin8_p, 
  input         fpga_refclk_in_n,
  input         fpga_refclk_in_p,
  input  [RX_JESD_L*RX_NUM_LINKS-1:0]  rx_data_n,
  input  [RX_JESD_L*RX_NUM_LINKS-1:0]  rx_data_p,
  output [TX_JESD_L*TX_NUM_LINKS-1:0]  tx_data_n,
  output [TX_JESD_L*TX_NUM_LINKS-1:0]  tx_data_p,
  input    fpga_syncin_0_n,
  input    fpga_syncin_0_p,
  inout    fpga_syncin_1_n,
  inout    fpga_syncin_1_p,
  output   fpga_syncout_0_n,
  output   fpga_syncout_0_p,
  inout    fpga_syncout_1_n,
  inout    fpga_syncout_1_p,
  inout  [10:0] gpio,
  inout         hmc_gpio1,
  output        hmc_sync,
  input  [1:0]  irqb,
  output        rstb,
  output [1:0]  rxen,
  output        spi0_csb,
  input         spi0_miso,
  output        spi0_mosi,
  output        spi0_sclk,
  output        spi1_csb,
  output        spi1_sclk,
  inout         spi1_sdio,
  input         sysref2_n,
  input         sysref2_p,
  output [1:0]  txen
);

  // internal signals

  wire    [94:0]  gpio_i;
  wire    [94:0]  gpio_o;
  wire    [94:0]  gpio_t;
  wire    [ 2:0]  spi0_csn;

  wire    [ 2:0]  spi1_csn;
  wire            spi1_mosi;
  wire            spi1_miso;

  wire            ref_clk;
  wire            ref_clk_div2;
  wire            ref_clk_div2_bufg;
  wire            sysref;
  wire    [TX_NUM_LINKS-1:0]   tx_syncin;
  wire    [RX_NUM_LINKS-1:0]   rx_syncout;

  wire    [7:0]   rx_data_p_loc;
  wire    [7:0]   rx_data_n_loc;
  wire    [7:0]   tx_data_p_loc;
  wire    [7:0]   tx_data_n_loc;

  wire            clkin6;
  wire            clkin10;
  wire            clkin8;
  wire            clkin8_bufg;
  wire            tx_device_clk;
  wire            rx_device_clk_internal;
  wire            rx_device_clk;

  wire            clk_125;
  wire            clk_125_aresetn;

  wire            clk_250;
  wire            clk_250_aresetn;

  wire            vio_rstb;
  wire            rstb_i;
//// 
  wire            rx_device_clk_1;
  wire            rx_device_clk_aresetn;

  wire [255:0]    adc_tdata_256b;
  wire            adc_tvalid_256b;
  wire            adc_tdata_256b_overflow;
  wire            adc_fifo_tready_256b;
  reg  [31:0]     adc_tvalid_256b_cnt_r = 32'h0;
////
  wire [511:0]    cmac_0_tx_tdata_512b;
  wire            cmac_0_tx_tvalid_512b; 
  wire            cmac_0_tx_tvalid_512b_en; 
  wire            cmac_0_tx_tready_512b;    
  wire            cmac_0_tx_tready_512b_en;    
  reg  [31:0]     cmac_0_tx_tvalid_512b_cnt_r = 32'h0;

  wire  [511:0]   cmac_0_rx_tdata_512b;                
  wire            cmac_0_rx_tvalid_512b;               
  wire            cmac_0_rx_tvalid_512b_en;               
  wire            cmac_0_rx_tready_512b;                
  wire            cmac_0_rx_tready_512b_en;                
  reg   [31:0]    cmac_0_rx_tvalid_512b_cnt_r = 32'h0; 
  
  wire  [127:0]   cmac_0_rx_tdata_128b;                
  wire            cmac_0_rx_tvalid_128b;               

////
  wire [511:0]    cmac_4_tx_tdata_512b;
  wire            cmac_4_tx_tvalid_512b; 
  wire            cmac_4_tx_tvalid_512b_en; 
  wire            cmac_4_tx_tready_512b;    
  wire            cmac_4_tx_tready_512b_en;    
  reg  [31:0]     cmac_4_tx_tvalid_512b_cnt_r = 32'h0;

  wire  [511:0]   cmac_4_rx_tdata_512b;                
  wire            cmac_4_rx_tvalid_512b;               
  wire            cmac_4_rx_tvalid_512b_en;               
  wire            cmac_4_rx_tready_512b;                
  wire            cmac_4_rx_tready_512b_en;                
  reg   [31:0]    cmac_4_rx_tvalid_512b_cnt_r = 32'h0; 

  wire  [127:0]   cmac_4_rx_tdata_128b;                
  wire            cmac_4_rx_tvalid_128b;               

////
  wire  [255:0]   cmac_rx_tdata_256b;                
  wire            cmac_rx_tvalid_256b;               
  wire            cmac_rx_tready_256b;  
  wire            cmac_rx_tready_256b_i;
  reg   [31:0]    cmac_rx_tvalid_256b_cnt_r = 32'h0; 

////
  wire            tx_device_clk_1;
  wire            tx_device_clk_aresetn;    

  wire  [255:0]   mem_xfer_tx_upload_tdata_256b; 
  wire            mem_xfer_tx_upload_tvalid_256b;
  wire            mem_xfer_tx_upload_tready_256b;
  reg   [31:0]    mem_xfer_tx_upload_tvalid_256b_cnt_r = 32'h0;

  wire  [255:0]   dac_tdata_256b;
  wire            dac_tvalid_256b;
  wire            dac_tready_256b;

  wire  [255:0]   dac_tdata_256b_pipe;
  wire            dac_tvalid_256b_pipe;
  wire            dac_tready_256b_pipe;
  reg   [31:0]    dac_tvalid_256b_cnt_r = 32'h0; 
    
//////////////////////////
  wire  [31:0]    slv_reg9;
  wire  [31:0]    slv_reg10;


  wire  [31:0]    slv_reg31;
  wire  [31:0]    slv_reg38;
  wire  [31:0]    slv_reg45;
  wire  [31:0]    slv_reg52;

  wire  [1:0]     dac_src_data_sel;
    
  wire            chan1to4_mode_sel;
  wire            playback_path_data_enable_n;
  
  wire            clk_100;
  wire            clk_100_aresetn;
  wire            clk_100_areset;
  wire   [31:0]   M11_AXI_0_araddr;
  wire   [2:0]    M11_AXI_0_arprot;
  wire            M11_AXI_0_arready;
  wire            M11_AXI_0_arvalid;
  wire   [31:0]   M11_AXI_0_awaddr;
  wire   [2:0]    M11_AXI_0_awprot;
  wire            M11_AXI_0_awready;
  wire            M11_AXI_0_awvalid;
  wire            M11_AXI_0_bready;
  wire   [1:0]    M11_AXI_0_bresp;
  wire            M11_AXI_0_bvalid;
  wire   [31:0]   M11_AXI_0_rdata;
  wire            M11_AXI_0_rready;
  wire   [1:0]    M11_AXI_0_rresp;
  wire            M11_AXI_0_rvalid;
  wire   [31:0]   M11_AXI_0_wdata;
  wire            M11_AXI_0_wready;
  wire   [3:0]    M11_AXI_0_wstrb;
  wire            M11_AXI_0_wvalid;

  wire   [31:0]   M12_AXI_0_araddr;
  wire   [2:0]    M12_AXI_0_arprot;
  wire            M12_AXI_0_arready;
  wire            M12_AXI_0_arvalid;
  wire   [31:0]   M12_AXI_0_awaddr;
  wire   [2:0]    M12_AXI_0_awprot;
  wire            M12_AXI_0_awready;
  wire            M12_AXI_0_awvalid;
  wire            M12_AXI_0_bready;
  wire   [1:0]    M12_AXI_0_bresp;
  wire            M12_AXI_0_bvalid;
  wire   [31:0]   M12_AXI_0_rdata;
  wire            M12_AXI_0_rready;
  wire   [1:0]    M12_AXI_0_rresp;
  wire            M12_AXI_0_rvalid;
  wire   [31:0]   M12_AXI_0_wdata;
  wire            M12_AXI_0_wready;
  wire   [3:0]    M12_AXI_0_wstrb;
  wire            M12_AXI_0_wvalid;

  wire   [31:0]   M13_AXI_0_araddr;
  wire   [2:0]    M13_AXI_0_arprot;
  wire            M13_AXI_0_arready;
  wire            M13_AXI_0_arvalid;
  wire   [31:0]   M13_AXI_0_awaddr;
  wire   [2:0]    M13_AXI_0_awprot;
  wire            M13_AXI_0_awready;
  wire            M13_AXI_0_awvalid;
  wire            M13_AXI_0_bready;
  wire   [1:0]    M13_AXI_0_bresp;
  wire            M13_AXI_0_bvalid;
  wire   [31:0]   M13_AXI_0_rdata;
  wire            M13_AXI_0_rready;
  wire   [1:0]    M13_AXI_0_rresp;
  wire            M13_AXI_0_rvalid;
  wire   [31:0]   M13_AXI_0_wdata;
  wire            M13_AXI_0_wready;
  wire   [3:0]    M13_AXI_0_wstrb;
  wire            M13_AXI_0_wvalid;

  wire            sda_i;
  wire            sda_o;
  wire            sda_t;

  wire            scl_i;
  wire            scl_o;
  wire            scl_t;
  
  wire            mxfe_rx_data_offload_s_axis_tready;

  wire [3:0]      cmac_gt_0_grx_n;
  wire [3:0]      cmac_gt_0_grx_p;
  wire [3:0]      cmac_gt_0_gtx_n;
  wire [3:0]      cmac_gt_0_gtx_p;
  wire            cmac_refclk_0_clk_n;
  wire            cmac_refclk_0_clk_p;

  wire            cmac_tx_intfc_en; 
  wire            cmac_rx_intfc_en; 

  wire [3:0]      cmac_gt_4_grx_n;
  wire [3:0]      cmac_gt_4_grx_p;
  wire [3:0]      cmac_gt_4_gtx_n;
  wire [3:0]      cmac_gt_4_gtx_p;
  wire            cmac_refclk_4_clk_n;
  wire            cmac_refclk_4_clk_p;

  wire [127:0]    adc_tdata_128b_chan0;
  wire [127:0]    adc_tdata_128b_chan1;
  
  
////////////////////////////////////////////////////////////////

  // instantiations

  IBUFDS_GTE4 i_ibufds_ref_clk (
    .CEB                                  (1'd0),
    .I                                    (fpga_refclk_in_p),
    .IB                                   (fpga_refclk_in_n),
    .O                                    (ref_clk),
    .ODIV2                                (ref_clk_div2)
    );

  BUFG_GT i_bufgt_ref_clk (
    .I                                    (ref_clk_div2),
    .CE                                   (1'b1),
    .CEMASK                               (1'b0),
    .CLR                                  (1'b0),
    .CLRMASK                              (1'b0),
    .DIV                                  (3'b000),
    .O                                    (ref_clk_div2_bufg)
    );
    
////
  IBUFDS i_ibufds_sysref (
    .I                                    (sysref2_p),
    .IB                                   (sysref2_n),
    .O                                    (sysref)
    );
    
/////
  IBUFDS i_ibufds_clkin6 (
    .I                                    (clkin6_p),
    .IB                                   (clkin6_n),
    .O                                    (clkin6)
    );

  BUFG i_bufg_tx_device_clk (
    .I                                    (clkin6),
    .O                                    (tx_device_clk)
    );
    
////    
  IBUFDS i_ibufds_clkin10 (
    .I                                    (clkin10_p),
    .IB                                   (clkin10_n),
    .O                                    (clkin10)
    );
    
  BUFG i_bufg_rx_device_clk (
    .I                                    (clkin10),
    .O                                    (rx_device_clk)
    );
    
/////
  IBUFDS_GTE4 i_ibufds_clkin8 (
    .I                                    (clkin8_p),
    .IB                                   (clkin8_n),
    .CEB                                  (1'b0),
    .O                                    (),
    .ODIV2                                (clkin8)
    );

  BUFG_GT i_bufgt_clkin8 (
    .I                                    (clkin8),
    .CE                                   (1'b1),
    .CEMASK                               (1'b0),
    .CLR                                  (1'b0),
    .CLRMASK                              (1'b0),
    .DIV                                  (3'b000),
    .O                                    (clkin8_bufg)
    );
    
///    
  IBUFDS i_ibufds_syncin_0 (
    .I                                    (fpga_syncin_0_p),
    .IB                                   (fpga_syncin_0_n),
    .O                                    (tx_syncin[0])
    );

  OBUFDS i_obufds_syncout_0 (
    .I                                    (rx_syncout[0]),
    .O                                    (fpga_syncout_0_p),
    .OB                                   (fpga_syncout_0_n)
    );

  
//  assign rx_device_clk = SHARED_DEVCLK ? tx_device_clk : rx_device_clk_internal;

  // spi

  assign spi0_csb = spi0_csn[0];
  assign spi1_csb = spi1_csn[0];

  ad_3w_spi #(
    .NUM_OF_SLAVES                        (1)
    ) 
  i_spi (
    .spi_csn                              (spi1_csn[0]),
    .spi_clk                              (spi1_sclk),
    .spi_mosi                             (spi1_mosi),
    .spi_miso                             (spi1_miso),
    .spi_sdio                             (spi1_sdio),
    .spi_dir                              ()
    );

  // gpios

  ad_iobuf #(
    .DATA_WIDTH                           (12)
    ) 
  i_iobuf (
    .dio_t                                (gpio_t[43:32]),
    .dio_i                                (gpio_o[43:32]),
    .dio_o                                (gpio_i[43:32]),
    .dio_p                                ({hmc_gpio1,       // 43
                                            gpio[10:0]})     // 42-32
    );   

  assign gpio_i[44] = agc0[0];
  assign gpio_i[45] = agc0[1];
  assign gpio_i[46] = agc1[0];
  assign gpio_i[47] = agc1[1];
  assign gpio_i[48] = agc2[0];
  assign gpio_i[49] = agc2[1];
  assign gpio_i[50] = agc3[0];
  assign gpio_i[51] = agc3[1];
  assign gpio_i[52] = irqb[0];
  assign gpio_i[53] = irqb[1];

  assign hmc_sync = gpio_o[54];
  assign rstb     = gpio_o[55];
  assign rxen[0]  = gpio_o[56];
  assign rxen[1]  = gpio_o[57];
  assign txen[0]  = gpio_o[58];
  assign txen[1]  = gpio_o[59];

  assign rstb       = rstb_i;
  
  generate
    if (TX_NUM_LINKS > 1 & JESD_MODE == "8B10B") 
    begin
      assign tx_syncin[1] = fpga_syncin_1_p;
    end 
    else 
    begin
      ad_iobuf #(
        .DATA_WIDTH                       (2)
        ) 
      i_syncin_iobuf (
        .dio_t                            (gpio_t[61:60]),
        .dio_i                            (gpio_o[61:60]),
        .dio_o                            (gpio_i[61:60]),
        .dio_p                            ({fpga_syncin_1_n,      // 61
                                            fpga_syncin_1_p}));   // 60
    end

    if (RX_NUM_LINKS > 1 & JESD_MODE == "8B10B") 
    begin
      assign fpga_syncout_1_p = rx_syncout[1];
      assign fpga_syncout_1_n = 0;
    end 
    else 
    begin
      ad_iobuf #(
        .DATA_WIDTH(2)
        ) 
      i_syncout_iobuf (
        .dio_t                            (gpio_t[63:62]),
        .dio_i                            (gpio_o[63:62]),
        .dio_o                            (gpio_i[63:62]),
        .dio_p                            ({fpga_syncout_1_n,      // 63
                                            fpga_syncout_1_p})     // 62
        );   
    end
  endgenerate
  /* Board GPIOS. Buttons, LEDs, etc... */
//  assign gpio_i[20: 8] = gpio_bd_i;
//  assign gpio_bd_o = gpio_o[7:0];
  
  // Unused GPIOs
  assign gpio_i[59:54] = gpio_o[59:54];
  assign gpio_i[94:64] = gpio_o[94:64];
  assign gpio_i[31:21] = gpio_o[31:21];
  assign gpio_i[7:0] = gpio_o[7:0];

  system_wrapper i_system_wrapper (
    .gpio_i                               (gpio_i),
    .gpio_o                               (gpio_o),
    .gpio_t                               (gpio_t),
    .spi0_csn                             (spi0_csn),
    .spi0_miso                            (spi0_miso),
    .spi0_mosi                            (spi0_mosi),
    .spi0_sclk                            (spi0_sclk),
    .spi1_csn                             (spi1_csn),
    .spi1_miso                            (spi1_miso),
    .spi1_mosi                            (spi1_mosi),
    .spi1_sclk                            (spi1_sclk),
    // FMC HPC
    .rx_data_0_n                          (rx_data_n_loc[0]),
    .rx_data_0_p                          (rx_data_p_loc[0]),
    .rx_data_1_n                          (rx_data_n_loc[1]),
    .rx_data_1_p                          (rx_data_p_loc[1]),
    .rx_data_2_n                          (rx_data_n_loc[2]),
    .rx_data_2_p                          (rx_data_p_loc[2]),
    .rx_data_3_n                          (rx_data_n_loc[3]),
    .rx_data_3_p                          (rx_data_p_loc[3]),
    .rx_data_4_n                          (rx_data_n_loc[4]),
    .rx_data_4_p                          (rx_data_p_loc[4]),
    .rx_data_5_n                          (rx_data_n_loc[5]),
    .rx_data_5_p                          (rx_data_p_loc[5]),
    .rx_data_6_n                          (rx_data_n_loc[6]),
    .rx_data_6_p                          (rx_data_p_loc[6]),
    .rx_data_7_n                          (rx_data_n_loc[7]),
    .rx_data_7_p                          (rx_data_p_loc[7]),
    .tx_data_0_n                          (tx_data_n_loc[0]),
    .tx_data_0_p                          (tx_data_p_loc[0]),
    .tx_data_1_n                          (tx_data_n_loc[1]),
    .tx_data_1_p                          (tx_data_p_loc[1]),
    .tx_data_2_n                          (tx_data_n_loc[2]),
    .tx_data_2_p                          (tx_data_p_loc[2]),
    .tx_data_3_n                          (tx_data_n_loc[3]),
    .tx_data_3_p                          (tx_data_p_loc[3]),
    .tx_data_4_n                          (tx_data_n_loc[4]),
    .tx_data_4_p                          (tx_data_p_loc[4]),
    .tx_data_5_n                          (tx_data_n_loc[5]),
    .tx_data_5_p                          (tx_data_p_loc[5]),
    .tx_data_6_n                          (tx_data_n_loc[6]),
    .tx_data_6_p                          (tx_data_p_loc[6]),
    .tx_data_7_n                          (tx_data_n_loc[7]),
    .tx_data_7_p                          (tx_data_p_loc[7]),
    .ref_clk_q0                           (ref_clk),
    .ref_clk_q1                           (ref_clk),
    .rx_device_clk                        (rx_device_clk),
    .tx_device_clk                        (tx_device_clk),
    .rx_sync_0                            (rx_syncout),
    .tx_sync_0                            (tx_syncin),
    .rx_sysref_0                          (sysref),
    .tx_sysref_0                          (sysref),
    
    // these signals are sync to rx_device_clk
    .rx_device_clk_out                    (rx_device_clk_1),
    .rx_device_clk_aresetn_out            (rx_device_clk_aresetn),
    .packed_fifo_wr_data_out              (adc_tdata_256b),             // out    ADC Rx Data
    .packed_fifo_wr_en_out                (adc_tvalid_256b),            // out
    .packed_fifo_wr_overflow_out          (adc_tdata_256b_overflow),    // out
    
    .tx_device_clk_out                    (tx_device_clk_1),
    .tx_device_clk_aresetn_out            (tx_device_clk_aresetn),    
    .mxfe_tx_data_offload_m_axis_tdata    (mem_xfer_tx_upload_tdata_256b),   // out    mem transfer from uP
    .mxfe_tx_data_offload_m_axis_tvalid   (mem_xfer_tx_upload_tvalid_256b),  // out
    .mxfe_tx_data_offload_m_axis_tready   (mem_xfer_tx_upload_tready_256b),  // in
    .mxfe_tx_data_offload_m_axis_tkeep    (),   // out
    .mxfe_tx_data_offload_m_axis_tlast    (),   // out
    
    .util_mxfe_upack_s_axis_tdata         (dac_tdata_256b_pipe ),   // in    DAC Tx Data
    .util_mxfe_upack_s_axis_tvalid        (dac_tvalid_256b_pipe),   // in
    .util_mxfe_upack_s_axis_tready        (dac_tready_256b_pipe),   // out
            
    .sys_cpu_clk_out                      (clk_100),
    .sys_cpu_aresetn_out                  (clk_100_aresetn),
    .M11_AXI_0_araddr                     (M11_AXI_0_araddr),
    .M11_AXI_0_arprot                     (M11_AXI_0_arprot),
    .M11_AXI_0_arready                    (M11_AXI_0_arready),
    .M11_AXI_0_arvalid                    (M11_AXI_0_arvalid),
    .M11_AXI_0_awaddr                     (M11_AXI_0_awaddr),
    .M11_AXI_0_awprot                     (M11_AXI_0_awprot),
    .M11_AXI_0_awready                    (M11_AXI_0_awready),
    .M11_AXI_0_awvalid                    (M11_AXI_0_awvalid),
    .M11_AXI_0_bready                     (M11_AXI_0_bready),
    .M11_AXI_0_bresp                      (M11_AXI_0_bresp),
    .M11_AXI_0_bvalid                     (M11_AXI_0_bvalid),
    .M11_AXI_0_rdata                      (M11_AXI_0_rdata),
    .M11_AXI_0_rready                     (M11_AXI_0_rready),
    .M11_AXI_0_rresp                      (M11_AXI_0_rresp),
    .M11_AXI_0_rvalid                     (M11_AXI_0_rvalid),
    .M11_AXI_0_wdata                      (M11_AXI_0_wdata),
    .M11_AXI_0_wready                     (M11_AXI_0_wready),
    .M11_AXI_0_wstrb                      (M11_AXI_0_wstrb),
    .M11_AXI_0_wvalid                     (M11_AXI_0_wvalid),

    .M12_AXI_0_araddr                     (M12_AXI_0_araddr),
    .M12_AXI_0_arprot                     (M12_AXI_0_arprot),
    .M12_AXI_0_arready                    (M12_AXI_0_arready),
    .M12_AXI_0_arvalid                    (M12_AXI_0_arvalid),
    .M12_AXI_0_awaddr                     (M12_AXI_0_awaddr),
    .M12_AXI_0_awprot                     (M12_AXI_0_awprot),
    .M12_AXI_0_awready                    (M12_AXI_0_awready),
    .M12_AXI_0_awvalid                    (M12_AXI_0_awvalid),
    .M12_AXI_0_bready                     (M12_AXI_0_bready),
    .M12_AXI_0_bresp                      (M12_AXI_0_bresp),
    .M12_AXI_0_bvalid                     (M12_AXI_0_bvalid),
    .M12_AXI_0_rdata                      (M12_AXI_0_rdata),
    .M12_AXI_0_rready                     (M12_AXI_0_rready),
    .M12_AXI_0_rresp                      (M12_AXI_0_rresp),
    .M12_AXI_0_rvalid                     (M12_AXI_0_rvalid),
    .M12_AXI_0_wdata                      (M12_AXI_0_wdata),
    .M12_AXI_0_wready                     (M12_AXI_0_wready),
    .M12_AXI_0_wstrb                      (M12_AXI_0_wstrb),
    .M12_AXI_0_wvalid                     (M12_AXI_0_wvalid),

    .M13_AXI_0_araddr                     (M13_AXI_0_araddr),
    .M13_AXI_0_arprot                     (M13_AXI_0_arprot),
    .M13_AXI_0_arready                    (M13_AXI_0_arready),
    .M13_AXI_0_arvalid                    (M13_AXI_0_arvalid),
    .M13_AXI_0_awaddr                     (M13_AXI_0_awaddr),
    .M13_AXI_0_awprot                     (M13_AXI_0_awprot),
    .M13_AXI_0_awready                    (M13_AXI_0_awready),
    .M13_AXI_0_awvalid                    (M13_AXI_0_awvalid),
    .M13_AXI_0_bready                     (M13_AXI_0_bready),
    .M13_AXI_0_bresp                      (M13_AXI_0_bresp),
    .M13_AXI_0_bvalid                     (M13_AXI_0_bvalid),
    .M13_AXI_0_rdata                      (M13_AXI_0_rdata),
    .M13_AXI_0_rready                     (M13_AXI_0_rready),
    .M13_AXI_0_rresp                      (M13_AXI_0_rresp),
    .M13_AXI_0_rvalid                     (M13_AXI_0_rvalid),
    .M13_AXI_0_wdata                      (M13_AXI_0_wdata),
    .M13_AXI_0_wready                     (M13_AXI_0_wready),
    .M13_AXI_0_wstrb                      (M13_AXI_0_wstrb),
    .M13_AXI_0_wvalid                     (M13_AXI_0_wvalid),

    .Res_0                              (mxfe_rx_data_offload_s_axis_tready),
   
    .pl_clk1_clk250_out                   (clk_250),
    .pl_clk1_clk250_aresetn_out           (clk_250_aresetn),

    .pl_clk2_clk125_out                   (clk_125),
    .pl_clk2_clk125_aresetn_out           (clk_125_aresetn)
    );
 
  assign rx_data_p_loc[RX_JESD_L*RX_NUM_LINKS-1:0] = rx_data_p[RX_JESD_L*RX_NUM_LINKS-1:0];
  assign rx_data_n_loc[RX_JESD_L*RX_NUM_LINKS-1:0] = rx_data_n[RX_JESD_L*RX_NUM_LINKS-1:0];

  assign tx_data_p[TX_JESD_L*TX_NUM_LINKS-1:0] = tx_data_p_loc[TX_JESD_L*TX_NUM_LINKS-1:0];
  assign tx_data_n[TX_JESD_L*TX_NUM_LINKS-1:0] = tx_data_n_loc[TX_JESD_L*TX_NUM_LINKS-1:0];

  assign clk_100_areset = ~clk_100_aresetn;
  
//  ila_5 i_ila_rx ( 
//    .clk                                  (rx_device_clk_1),
//    .probe0                               (adc_tdata_256b[15:0]),     // 16
//    .probe1                               (adc_tdata_256b[31:16]),    // 16
//    .probe2                               (adc_tdata_256b[47:32]),    // 16
//    .probe3                               (adc_tdata_256b[63:48]),    // 16
//    .probe4                               (adc_tdata_256b[79:64]),    // 16
//    .probe5                               (adc_tdata_256b[95:80]),    // 16
//    .probe6                               (adc_tdata_256b[111:96]),   // 16
//    .probe7                               (adc_tdata_256b[127:112]),  // 16
//    .probe8                               (adc_tdata_256b[143:128]),  // 16
//    .probe9                               (adc_tdata_256b[159:144]),  // 16
//    .probe10                              (adc_tdata_256b[175:160]),  // 16
//    .probe11                              (adc_tdata_256b[191:176]),  // 16
//    .probe12                              (adc_tdata_256b[207:192]),  // 16
//    .probe13                              (adc_tdata_256b[223:208]),  // 16
//    .probe14                              (adc_tdata_256b[239:224]),  // 16
//    .probe15                              (adc_tdata_256b[255:240]),  // 16
//    .probe16                              (adc_tvalid_256b),          // 1
//    .probe17                              (adc_fifo_tready_256b)      // 1
//    );
   
///////////////////////////////////////////////////////////////////////////
  qsfp_intfc_v1_1  #(
    .FPGA_REVISION_DATE                       (FPGA_REVISION_DATE),
    .MINOR_REV                                (MINOR_REV),
    // Parameters of Axi Slave Bus Interface S00_AXI
    .C_S00_AXI_DATA_WIDTH                     (32),
    .C_S00_AXI_ADDR_WIDTH                     (8)
    )
  i_qsfp_intfc_v1_1 (
    .clk_125_in                               (clk_125),            
    .clk_125_reset_n_in                       (clk_125_aresetn),    

    .clk_250_in                               (clk_250),            
    .clk_250_reset_n_in                       (clk_250_aresetn),    

    .rx_device_clk_in                         (rx_device_clk_1),
    .tx_device_clk_in                         (tx_device_clk_1),

    .clkin8_in                                (clkin8_bufg),
//    .sysref_in                                (sysref),
    .ref_clk_div2_in                          (ref_clk_div2_bufg),
///////////

    .QSFP1_RESETL_LS                          (QSFP1_RESETL_LS),
    .QSFP1_MODPRSL_LS                         (QSFP1_MODPRSL_LS),
    .QSFP1_INTL_LS                            (QSFP1_INTL_LS),
///////////
                                                  
    .QSFP2_RESETL_LS                          (QSFP2_RESETL_LS),
    .QSFP2_MODPRSL_LS                         (QSFP2_MODPRSL_LS),
    .QSFP2_INTL_LS                            (QSFP2_INTL_LS),
///////////
                                                  
    .QSFP3_RESETL_LS                          (QSFP3_RESETL_LS),
    .QSFP3_MODPRSL_LS                         (QSFP3_MODPRSL_LS),
    .QSFP3_INTL_LS                            (QSFP3_INTL_LS),
///////////

    .QSFP4_RESETL_LS                          (QSFP4_RESETL_LS),
    .QSFP4_MODPRSL_LS                         (QSFP4_MODPRSL_LS),
    .QSFP4_INTL_LS                            (QSFP4_INTL_LS),
///////
    .cmac_0_rx_tvalid_512b_cnt_in             (cmac_0_rx_tvalid_512b_cnt_r),
    .cmac_4_rx_tvalid_512b_cnt_in             (cmac_4_rx_tvalid_512b_cnt_r),
    .cmac_rx_tvalid_256b_cnt_in               (cmac_rx_tvalid_256b_cnt_r),

    .mem_xfer_tx_upload_tvalid_256b_cnt_in    (mem_xfer_tx_upload_tvalid_256b_cnt_r),                      
    .dac_tvalid_256b_cnt_in                   (dac_tvalid_256b_cnt_r),                                  

    .adc_tvalid_256b_cnt_in                   (adc_tvalid_256b_cnt_r),
    .cmac_0_tx_tvalid_512b_cnt_in             (cmac_0_tx_tvalid_512b_cnt_r),
    .cmac_4_tx_tvalid_512b_cnt_in             (cmac_4_tx_tvalid_512b_cnt_r),
    
    .cnt_reset_out                            (cnt_reset),                                                 

    .slv_reg9_out                             (slv_reg9),
    .slv_reg10_out                            (slv_reg10),

    .slv_reg31_out                            (slv_reg31),
    .slv_reg38_out                            (slv_reg38),
    .slv_reg45_out                            (slv_reg45),
    .slv_reg52_out                            (slv_reg52),

    .sys_cpu_clk_in                           (clk_100),
    .s00_axi_aresetn_in                       (clk_100_aresetn),
    .s00_axi_awaddr                           (M11_AXI_0_awaddr[7:0]),
    .s00_axi_awprot                           (M11_AXI_0_awprot), 
    .s00_axi_awvalid                          (M11_AXI_0_awvalid),
    .s00_axi_awready                          (M11_AXI_0_awready),

    .s00_axi_wdata                            (M11_AXI_0_wdata),
    .s00_axi_wstrb                            (M11_AXI_0_wstrb),
    .s00_axi_wvalid                           (M11_AXI_0_wvalid),
    .s00_axi_wready                           (M11_AXI_0_wready),

    .s00_axi_bresp                            (M11_AXI_0_bresp),
    .s00_axi_bvalid                           (M11_AXI_0_bvalid),
    .s00_axi_bready                           (M11_AXI_0_bready),

    .s00_axi_araddr                           (M11_AXI_0_araddr[7:0]),
    .s00_axi_arprot                           (M11_AXI_0_arprot),
    .s00_axi_arvalid                          (M11_AXI_0_arvalid),
    .s00_axi_arready                          (M11_AXI_0_arready),

    .s00_axi_rdata                            (M11_AXI_0_rdata), 
    .s00_axi_rresp                            (M11_AXI_0_rresp),
    .s00_axi_rvalid                           (M11_AXI_0_rvalid), 
    .s00_axi_rready                           (M11_AXI_0_rready)
    );
  
  assign cmac_tx_intfc_en                   = slv_reg10[0];        //0x8000_0028 
  assign cmac_rx_intfc_en                   = slv_reg10[1];        //0x8000_0028 
//assign                                    = slv_reg10[7:2];
  assign dac_src_data_sel                   = slv_reg10[9:8];   
//assign                                    = slv_reg10[11:10];  
  assign chan1to4_mode_sel                  = slv_reg10[12];
//assign                                    = slv_reg10[14:13]; 
//assign                                    = slv_reg10[15];
//assign                                    = slv_reg10[30:16];
  assign playback_path_data_enable_n        = slv_reg10[31];

//ila_5 i_ila_rx ( 
//  .clk                                  (tx_device_clk_1),
//  .probe0                               (cmac_rx_tdata_256b[15:0]),     // 16
//  .probe1                               (cmac_rx_tdata_256b[31:16]),    // 16
//  .probe2                               (cmac_rx_tdata_256b[47:32]),    // 16
//  .probe3                               (cmac_rx_tdata_256b[63:48]),    // 16
//  .probe4                               (cmac_rx_tdata_256b[79:64]),    // 16
//  .probe5                               (cmac_rx_tdata_256b[95:80]),    // 16
//  .probe6                               (cmac_rx_tdata_256b[111:96]),   // 16
//  .probe7                               (cmac_rx_tdata_256b[127:112]),  // 16
//  .probe8                               (cmac_rx_tdata_256b[143:128]),  // 16
//  .probe9                               (cmac_rx_tdata_256b[159:144]),  // 16
//  .probe10                              (cmac_rx_tdata_256b[175:160]),  // 16
//  .probe11                              (cmac_rx_tdata_256b[191:176]),  // 16
//  .probe12                              (cmac_rx_tdata_256b[207:192]),  // 16
//  .probe13                              (cmac_rx_tdata_256b[223:208]),  // 16
//  .probe14                              (cmac_rx_tdata_256b[239:224]),  // 16
//  .probe15                              (cmac_rx_tdata_256b[255:240]),  // 16
//  .probe16                              (cmac_rx_tvalid_256b),          // 1
//  .probe17                              (cmac_rx_tready_256b_i)      // 1
//  );

///////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////

  assign cmac_refclk_0_clk_p = QSFP1_SI570_CLOCK_P;
  assign cmac_refclk_0_clk_n = QSFP1_SI570_CLOCK_N;
  
  assign cmac_gt_0_grx_p[0]  = QSFP1_RX1_P;
  assign cmac_gt_0_grx_n[0]  = QSFP1_RX1_N;
  assign cmac_gt_0_grx_p[1]  = QSFP1_RX2_P;
  assign cmac_gt_0_grx_n[1]  = QSFP1_RX2_N;
  assign cmac_gt_0_grx_p[2]  = QSFP1_RX3_P;
  assign cmac_gt_0_grx_n[2]  = QSFP1_RX3_N;
  assign cmac_gt_0_grx_p[3]  = QSFP1_RX4_P;
  assign cmac_gt_0_grx_n[3]  = QSFP1_RX4_N;
  
  assign QSFP1_TX1_P =  cmac_gt_0_gtx_p[0];   
  assign QSFP1_TX1_N =  cmac_gt_0_gtx_n[0];   
  assign QSFP1_TX2_P =  cmac_gt_0_gtx_p[1];   
  assign QSFP1_TX2_N =  cmac_gt_0_gtx_n[1];   
  assign QSFP1_TX3_P =  cmac_gt_0_gtx_p[2];   
  assign QSFP1_TX3_N =  cmac_gt_0_gtx_n[2];   
  assign QSFP1_TX4_P =  cmac_gt_0_gtx_p[3];   
  assign QSFP1_TX4_N =  cmac_gt_0_gtx_n[3];   
  
  raw_eth_wrapper i_raw_eth_cmac_0 (    
    .clk_100_0              (clk_100),
    .clk_100_reset_0        (clk_100_areset),
    
    .cmac_gt_0_grx_n        (cmac_gt_0_grx_n),      //in
    .cmac_gt_0_grx_p        (cmac_gt_0_grx_p),      //in
    .cmac_gt_0_gtx_n        (cmac_gt_0_gtx_n),      //out
    .cmac_gt_0_gtx_p        (cmac_gt_0_gtx_p),      //out
    .cmac_refclk_0_clk_n    (cmac_refclk_0_clk_n),
    .cmac_refclk_0_clk_p    (cmac_refclk_0_clk_p),
    
    .m_axis_aclk            (tx_device_clk_1),
    .m_axis_aresetn         (tx_device_clk_aresetn),
    .m_axis_tdata           (cmac_0_rx_tdata_512b),  // out
    .m_axis_tvalid          (cmac_0_rx_tvalid_512b), // out
    .m_axis_tready          (cmac_0_rx_tready_512b_en),  // in
    
    .axil_clk_0             (clk_100),
    .axil_resetn_0          (clk_100_aresetn),

    .s_axil_0_awaddr        (M12_AXI_0_awaddr),
    .s_axil_0_awprot        (M12_AXI_0_awprot), 
    .s_axil_0_awvalid       (M12_AXI_0_awvalid),
    .s_axil_0_awready       (M12_AXI_0_awready),
                               
    .s_axil_0_wdata         (M12_AXI_0_wdata),
    .s_axil_0_wstrb         (M12_AXI_0_wstrb),
    .s_axil_0_wvalid        (M12_AXI_0_wvalid),
    .s_axil_0_wready        (M12_AXI_0_wready),
                               
    .s_axil_0_bresp         (M12_AXI_0_bresp),
    .s_axil_0_bvalid        (M12_AXI_0_bvalid),
    .s_axil_0_bready        (M12_AXI_0_bready),
                               
    .s_axil_0_araddr        (M12_AXI_0_araddr),
    .s_axil_0_arprot        (M12_AXI_0_arprot),
    .s_axil_0_arvalid       (M12_AXI_0_arvalid),
    .s_axil_0_arready       (M12_AXI_0_arready),
                               
    .s_axil_0_rdata         (M12_AXI_0_rdata), 
    .s_axil_0_rresp         (M12_AXI_0_rresp),
    .s_axil_0_rvalid        (M12_AXI_0_rvalid), 
    .s_axil_0_rready        (M12_AXI_0_rready),

    .s_axis_clk             (rx_device_clk_1),
    .s_axis_aresetn         (rx_device_clk_aresetn),
    .s_axis_tdata           (cmac_0_tx_tdata_512b),     // in 
    .s_axis_tvalid          (cmac_0_tx_tvalid_512b_en),    // in
    .s_axis_tready          (cmac_0_tx_tready_512b)     // out
    );
        
  assign adc_tdata_128b_chan0 =  {adc_tdata_256b[223:192], adc_tdata_256b[159:128], adc_tdata_256b[95:64],   adc_tdata_256b[31:0]};   // adc_chan0_s3,  adc_chan0_s2, adc_chan0_s1,  adc_chan0_s0

  axis_dwidth_converter_128b_to_512b i_axis_dwidth_converter_128b_to_512b_cmac_0 (  
    .aclk                                 (rx_device_clk_1),            // in
    .aresetn                              (rx_device_clk_aresetn),      // in

    .s_axis_tdata                         (adc_tdata_128b_chan0),             // in
    .s_axis_tvalid                        (adc_tvalid_256b),            // in
    .s_axis_tready                        ( ),                          // out

    .m_axis_tdata                         (cmac_0_tx_tdata_512b),         // out
    .m_axis_tvalid                        (cmac_0_tx_tvalid_512b),        // out
    .m_axis_tready                        (cmac_0_tx_tready_512b_en)         // in
    );

  assign cmac_0_tx_tvalid_512b_en  = (cmac_tx_intfc_en == 1'b1) ? cmac_0_tx_tvalid_512b : 1'b0;
  assign cmac_0_tx_tready_512b_en  = (cmac_tx_intfc_en == 1'b1) ? cmac_0_tx_tready_512b : 1'b0;
 ///////////
  assign cmac_0_rx_tvalid_512b_en  = (cmac_rx_intfc_en == 1'b1) ? cmac_0_rx_tvalid_512b : 1'b0;
  assign cmac_0_rx_tready_512b_en  = (cmac_rx_intfc_en == 1'b1) ? cmac_0_rx_tready_512b : 1'b0;
  
  axis_dwidth_converter_512b_to_128b i_axis_dwidth_converter_512b_to_128b_cmac_0 (  
    .aclk                                 (tx_device_clk_1),            // in
    .aresetn                              (tx_device_clk_aresetn),      // in

    .s_axis_tdata                         (cmac_0_rx_tdata_512b),      // in
    .s_axis_tvalid                        (cmac_0_rx_tvalid_512b_en),     // in
    .s_axis_tready                        (cmac_0_rx_tready_512b),       // out

    .m_axis_tdata                         (cmac_0_rx_tdata_128b),  // out
    .m_axis_tvalid                        (cmac_0_rx_tvalid_128b), // out
    .m_axis_tready                        (cmac_rx_tready_256b_i)  // in
  );
  



///////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////

  assign cmac_refclk_4_clk_p = QSFP4_SI570_CLOCK_P;
  assign cmac_refclk_4_clk_n = QSFP4_SI570_CLOCK_N;
  
  assign cmac_gt_4_grx_p[0]  = QSFP4_RX1_P;
  assign cmac_gt_4_grx_n[0]  = QSFP4_RX1_N;
  assign cmac_gt_4_grx_p[1]  = QSFP4_RX2_P;
  assign cmac_gt_4_grx_n[1]  = QSFP4_RX2_N;
  assign cmac_gt_4_grx_p[2]  = QSFP4_RX3_P;
  assign cmac_gt_4_grx_n[2]  = QSFP4_RX3_N;
  assign cmac_gt_4_grx_p[3]  = QSFP4_RX4_P;
  assign cmac_gt_4_grx_n[3]  = QSFP4_RX4_N;
  
  assign QSFP4_TX1_P =  cmac_gt_4_gtx_p[0];   
  assign QSFP4_TX1_N =  cmac_gt_4_gtx_n[0];   
  assign QSFP4_TX2_P =  cmac_gt_4_gtx_p[1];   
  assign QSFP4_TX2_N =  cmac_gt_4_gtx_n[1];   
  assign QSFP4_TX3_P =  cmac_gt_4_gtx_p[2];   
  assign QSFP4_TX3_N =  cmac_gt_4_gtx_n[2];   
  assign QSFP4_TX4_P =  cmac_gt_4_gtx_p[3];   
  assign QSFP4_TX4_N =  cmac_gt_4_gtx_n[3];   
  
  raw_eth_wrapper_cmac_4 i_raw_eth_cmac_4 (    
    .clk_100_0              (clk_100),
    .clk_100_reset_0        (clk_100_areset),
    
    .cmac_gt_0_grx_n        (cmac_gt_4_grx_n),      //in
    .cmac_gt_0_grx_p        (cmac_gt_4_grx_p),      //in
    .cmac_gt_0_gtx_n        (cmac_gt_4_gtx_n),      //out
    .cmac_gt_0_gtx_p        (cmac_gt_4_gtx_p),      //out
    .cmac_refclk_0_clk_n    (cmac_refclk_4_clk_n),
    .cmac_refclk_0_clk_p    (cmac_refclk_4_clk_p),
    
    .m_axis_aclk            (tx_device_clk_1),
    .m_axis_aresetn         (tx_device_clk_aresetn),
    .m_axis_tdata           (cmac_4_rx_tdata_512b),  // out
    .m_axis_tvalid          (cmac_4_rx_tvalid_512b), // out
    .m_axis_tready          (cmac_4_rx_tready_512b_en),  // in
    
    .axil_clk_0             (clk_100),
    .axil_resetn_0          (clk_100_aresetn),

    .s_axil_0_awaddr        (M13_AXI_0_awaddr),
    .s_axil_0_awprot        (M13_AXI_0_awprot), 
    .s_axil_0_awvalid       (M13_AXI_0_awvalid),
    .s_axil_0_awready       (M13_AXI_0_awready),
                               
    .s_axil_0_wdata         (M13_AXI_0_wdata),
    .s_axil_0_wstrb         (M13_AXI_0_wstrb),
    .s_axil_0_wvalid        (M13_AXI_0_wvalid),
    .s_axil_0_wready        (M13_AXI_0_wready),
                               
    .s_axil_0_bresp         (M13_AXI_0_bresp),
    .s_axil_0_bvalid        (M13_AXI_0_bvalid),
    .s_axil_0_bready        (M13_AXI_0_bready),
                               
    .s_axil_0_araddr        (M13_AXI_0_araddr),
    .s_axil_0_arprot        (M13_AXI_0_arprot),
    .s_axil_0_arvalid       (M13_AXI_0_arvalid),
    .s_axil_0_arready       (M13_AXI_0_arready),
                               
    .s_axil_0_rdata         (M13_AXI_0_rdata), 
    .s_axil_0_rresp         (M13_AXI_0_rresp),
    .s_axil_0_rvalid        (M13_AXI_0_rvalid), 
    .s_axil_0_rready        (M13_AXI_0_rready),

    .s_axis_clk             (rx_device_clk_1),
    .s_axis_aresetn         (rx_device_clk_aresetn),
    .s_axis_tdata           (cmac_4_tx_tdata_512b),     // in 
    .s_axis_tvalid          (cmac_4_tx_tvalid_512b_en),    // in
    .s_axis_tready          (cmac_4_tx_tready_512b)     // out
    );

  assign adc_tdata_128b_chan1 =  {adc_tdata_256b[255:224], adc_tdata_256b[191:160], adc_tdata_256b[127:96],  adc_tdata_256b[63:32]};   // adc_chan1_s3,  adc_chan1_s2, adc_chan1_s1,  adc_chan1_s0
  
  axis_dwidth_converter_128b_to_512b i_axis_dwidth_converter_128b_to_512b_cmac4 (  
    .aclk                                 (rx_device_clk_1),            // in
    .aresetn                              (rx_device_clk_aresetn),      // in

    .s_axis_tdata                         (adc_tdata_128b_chan1),             // in
    .s_axis_tvalid                        (adc_tvalid_256b),            // in
    .s_axis_tready                        ( ),                          // out

    .m_axis_tdata                         (cmac_4_tx_tdata_512b),         // out
    .m_axis_tvalid                        (cmac_4_tx_tvalid_512b),        // out
    .m_axis_tready                        (cmac_4_tx_tready_512b_en)         // in
    );

  assign cmac_4_tx_tvalid_512b_en  = (cmac_tx_intfc_en == 1'b1) ? cmac_4_tx_tvalid_512b : 1'b0;
  assign cmac_4_tx_tready_512b_en  = (cmac_tx_intfc_en == 1'b1) ? cmac_4_tx_tready_512b : 1'b0;
 ///////////
  assign cmac_4_rx_tvalid_512b_en  = (cmac_rx_intfc_en == 1'b1) ? cmac_4_rx_tvalid_512b : 1'b0;
  assign cmac_4_rx_tready_512b_en  = (cmac_rx_intfc_en == 1'b1) ? cmac_4_rx_tready_512b : 1'b0;
  
  axis_dwidth_converter_512b_to_128b i_axis_dwidth_converter_512b_to_128b_cmac_4 (  
    .aclk                                 (tx_device_clk_1),            // in
    .aresetn                              (tx_device_clk_aresetn),      // in

    .s_axis_tdata                         (cmac_4_rx_tdata_512b),      // in
    .s_axis_tvalid                        (cmac_4_rx_tvalid_512b_en),     // in
    .s_axis_tready                        (cmac_4_rx_tready_512b),       // out

    .m_axis_tdata                         (cmac_4_rx_tdata_128b),  // out
    .m_axis_tvalid                        (cmac_4_rx_tvalid_128b), // out
    .m_axis_tready                        (cmac_rx_tready_256b_i)  // in
  );
  
////////////////////////////////////////////////////////////////////////////  
////////////////////////////////////////////////////////////////////////////  

//  assign cmac_rx_tdata_256b      = {cmac_4_rx_tdata_128b, cmac_0_rx_tdata_128b};
//                                     adc_chan1_s3                  adc_chan0_s3               //adc_chan1_s2                    adc_chan0_s2               adc_chan1_s1                     adc_chan0_s1            adc_chan1_s0                  adc_chan0_s0
  assign cmac_rx_tdata_256b      = {cmac_4_rx_tdata_128b[127:96], cmac_0_rx_tdata_128b[127:96], cmac_4_rx_tdata_128b[95:64], cmac_0_rx_tdata_128b[95:64], cmac_4_rx_tdata_128b[63:32], cmac_0_rx_tdata_128b[63:32], cmac_4_rx_tdata_128b[31:0], cmac_0_rx_tdata_128b[31:0]};   

  assign cmac_rx_tvalid_256b     = cmac_4_rx_tvalid_128b & cmac_0_rx_tvalid_128b;
  assign cmac_rx_tready_256b_i   = cmac_rx_tvalid_256b & cmac_rx_tready_256b;

  ila_5 i_ila_rx ( 
    .clk                                  (tx_device_clk_1),
    .probe0                               (cmac_rx_tdata_256b[15:0]),     // 16
    .probe1                               (cmac_rx_tdata_256b[31:16]),    // 16
    .probe2                               (cmac_rx_tdata_256b[47:32]),    // 16
    .probe3                               (cmac_rx_tdata_256b[63:48]),    // 16
    .probe4                               (cmac_rx_tdata_256b[79:64]),    // 16
    .probe5                               (cmac_rx_tdata_256b[95:80]),    // 16
    .probe6                               (cmac_rx_tdata_256b[111:96]),   // 16
    .probe7                               (cmac_rx_tdata_256b[127:112]),  // 16
    .probe8                               (cmac_rx_tdata_256b[143:128]),  // 16
    .probe9                               (cmac_rx_tdata_256b[159:144]),  // 16
    .probe10                              (cmac_rx_tdata_256b[175:160]),  // 16
    .probe11                              (cmac_rx_tdata_256b[191:176]),  // 16
    .probe12                              (cmac_rx_tdata_256b[207:192]),  // 16
    .probe13                              (cmac_rx_tdata_256b[223:208]),  // 16
    .probe14                              (cmac_rx_tdata_256b[239:224]),  // 16
    .probe15                              (cmac_rx_tdata_256b[255:240]),  // 16
    .probe16                              (cmac_rx_tvalid_256b),          // 1
    .probe17                              (cmac_rx_tready_256b)      // 1
    );

  
  axis_mux_256b i_dac_axis_mux_256b (
    .aclk                         (tx_device_clk_1),                    // input 
    .aresetn                      (tx_device_clk_aresetn),              // input 
    .aselect                      (dac_src_data_sel[0]),              // input 

    .s0_axis_tdata                (mem_xfer_tx_upload_tdata_256b),      // input 
    .s0_axis_tvalid               (mem_xfer_tx_upload_tvalid_256b),     // input 
    .s0_axis_tready               (mem_xfer_tx_upload_tready_256b),     // output

    .s1_axis_tdata                (cmac_rx_tdata_256b),                      // input 
    .s1_axis_tvalid               (cmac_rx_tvalid_256b),                     // input 
    .s1_axis_tready               (cmac_rx_tready_256b),                     // output

    .m_axis_tdata                 (dac_tdata_256b),                  // output
    .m_axis_tvalid                (dac_tvalid_256b),                 // output
    .m_axis_tready                (dac_tready_256b)                  // input 
  );

  axis_register_slice_256b i_util_mxfe_upack_reg_slice_256b (
    .aclk                                 (tx_device_clk_1),                         // in
    .aresetn                              (tx_device_clk_aresetn),                   // in
    .s_axis_tdata                         (dac_tdata_256b),            // in
    .s_axis_tvalid                        (dac_tvalid_256b),           // in
    .s_axis_tready                        (dac_tready_256b),           // out
    .m_axis_tdata                         (dac_tdata_256b_pipe),       // out
    .m_axis_tvalid                        (dac_tvalid_256b_pipe),      // out
    .m_axis_tready                        (dac_tready_256b_pipe)       // in
    );

////////////////////////////////////////////////////////////////////////////  
  always @(posedge tx_device_clk_1)  
  begin
    if (tx_device_clk_aresetn == 1'b0 || cnt_reset == 1'b1)
      mem_xfer_tx_upload_tvalid_256b_cnt_r   <= 32'h0;
    else if (mem_xfer_tx_upload_tvalid_256b == 1'b1 && mem_xfer_tx_upload_tready_256b == 1'b1)
      mem_xfer_tx_upload_tvalid_256b_cnt_r   <= mem_xfer_tx_upload_tvalid_256b_cnt_r + 1;
  end

  always @(posedge tx_device_clk_1)  
  begin
    if (tx_device_clk_aresetn == 1'b0 || cnt_reset == 1'b1)
      dac_tvalid_256b_cnt_r   <= 32'h0;
    else if (dac_tvalid_256b_pipe == 1'b1 && dac_tready_256b_pipe == 1'b1)
      dac_tvalid_256b_cnt_r   <= dac_tvalid_256b_cnt_r + 1;
  end

////////////////////////
  always @(posedge tx_device_clk_1)  
  begin
    if (tx_device_clk_aresetn == 1'b0 || cnt_reset == 1'b1)
      cmac_rx_tvalid_256b_cnt_r   <= 32'h0;
    else if (cmac_rx_tvalid_256b == 1'b1 && cmac_rx_tready_256b_i == 1'b1)
      cmac_rx_tvalid_256b_cnt_r   <= cmac_rx_tvalid_256b_cnt_r + 1;
  end

  always @(posedge tx_device_clk_1)  
  begin
    if (tx_device_clk_aresetn == 1'b0 || cnt_reset == 1'b1)
      cmac_0_rx_tvalid_512b_cnt_r   <= 32'h0;
    else if (cmac_0_rx_tvalid_512b_en == 1'b1 && cmac_0_rx_tready_512b_en == 1'b1)
      cmac_0_rx_tvalid_512b_cnt_r   <= cmac_0_rx_tvalid_512b_cnt_r + 1;
  end

  always @(posedge tx_device_clk_1)  
  begin
    if (tx_device_clk_aresetn == 1'b0 || cnt_reset == 1'b1)
      cmac_4_rx_tvalid_512b_cnt_r   <= 32'h0;
    else if (cmac_4_rx_tvalid_512b_en == 1'b1 && cmac_4_rx_tready_512b_en == 1'b1)
      cmac_4_rx_tvalid_512b_cnt_r   <= cmac_4_rx_tvalid_512b_cnt_r + 1;
  end


////////////////////////
  always @(posedge rx_device_clk_1)  
  begin
    if (rx_device_clk_aresetn == 1'b0 || cnt_reset == 1'b1)
      adc_tvalid_256b_cnt_r   <= 32'h0;
    else if (adc_tvalid_256b == 1'b1)
      adc_tvalid_256b_cnt_r   <= adc_tvalid_256b_cnt_r + 1;
  end

  always @(posedge rx_device_clk_1)  
  begin
    if (rx_device_clk_aresetn == 1'b0 || cnt_reset == 1'b1)
      cmac_0_tx_tvalid_512b_cnt_r   <= 32'h0;
    else if (cmac_0_tx_tvalid_512b_en == 1'b1 && cmac_0_tx_tready_512b_en == 1'b1)
      cmac_0_tx_tvalid_512b_cnt_r   <= cmac_0_tx_tvalid_512b_cnt_r + 1;
  end

  always @(posedge rx_device_clk_1)  
  begin
    if (rx_device_clk_aresetn == 1'b0 || cnt_reset == 1'b1)
      cmac_4_tx_tvalid_512b_cnt_r   <= 32'h0;
    else if (cmac_4_tx_tvalid_512b_en == 1'b1 && cmac_4_tx_tready_512b_en == 1'b1)
      cmac_4_tx_tvalid_512b_cnt_r   <= cmac_4_tx_tvalid_512b_cnt_r + 1;
  end

//////////////////////////
  si5332_wrapper i_si5332_wrapper ( 
    .clk_100_in                               (clk_100),
    .clk_100_areset_in                        (clk_100_areset),

    .sda_in                                   (sda_i),                
    .sda_out                                  (sda_o),                
    .sda_t_out                                (sda_t),                

    .scl_in                                   (scl_i),
    .scl_out                                  (scl_o),
    .scl_t_out                                (scl_t)
    );

  IOBUF i_scl_iobuf (
    .O                                        (scl_i),
    .I                                        (scl_o),
    .IO                                       (pll_scl),
    .T                                        (scl_t)
    );

  IOBUF  i_sda_iobuf (
    .O                                        (sda_i),
    .I                                        (sda_o),
    .IO                                       (pll_sda),
    .T                                        (sda_t)
    );


endmodule
