module axi_basic_top #(
  parameter C_DATA_WIDTH  = 128,          // RX/TX interface data width
  parameter C_FAMILY      = "X7",         // Targeted FPGA family
  parameter C_ROOT_PORT   = "FALSE",      // PCIe block is in root port mode
  parameter C_PM_PRIORITY = "FALSE",      // Disable TX packet boundary thrtl
  parameter TCQ = 1,                      // Clock to Q time

  // Do not override parameters below this line
  parameter REM_WIDTH  = (C_DATA_WIDTH == 128) ? 2 : 1, // trem/rrem width
  parameter KEEP_WIDTH = C_DATA_WIDTH / 8               // KEEP width
  ) (
  //---------------------------------------------//
  // User Design I/O                             //
  //---------------------------------------------//

  // AXI TX
  //-----------
  input   [C_DATA_WIDTH-1:0] s_axis_tx_tdata,        // TX data from user
  input                      s_axis_tx_tvalid,       // TX data is valid
  output                     s_axis_tx_tready,       // TX ready for data
  input     [KEEP_WIDTH-1:0] s_axis_tx_tkeep,        // TX strobe byte enables
  input                      s_axis_tx_tlast,        // TX data is last
  input                [3:0] s_axis_tx_tuser,        // TX user signals

  // AXI RX
  //-----------
  output  [C_DATA_WIDTH-1:0] m_axis_rx_tdata,        // RX data to user
  output                     m_axis_rx_tvalid,       // RX data is valid
  input                      m_axis_rx_tready,       // RX ready for data
  output    [KEEP_WIDTH-1:0] m_axis_rx_tkeep,        // RX strobe byte enables
  output                     m_axis_rx_tlast,        // RX data is last
  output              [21:0] m_axis_rx_tuser,        // RX user signals

  // User Misc.
  //-----------
  input                      user_turnoff_ok,        // Turnoff OK from user
  input                      user_tcfg_gnt,          // Send cfg OK from user

  //---------------------------------------------//
  // PCIe Block I/O                              //
  //---------------------------------------------//

  // TRN TX
  //-----------
  output [C_DATA_WIDTH-1:0] trn_td,                  // TX data from block
  output                    trn_tsof,                // TX start of packet
  output                    trn_teof,                // TX end of packet
  output                    trn_tsrc_rdy,            // TX source ready
  input                     trn_tdst_rdy,            // TX destination ready
  output                    trn_tsrc_dsc,            // TX source discontinue
  output    [REM_WIDTH-1:0] trn_trem,                // TX remainder
  output                    trn_terrfwd,             // TX error forward
  output                    trn_tstr,                // TX streaming enable
  input               [5:0] trn_tbuf_av,             // TX buffers available
  output                    trn_tecrc_gen,           // TX ECRC generate

  // TRN RX
  //-----------
  input  [C_DATA_WIDTH-1:0] trn_rd,                  // RX data from block
  input                     trn_rsof,                // RX start of packet
  input                     trn_reof,                // RX end of packet
  input                     trn_rsrc_rdy,            // RX source ready
  output                    trn_rdst_rdy,            // RX destination ready
  input                     trn_rsrc_dsc,            // RX source discontinue
  input     [REM_WIDTH-1:0] trn_rrem,                // RX remainder
  input                     trn_rerrfwd,             // RX error forward
  input               [6:0] trn_rbar_hit,            // RX BAR hit
  input                     trn_recrc_err,           // RX ECRC error

  // TRN Misc.
  //-----------
  input                     trn_tcfg_req,            // TX config request
  output                    trn_tcfg_gnt,            // RX config grant
  input                     trn_lnk_up,              // PCIe link up

  // 7 Series/Virtex6 PM
  //-----------
  input               [2:0] cfg_pcie_link_state,     // Encoded PCIe link state

  // Virtex6 PM
  //-----------
  input                     cfg_pm_send_pme_to,      // PM send PME turnoff msg
  input               [1:0] cfg_pmcsr_powerstate,    // PMCSR power state
  input              [31:0] trn_rdllp_data,          // RX DLLP data
  input                     trn_rdllp_src_rdy,       // RX DLLP source ready

  // Virtex6/Spartan6 PM
  //-----------
  input                     cfg_to_turnoff,          // Turnoff request
  output                    cfg_turnoff_ok,          // Turnoff grant

  // System
  //-----------
  output              [2:0] np_counter,              // Non-posted counter
  input                     user_clk,                // user clock from block
  input                     user_rst                 // user reset from block
);


//---------------------------------------------//
// RX Data Pipeline                            //
//---------------------------------------------//

axi_basic_rx #(
  .C_DATA_WIDTH( C_DATA_WIDTH ),
  .C_FAMILY( C_FAMILY ),

  .TCQ( TCQ ),
  .REM_WIDTH( REM_WIDTH ),
  .KEEP_WIDTH( KEEP_WIDTH )
) rx_inst (

  // Outgoing AXI TX
  //-----------
  .m_axis_rx_tdata( m_axis_rx_tdata ),
  .m_axis_rx_tvalid( m_axis_rx_tvalid ),
  .m_axis_rx_tready( m_axis_rx_tready ),
  .m_axis_rx_tkeep( m_axis_rx_tkeep ),
  .m_axis_rx_tlast( m_axis_rx_tlast ),
  .m_axis_rx_tuser( m_axis_rx_tuser ),

  // Incoming TRN RX
  //-----------
  .trn_rd( trn_rd ),
  .trn_rsof( trn_rsof ),
  .trn_reof( trn_reof ),
  .trn_rsrc_rdy( trn_rsrc_rdy ),
  .trn_rdst_rdy( trn_rdst_rdy ),
  .trn_rsrc_dsc( trn_rsrc_dsc ),
  .trn_rrem( trn_rrem ),
  .trn_rerrfwd( trn_rerrfwd ),
  .trn_rbar_hit( trn_rbar_hit ),
  .trn_recrc_err( trn_recrc_err ),

  // System
  //-----------
  .np_counter( np_counter ),
  .user_clk( user_clk ),
  .user_rst( user_rst )
);



//---------------------------------------------//
// TX Data Pipeline                            //
//---------------------------------------------//

axi_basic_tx #(
  .C_DATA_WIDTH( C_DATA_WIDTH ),
  .C_FAMILY( C_FAMILY ),
  .C_ROOT_PORT( C_ROOT_PORT ),
  .C_PM_PRIORITY( C_PM_PRIORITY ),

  .TCQ( TCQ ),
  .REM_WIDTH( REM_WIDTH ),
  .KEEP_WIDTH( KEEP_WIDTH )
) tx_inst (

  // Incoming AXI RX
  //-----------
  .s_axis_tx_tdata( s_axis_tx_tdata ),
  .s_axis_tx_tvalid( s_axis_tx_tvalid ),
  .s_axis_tx_tready( s_axis_tx_tready ),
  .s_axis_tx_tkeep( s_axis_tx_tkeep ),
  .s_axis_tx_tlast( s_axis_tx_tlast ),
  .s_axis_tx_tuser( s_axis_tx_tuser ),

  // User Misc.
  //-----------
  .user_turnoff_ok( user_turnoff_ok ),
  .user_tcfg_gnt( user_tcfg_gnt ),

  // Outgoing TRN TX
  //-----------
  .trn_td( trn_td ),
  .trn_tsof( trn_tsof ),
  .trn_teof( trn_teof ),
  .trn_tsrc_rdy( trn_tsrc_rdy ),
  .trn_tdst_rdy( trn_tdst_rdy ),
  .trn_tsrc_dsc( trn_tsrc_dsc ),
  .trn_trem( trn_trem ),
  .trn_terrfwd( trn_terrfwd ),
  .trn_tstr( trn_tstr ),
  .trn_tbuf_av( trn_tbuf_av ),
  .trn_tecrc_gen( trn_tecrc_gen ),

  // TRN Misc.
  //-----------
  .trn_tcfg_req( trn_tcfg_req ),
  .trn_tcfg_gnt( trn_tcfg_gnt ),
  .trn_lnk_up( trn_lnk_up ),

  // 7 Series/Virtex6 PM
  //-----------
  .cfg_pcie_link_state( cfg_pcie_link_state ),

  // Virtex6 PM
  //-----------
  .cfg_pm_send_pme_to( cfg_pm_send_pme_to ),
  .cfg_pmcsr_powerstate( cfg_pmcsr_powerstate ),
  .trn_rdllp_data( trn_rdllp_data ),
  .trn_rdllp_src_rdy( trn_rdllp_src_rdy ),

  // Spartan6 PM
  //-----------
  .cfg_to_turnoff( cfg_to_turnoff ),
  .cfg_turnoff_ok( cfg_turnoff_ok ),

  // System
  //-----------
  .user_clk( user_clk ),
  .user_rst( user_rst )
);

endmodule