
//-----------------------------------------------------------------------------
//
// (c) Copyright 2009-2010 Xilinx, Inc. All rights reserved.
//
// This file contains confidential and proprietary information
// of Xilinx, Inc. and is protected under U.S. and
// international copyright and other intellectual property
// laws.
//
// DISCLAIMER
// This disclaimer is not a license and does not grant any
// rights to the materials distributed herewith. Except as
// otherwise provided in a valid license issued to you by
// Xilinx, and to the maximum extent permitted by applicable
// law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
// WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
// AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
// BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
// INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
// (2) Xilinx shall not be liable (whether in contract or tort,
// including negligence, or under any other theory of
// liability) for any loss or damage of any kind or nature
// related to, arising under or in connection with these
// materials, including for any direct, or any indirect,
// special, incidental, or consequential loss or damage
// (including loss of data, profits, goodwill, or any type of
// loss or damage suffered as a result of any action brought
// by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the
// possibility of the same.
//
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-
// safe, or for use in any application requiring fail-safe
// performance, such as life-support or safety devices or
// systems, Class III medical devices, nuclear facilities,
// applications related to the deployment of airbags, or any
// other applications that could lead to death, personal
// injury, or severe property or environmental damage
// (individually and collectively, "Critical
// Applications"). Customer assumes the sole risk and
// liability of any use of Xilinx products in Critical
// Applications, subject only to applicable laws and
// regulations governing limitations on product liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
// PART OF THIS FILE AT ALL TIMES.
//
//-----------------------------------------------------------------------------
// Project    : V5-Block Plus for PCI Express
// File       : pcie_gt_wrapper.v
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//
//   ____  ____
//  /   /\/   /
// /___/  \  /    Vendor      : Xilinx
// \   \   \/     Version     : 1.6
//  \   \         Application : Generated by Xilinx PCI Express Wizard
//  /   /         Filename    : pcie_gt_wrapper.v
// /___/   /\     Module      : pcie_gt_wrapper
// \   \  /  \
//  \___\/\___\
//
//------------------------------------------------------------------------------
//
//  Description : Wrapper for Rocket IO GTP Transceivers 
//  
//-----------------------------------------------------------------------------  
`timescale 1ns/1ns
module pcie_gt_wrapper #
   (
     parameter NO_OF_LANES = 8,
     parameter SIM = 0,
     parameter PLL_DIVSEL_FB = 5,
     parameter PLL_DIVSEL_REF = 2,
     parameter CLK25_DIVIDER = 4,
     parameter TXDIFFBOOST = "TRUE"
   )  
   (
      //RX signals
      output  wire   [7:0]                gt_rx_elec_idle,
      output  wire   [23:0]               gt_rx_status,
      output  wire   [63:0]               gt_rx_data,
      output  wire   [7:0]                gt_rx_phy_status,
      output  wire   [7:0]                gt_rx_data_k,
      output  wire   [7:0]                gt_rx_valid,
      output  wire   [7:0]                gt_rx_chanisaligned,
      input   wire   [NO_OF_LANES-1:0]    gt_rx_n,     
      input   wire   [NO_OF_LANES-1:0]    gt_rx_p,     
      
      //TX signals
      output  wire   [NO_OF_LANES-1:0]    gt_tx_n,     
      output  wire   [NO_OF_LANES-1:0]    gt_tx_p,     
      input   wire   [63:0]               gt_tx_data,
      input   wire   [7:0]                gt_tx_data_k,
      input   wire   [7:0]                gt_tx_elec_idle,
      input   wire   [7:0]                gt_tx_detect_rx_loopback,
      input   wire   [7:0]                gt_tx_compliance,
      input   wire   [7:0]                gt_rx_polarity,
      input   wire   [15:0]               gt_power_down,
      input   wire   [7:0]                gt_deskew_lanes,
      input   wire   [7:0]                gt_pipe_reset,
      input   wire   [7:0]                gt_rx_present,
      
      //Reset signals
      input   wire                        gsr,
      input   wire                        gtreset,
      input   wire                        clock_lock,
      //Refclk signals 
      input   wire                        refclk,
      output  wire                        refclkout_bufg,
      output  wire                        gtclk_bufg,
      output  wire  [7:0]                 resetdone,
      output  wire  [3:0]                 plllkdet_out,
      input   wire                        gt_usrclk,
      output  wire  [7:0]                 rxbyteisaligned,
      output  wire  [7:0]                 rxchanbondseq,

      output  wire                        pcie_reset,
      
      //Dynamic reconfiguration port (DRP)
      input   wire                        gt_dclk,
      input   wire   [NO_OF_LANES*7-1:0]  gt_daddr,
      input   wire   [NO_OF_LANES-1:0]    gt_den,
      input   wire   [NO_OF_LANES-1:0]    gt_dwen,
      input   wire   [NO_OF_LANES*16-1:0] gt_di,
      output  wire   [NO_OF_LANES*16-1:0] gt_do,
      output  wire   [NO_OF_LANES-1:0]    gt_drdy,

      input   wire   [2:0]                gt_txdiffctrl_0,
      input   wire   [2:0]                gt_txdiffctrl_1,
      input   wire   [2:0]                gt_txbuffctrl_0,
      input   wire   [2:0]                gt_txbuffctrl_1,
      input   wire   [2:0]                gt_txpreemphesis_0,
      input   wire   [2:0]                gt_txpreemphesis_1
   );


/************************** Start of GT instantiation *************************/

     //Signal declaration
     wire [NO_OF_LANES-1:0] gt_clk;
     wire [NO_OF_LANES-1:0] gt_refclk_out;
     wire [7:0] gt_rx_enchansync  = 8'h01;
     
     
     wire [2:0] gt_rx_chbond_i [8:0];
     wire [2:0] gt_rx_chbond_o [8:0];
       
     wire [7:0] float_rx_data_k = 8'b0;
     wire [63:0] float_rx_data = 64'b0;
     
     
     wire [7:0] GT_TXN,GT_RXN;
     wire [7:0] GT_TXP,GT_RXP;
     wire [7:0] rTXN;
     wire [7:0] rTXP;
     
     wire [7:0] gt_rx_elec_idle_reset;
     wire [3:0] gt_rx_en_elec_idle_resetb;

     wire [63:0]   gt_rx_data_reg;
     wire [7:0]    gt_rx_data_k_reg;
     wire [7:0]    gt_rx_valid_reg;
     wire [7:0]    gt_rx_elec_idle_reg;
     wire [23:0]   gt_rx_status_reg;
     wire [7:0]    gt_rx_phy_status_reg;
     wire [7:0]    gt_rx_chanisaligned_reg;
     wire  [7:0]    gt_pipe_reset_reg;
     wire  [15:0]   gt_rx_power_down_reg;
     wire  [7:0]    gt_rx_polarity_reg;
     wire [63:0]   gt_tx_data_reg;              
     wire [7:0]    gt_tx_data_k_reg;            
     wire [7:0]    gt_tx_elec_idle_reg;         
     wire [7:0]    gt_tx_detect_rx_loopback_reg;
     wire [7:0]    gt_tx_compliance_reg;        
     wire [15:0]   gt_tx_power_down_reg;

     reg [7:0]     one  = 8'hff;
     reg [63:0]    zero = 63'h0000000000000000;

     wire rst_init = gt_pipe_reset_reg[0];
     wire  rxreset_i; // connect to RXRESET of the GT inputs 
     reg  rxreset;  
     reg  m1_delayed_elec_idle_reset;
     reg  m2_delayed_elec_idle_reset;
     reg  delayed_elec_idle_reset;
    

//////////////////////////////////////////////////////////
// Flop Locations for GT TX signals
// Registering TX side signals
/////////////////////////////////////////////////////////

     genvar a;
     generate
     for ( a=0; a < NO_OF_LANES ; a=a+1)
     begin: flop 
     
     FD tx_data0 ( .Q (gt_tx_data_reg[8*a+0]), .D (gt_tx_data[8*a+0]), .C(gt_usrclk));
     FD tx_data1 ( .Q (gt_tx_data_reg[8*a+1]), .D (gt_tx_data[8*a+1]), .C(gt_usrclk));
     FD tx_data2 ( .Q (gt_tx_data_reg[8*a+2]), .D (gt_tx_data[8*a+2]), .C(gt_usrclk));
     FD tx_data3 ( .Q (gt_tx_data_reg[8*a+3]), .D (gt_tx_data[8*a+3]), .C(gt_usrclk));
     FD tx_data4 ( .Q (gt_tx_data_reg[8*a+4]), .D (gt_tx_data[8*a+4]), .C(gt_usrclk));
     FD tx_data5 ( .Q (gt_tx_data_reg[8*a+5]), .D (gt_tx_data[8*a+5]), .C(gt_usrclk));
     FD tx_data6 ( .Q (gt_tx_data_reg[8*a+6]), .D (gt_tx_data[8*a+6]), .C(gt_usrclk));
     FD tx_data7 ( .Q (gt_tx_data_reg[8*a+7]), .D (gt_tx_data[8*a+7]), .C(gt_usrclk));
     
     FD tx_data_k    ( .Q (gt_tx_data_k_reg[a]),     .D (gt_tx_data_k[a]),     .C(gt_usrclk));
     
     FDCP #(.INIT(1'b1)) tx_elec_idle  ( .Q (gt_tx_elec_idle_reg[a]),  .D (gt_tx_elec_idle[a]),  .C(gt_usrclk), .CLR(1'b0), .PRE(~clock_lock));
     
     FD tx_compliance( .Q (gt_tx_compliance_reg[a]), .D (gt_tx_compliance[a]), .C(gt_usrclk));
        
     FD tx_detect_rx_loopback ( .Q (gt_tx_detect_rx_loopback_reg[a]), .D (gt_tx_detect_rx_loopback[a]), .C(gt_usrclk));

     FDCP #(.INIT(1'b1)) tx_power_down0 ( .Q (gt_tx_power_down_reg[2*a+0]),  .D (gt_power_down[2*a+0]),  .C(gt_usrclk), .CLR(1'b0), .PRE(~clock_lock));
     FDCP #(.INIT(1'b0)) tx_power_down1 ( .Q (gt_tx_power_down_reg[2*a+1]),  .D (gt_power_down[2*a+1]),  .C(gt_usrclk), .CLR(~clock_lock), .PRE(1'b0));

     FDCP #(.INIT(1'b1)) rx_power_down0 ( .Q (gt_rx_power_down_reg[2*a+0]),  .D (gt_power_down[2*a+0]),  .C(gt_usrclk), .CLR(1'b0), .PRE(~clock_lock));
     FDCP #(.INIT(1'b0)) rx_power_down1 ( .Q (gt_rx_power_down_reg[2*a+1]),  .D (gt_power_down[2*a+1]),  .C(gt_usrclk), .CLR(~clock_lock), .PRE(1'b0));

     FD rx_polarity      ( .Q (gt_rx_polarity_reg[a]),   .D (gt_rx_polarity[a]),   .C(gt_usrclk));
  
     FDCP #(.INIT(1'b1)) reset          ( .Q (gt_pipe_reset_reg[a]),    .D (gt_pipe_reset[a]),    .C(gt_usrclk), .CLR(1'b0), .PRE(~clock_lock));

     FD rx_data_0        ( .Q (gt_rx_data[8*a+0]),    .D (gt_rx_data_reg[8*a+0]),     .C(gt_usrclk));
     FD rx_data_1        ( .Q (gt_rx_data[8*a+1]),    .D (gt_rx_data_reg[8*a+1]),     .C(gt_usrclk));
     FD rx_data_2        ( .Q (gt_rx_data[8*a+2]),    .D (gt_rx_data_reg[8*a+2]),     .C(gt_usrclk));
     FD rx_data_3        ( .Q (gt_rx_data[8*a+3]),    .D (gt_rx_data_reg[8*a+3]),     .C(gt_usrclk));
     FD rx_data_4        ( .Q (gt_rx_data[8*a+4]),    .D (gt_rx_data_reg[8*a+4]),     .C(gt_usrclk));
     FD rx_data_5        ( .Q (gt_rx_data[8*a+5]),    .D (gt_rx_data_reg[8*a+5]),     .C(gt_usrclk));
     FD rx_data_6        ( .Q (gt_rx_data[8*a+6]),    .D (gt_rx_data_reg[8*a+6]),     .C(gt_usrclk));
     FD rx_data_7        ( .Q (gt_rx_data[8*a+7]),    .D (gt_rx_data_reg[8*a+7]),     .C(gt_usrclk));

     FD rx_data_k        ( .Q (gt_rx_data_k[a]),      .D (gt_rx_data_k_reg[a]),       .C(gt_usrclk));

     FDCP #(.INIT(1'b1)) rx_elec_idle   ( .Q (gt_rx_elec_idle[a]),   .D (gt_rx_elec_idle_reg[a]),    .C(gt_usrclk), .CLR(1'b0), .PRE(~clock_lock));
     FD rx_valid         ( .Q (gt_rx_valid[a]),       .D (gt_rx_valid_reg[a]),        .C(gt_usrclk));

     FDCP #(.INIT(1'b1)) rx_phy_status  ( .Q (gt_rx_phy_status[a]),    .D (gt_rx_phy_status_reg[a]),      .C(gt_usrclk), .CLR(1'b0), .PRE(~clock_lock));
     FD rx_chanisaligned ( .Q (gt_rx_chanisaligned[a]), .D (gt_rx_chanisaligned_reg[a]),   .C(gt_usrclk));

     FD rx_status_0      ( .Q (gt_rx_status[3*a+0]),  .D (gt_rx_status_reg[3*a+0]),   .C(gt_usrclk));
     FD rx_status_1      ( .Q (gt_rx_status[3*a+1]),  .D (gt_rx_status_reg[3*a+1]),   .C(gt_usrclk));
     FD rx_status_2      ( .Q (gt_rx_status[3*a+2]),  .D (gt_rx_status_reg[3*a+2]),   .C(gt_usrclk));


    end
    endgenerate
   
    genvar b;
    generate
    for (b=NO_OF_LANES; b < 8; b=b+1) 
    begin: tied_off   
        assign gt_tx_data_reg[8*b+7:8*b+0]          = 8'b0;
        assign gt_tx_data_k_reg[b]                  = 1'b0;
        assign gt_tx_elec_idle_reg[b]               = 1'b1;
        assign gt_tx_detect_rx_loopback_reg[b]      = 1'b0;
        assign gt_tx_compliance_reg[b]              = 1'b0;
        assign gt_tx_power_down_reg[2*b+1:2*b+0]    = 2'b0;
        assign gt_rx_power_down_reg[2*b+1:2*b+0]    = 2'b0;
        assign gt_pipe_reset_reg[b]                 = 1'b0;
        assign gt_rx_polarity_reg[b]                = 1'b0;

        assign gt_rx_data[8*b+7:8*b+0]              = 8'b0;
        assign gt_rx_data_k[b]                      = 1'b0;
        assign gt_rx_valid[b]                       = 1'b0;   
        assign gt_rx_elec_idle[b]                   = 1'b1;
        assign gt_rx_status[3*b+2:3*b]              = 3'b0;   
        assign gt_rx_phy_status[b]                  = 1'b0;
        assign gt_rx_chanisaligned[b]               = 1'b0;

    end
    endgenerate         



     assign rTXN = GT_TXN;
     assign rTXP = GT_TXP;
         
     assign gt_tx_n = rTXN[(NO_OF_LANES-1):0];
     assign gt_tx_p = rTXP[(NO_OF_LANES-1):0];
     
     assign GT_RXN[(NO_OF_LANES-1):0] = gt_rx_n;
     assign GT_RXP[(NO_OF_LANES-1):0] = gt_rx_p;
    
     BUFG bufg1 (.I(gt_clk[0]),        .O(gtclk_bufg));
     BUFG bufg2 (.I(gt_refclk_out[0]), .O(refclkout_bufg));

    
// Channel bonding settings. These settings should be changed
// based on how the GTs are daisy chained. For more imformation on channel 
// bonding please refer to the V5 Rocket I/O Transceiver User Guide 

     assign gt_rx_chbond_i[0] = 3'b0;

     genvar c;
     generate
     for ( c=0; c <= NO_OF_LANES-1 ; c=c+1)
     begin:  ch_bond
          assign gt_rx_chbond_i[c+1] = (NO_OF_LANES == 1)? 3'b0 : gt_rx_chbond_o[c];
     end
     endgenerate
   

wire TXENPMAPHASEALIGN;
wire TXPMASETPHASE;
reg  ignore_resetdone = 1'b0;
wire tx_sync_reset;
reg  resetdone_reg = 1'b0;
wire sync_done;
reg rst_pcie = 1'b1;
reg [2:0] rstdone_cnt = 3'b000;
reg       mgt_txreset;
reg [1:0] mgt_txreset_cnt;

     genvar i;   
     generate 
        for (i=0; i < NO_OF_LANES; i= i+2)
           begin: GTD
              GTP_DUAL #
           
               (
                  .SIM_MODE                   ("FAST"                  ),
                  .SIM_RECEIVER_DETECT_PASS0  ("TRUE"                  ),
                  .SIM_RECEIVER_DETECT_PASS1  ("TRUE"                  ),
                  .SIM_GTPRESET_SPEEDUP       (1                       ),
                  .AC_CAP_DIS_0               ("FALSE"                 ),
                  .AC_CAP_DIS_1               ("FALSE"                 ),
                  .ALIGN_COMMA_WORD_0         (1                       ),
                  .ALIGN_COMMA_WORD_1         (1                       ),
                  .CHAN_BOND_1_MAX_SKEW_0     (7                       ),
                  .CHAN_BOND_1_MAX_SKEW_1     (7                       ),
                  .CHAN_BOND_2_MAX_SKEW_0     (7                       ),
                  .CHAN_BOND_2_MAX_SKEW_1     (7                       ),
                  .CHAN_BOND_LEVEL_0          (NO_OF_LANES==1?0:NO_OF_LANES-(i+1)),
                  .CHAN_BOND_LEVEL_1          (NO_OF_LANES==1?0:NO_OF_LANES-(i+2)),
                  .CHAN_BOND_MODE_0           (NO_OF_LANES==1?"OFF":(i==0)?"MASTER":"SLAVE"),
                  .CHAN_BOND_MODE_1           (NO_OF_LANES==1?"OFF":"SLAVE"),
                  .CHAN_BOND_SEQ_2_USE_0      ("TRUE"                  ),
                  .CHAN_BOND_SEQ_2_USE_1      ("TRUE"                  ),
                  .CHAN_BOND_SEQ_LEN_0        (4                       ),
                  .CHAN_BOND_SEQ_LEN_1        (4                       ),
                  .CLK25_DIVIDER              (CLK25_DIVIDER           ),
                  .CLKINDC_B                  ("TRUE"                  ),
                  .CLK_CORRECT_USE_0          ("TRUE"                  ),
                  .CLK_CORRECT_USE_1          ("TRUE"                  ),
                  .CLK_COR_ADJ_LEN_0          (1                       ),
                  .CLK_COR_ADJ_LEN_1          (1                       ),
                  .CLK_COR_DET_LEN_0          (1                       ),
                  .CLK_COR_DET_LEN_1          (1                       ),
                  .CLK_COR_INSERT_IDLE_FLAG_0 ("FALSE"                 ),
                  .CLK_COR_INSERT_IDLE_FLAG_1 ("FALSE"                 ),
                  .CLK_COR_KEEP_IDLE_0        ("FALSE"                 ),
                  .CLK_COR_KEEP_IDLE_1        ("FALSE"                 ),
                  .CLK_COR_MAX_LAT_0          (18                      ),
                  .CLK_COR_MAX_LAT_1          (18                      ),
                  .CLK_COR_MIN_LAT_0          (16                      ),
                  .CLK_COR_MIN_LAT_1          (16                      ),
                  .CLK_COR_PRECEDENCE_0       ("TRUE"                  ),
                  .CLK_COR_PRECEDENCE_1       ("TRUE"                  ),
                  .CLK_COR_REPEAT_WAIT_0      (5                       ),
                  .CLK_COR_REPEAT_WAIT_1      (5                       ),
                  .CLK_COR_SEQ_2_USE_0        ("FALSE"                 ),
                  .CLK_COR_SEQ_2_USE_1        ("FALSE"                 ),
                  .COMMA_DOUBLE_0             ("FALSE"                 ),
                  .COMMA_DOUBLE_1             ("FALSE"                 ),
                  .DEC_MCOMMA_DETECT_0        ("TRUE"                  ),
                  .DEC_MCOMMA_DETECT_1        ("TRUE"                  ),
                  .DEC_PCOMMA_DETECT_0        ("TRUE"                  ),
                  .DEC_PCOMMA_DETECT_1        ("TRUE"                  ),
                  .DEC_VALID_COMMA_ONLY_0     ("TRUE"                  ),
                  .DEC_VALID_COMMA_ONLY_1     ("TRUE"                  ),
                  .MCOMMA_DETECT_0            ("TRUE"                  ),
                  .MCOMMA_DETECT_1            ("TRUE"                  ),
                  .OOB_CLK_DIVIDER            (4                       ),
                  .OVERSAMPLE_MODE            ("FALSE"                 ),
                  .PCI_EXPRESS_MODE_0         ("TRUE"                  ),
                  .PCI_EXPRESS_MODE_1         ("TRUE"                  ),
                  .PCOMMA_DETECT_0            ("TRUE"                  ),
                  .PCOMMA_DETECT_1            ("TRUE"                  ),
                  .PLL_DIVSEL_FB              (PLL_DIVSEL_FB           ),
                  .PLL_DIVSEL_REF             (PLL_DIVSEL_REF          ),
                  .PLL_RXDIVSEL_OUT_0         (1                       ),
                  .PLL_RXDIVSEL_OUT_1         (1                       ),
                  .PLL_SATA_0                 ("FALSE"                 ),
                  .PLL_SATA_1                 ("FALSE"                 ),
                  .PLL_TXDIVSEL_COMM_OUT      (1                       ),
                  .PLL_TXDIVSEL_OUT_0         (1                       ),
                  .PLL_TXDIVSEL_OUT_1         (1                       ),
                  
                  .RCV_TERM_GND_0             ("TRUE"                  ),
                  .RCV_TERM_GND_1             ("TRUE"                  ),
                  .RCV_TERM_MID_0             ("TRUE"                  ),
                  .RCV_TERM_MID_1             ("TRUE"                  ),
                  .RCV_TERM_VTTRX_0           ("FALSE"                 ),
                  .RCV_TERM_VTTRX_1           ("FALSE"                 ),
                  .RX_BUFFER_USE_0            ("TRUE"                  ),
                  .RX_BUFFER_USE_1            ("TRUE"                  ),
                  .RX_DECODE_SEQ_MATCH_0      ("TRUE"                  ),
                  .RX_DECODE_SEQ_MATCH_1      ("TRUE"                  ),
                  .RX_LOSS_OF_SYNC_FSM_0      ("FALSE"                 ),
                  .RX_LOSS_OF_SYNC_FSM_1      ("FALSE"                 ),
                  .RX_LOS_INVALID_INCR_0      (8                       ),
                  .RX_LOS_INVALID_INCR_1      (8                       ),
                  .RX_LOS_THRESHOLD_0         (128                     ),
                  .RX_LOS_THRESHOLD_1         (128                     ),
                  .RX_SLIDE_MODE_0            ("PCS"                   ),
                  .RX_SLIDE_MODE_1            ("PCS"                   ),
                  .RX_STATUS_FMT_0            ("PCIE"                  ),
                  .RX_STATUS_FMT_1            ("PCIE"                  ),
                  .RX_XCLK_SEL_0              ("RXREC"                 ),
                  .RX_XCLK_SEL_1              ("RXREC"                 ),
                  .SATA_MAX_BURST_0           (7                       ),
                  .SATA_MAX_BURST_1           (7                       ),
                  .SATA_MAX_INIT_0            (22                      ),
                  .SATA_MAX_INIT_1            (22                      ),
                  .SATA_MAX_WAKE_0            (7                       ),
                  .SATA_MAX_WAKE_1            (7                       ),
                  .SATA_MIN_BURST_0           (4                       ),
                  .SATA_MIN_BURST_1           (4                       ),
                  .SATA_MIN_INIT_0            (12                      ),
                  .SATA_MIN_INIT_1            (12                      ),
                  .SATA_MIN_WAKE_0            (4                       ),
                  .SATA_MIN_WAKE_1            (4                       ),
                  .TERMINATION_IMP_0          (50                      ),
                  .TERMINATION_IMP_1          (50                      ),
                  .TERMINATION_OVRD           ("FALSE"                 ),
                  .TX_BUFFER_USE_0            ("TRUE"                 ),
                  .TX_BUFFER_USE_1            ("TRUE"                 ),
                  .TX_DIFF_BOOST_0            (TXDIFFBOOST             ), //TRUE
                  .TX_DIFF_BOOST_1            (TXDIFFBOOST             ), //TRUE
                  .TX_SYNC_FILTERB            (1                       ),
                  .TX_XCLK_SEL_0              ("TXOUT"                 ),
                  .TX_XCLK_SEL_1              ("TXOUT"                 ),
                  .CHAN_BOND_SEQ_1_1_0        (10'b0001001010          ), //D10.2 (end TS1)
                  .CHAN_BOND_SEQ_1_1_1        (10'b0001001010          ), //D10.2 (end TS1)
                  .CHAN_BOND_SEQ_1_2_0        (10'b0001001010          ), //D10.2 (end TS1)
                  .CHAN_BOND_SEQ_1_2_1        (10'b0001001010          ), //D10.2 (end TS1)
                  .CHAN_BOND_SEQ_1_3_0        (10'b0001001010          ), //D10.2 (end TS1)
                  .CHAN_BOND_SEQ_1_3_1        (10'b0001001010          ), //D10.2 (end TS1)
                  .CHAN_BOND_SEQ_1_4_0        (10'b0110111100          ), //K28.5 (COM)
                  .CHAN_BOND_SEQ_1_4_1        (10'b0110111100          ), //K28.5 (COM)
                  .CHAN_BOND_SEQ_1_ENABLE_0   (4'b1111                 ), //Look for 4 byte seq
                  .CHAN_BOND_SEQ_1_ENABLE_1   (4'b1111                 ), //Look for 4 byte seq
                  .CHAN_BOND_SEQ_2_1_0        (10'b0100111100          ), //K28.1 (FTS)
                  .CHAN_BOND_SEQ_2_1_1        (10'b0100111100          ), //K28.1 (FTS)
                  .CHAN_BOND_SEQ_2_2_0        (10'b0100111100          ), //K28.1 (FTS)
                  .CHAN_BOND_SEQ_2_2_1        (10'b0100111100          ), //K28.1 (FTS)
                  .CHAN_BOND_SEQ_2_3_0        (10'b0110111100          ), //K28.5 (COM)
                  .CHAN_BOND_SEQ_2_3_1        (10'b0110111100          ), //K28.5 (COM)
                  .CHAN_BOND_SEQ_2_4_0        (10'b0100011100          ), //K28.0 (SKP)
                  .CHAN_BOND_SEQ_2_4_1        (10'b0100011100          ), //K28.0 (SKP)
                  .CHAN_BOND_SEQ_2_ENABLE_0   (4'b1111                 ), //Look for 4 byte seq
                  .CHAN_BOND_SEQ_2_ENABLE_1   (4'b1111                 ), //Look for 4 byte seq
                  .CLK_COR_SEQ_1_1_0          (10'b0100011100          ), //K28.0 (SKP)
                  .CLK_COR_SEQ_1_1_1          (10'b0100011100          ), //K28.0 (SKP)
                  .CLK_COR_SEQ_1_2_0          (10'b0000000000          ),
                  .CLK_COR_SEQ_1_2_1          (10'b0000000000          ),
                  .CLK_COR_SEQ_1_3_0          (10'b0000000000          ),
                  .CLK_COR_SEQ_1_3_1          (10'b0000000000          ),
                  .CLK_COR_SEQ_1_4_0          (10'b0000000000          ),
                  .CLK_COR_SEQ_1_4_1          (10'b0000000000          ),
                  .CLK_COR_SEQ_1_ENABLE_0     (4'b1111                 ),
                  .CLK_COR_SEQ_1_ENABLE_1     (4'b1111                 ),
                  .CLK_COR_SEQ_2_1_0          (10'b0000000000          ),
                  .CLK_COR_SEQ_2_1_1          (10'b0000000000          ),
                  .CLK_COR_SEQ_2_2_0          (10'b0000000000          ),
                  .CLK_COR_SEQ_2_2_1          (10'b0000000000          ),
                  .CLK_COR_SEQ_2_3_0          (10'b0000000000          ),
                  .CLK_COR_SEQ_2_3_1          (10'b0000000000          ),
                  .CLK_COR_SEQ_2_4_0          (10'b0000000000          ),
                  .CLK_COR_SEQ_2_4_1          (10'b0000000000          ),
                  .CLK_COR_SEQ_2_ENABLE_0     (4'b1111                 ),
                  .CLK_COR_SEQ_2_ENABLE_1     (4'b1111                 ),
                  .COMMA_10B_ENABLE_0         (10'b1111111111          ),
                  .COMMA_10B_ENABLE_1         (10'b1111111111          ),
                  .COM_BURST_VAL_0            (4'b1111                 ),
                  .COM_BURST_VAL_1            (4'b1111                 ),
                  .MCOMMA_10B_VALUE_0         (10'b1010000011          ),
                  .MCOMMA_10B_VALUE_1         (10'b1010000011          ),
                  .OOBDETECT_THRESHOLD_0      (3'b010                  ),
                  .OOBDETECT_THRESHOLD_1      (3'b010                  ),
                  .PCOMMA_10B_VALUE_0         (10'b0101111100          ),
                  .PCOMMA_10B_VALUE_1         (10'b0101111100          ),
                  .PCS_COM_CFG                ( (PLL_DIVSEL_FB == 1)? 28'h1680a07 : 28'h1680a0e ),
                  .PMA_CDR_SCAN_0             (27'h6C07640             ),
                  .PMA_CDR_SCAN_1             (27'h6C07640             ),
                  .PMA_RX_CFG_0               (25'h09F0089             ),
                  .PMA_RX_CFG_1               (25'h09F0089             ),
                  .PRBS_ERR_THRESHOLD_0       (32'h00000001            ),
                  .PRBS_ERR_THRESHOLD_1       (32'h00000001            ),
                  .SATA_BURST_VAL_0           (3'b100                  ),
                  .SATA_BURST_VAL_1           (3'b100                  ),
                  .SATA_IDLE_VAL_0            (3'b011                  ),
                  .SATA_IDLE_VAL_1            (3'b011                  ),
                  .TERMINATION_CTRL           (5'b10100                ),
                  .TRANS_TIME_FROM_P2_0       (16'h003C                ),
                  .TRANS_TIME_FROM_P2_1       (16'h003C                ),
                  .TRANS_TIME_NON_P2_0        (16'h0019                ),
                  .TRANS_TIME_NON_P2_1        (16'h0019                ),
                  .TRANS_TIME_TO_P2_0         (16'h0064                ),
                  .TRANS_TIME_TO_P2_1         (16'h0064                ),
                  .TXRX_INVERT_0              (5'b00000                ),
                  .TXRX_INVERT_1              (5'b00000                )
                  
                  
              )   
              
              GT_i(
              // GT_DUAL outputs
              .DO(gt_do[16*i+15:16*i]),
              .DRDY(gt_drdy[i]),
              .PHYSTATUS0(gt_rx_phy_status_reg[i+0]),
              .PHYSTATUS1(gt_rx_phy_status_reg[i+1]),
              .PLLLKDET(plllkdet_out[i/2]),
              .REFCLKOUT(gt_refclk_out[i]), 
              .RESETDONE0(resetdone[i]),
              .RESETDONE1(resetdone[i+1]),
              .RXBUFSTATUS0(),
              .RXBUFSTATUS1(),
              .RXBYTEISALIGNED0(rxbyteisaligned[i]),
              .RXBYTEISALIGNED1(rxbyteisaligned[i+1]),
              .RXBYTEREALIGN0(),
              .RXBYTEREALIGN1(),
              .RXCHANBONDSEQ0(rxchanbondseq[i]),
              .RXCHANBONDSEQ1(rxchanbondseq[i+1]),
              .RXCHANISALIGNED0(gt_rx_chanisaligned_reg[i+0]),
              .RXCHANISALIGNED1(gt_rx_chanisaligned_reg[i+1]),
              .RXCHANREALIGN0(),
              .RXCHANREALIGN1(),
              .RXCHARISCOMMA0(),
              .RXCHARISCOMMA1(),
              .RXCHARISK0({float_rx_data_k[i+0],gt_rx_data_k_reg[i+0]}),
              .RXCHARISK1({float_rx_data_k[i+1],gt_rx_data_k_reg[i+1]}),
              .RXCHBONDO0(gt_rx_chbond_o[i]),   
              .RXCHBONDO1(gt_rx_chbond_o[i+1]),
              .RXCLKCORCNT0(),
              .RXCLKCORCNT1(),
              .RXCOMMADET0(),
              .RXCOMMADET1(),
              .RXDATA0({float_rx_data[8*i+7:8*i],gt_rx_data_reg[8*i+7:8*i]}),
              .RXDATA1({float_rx_data[8*i+15:8*i+8],gt_rx_data_reg[8*i+15:8*i+8]}),
              .RXDISPERR0(),
              .RXDISPERR1(),
              .RXELECIDLE0(gt_rx_elec_idle_reg[i+0]),
              .RXELECIDLE1(gt_rx_elec_idle_reg[i+1]),
              .RXLOSSOFSYNC0(),
              .RXLOSSOFSYNC1(),
              .RXNOTINTABLE0(),
              .RXNOTINTABLE1(),
              .RXOVERSAMPLEERR0(),
              .RXOVERSAMPLEERR1(),
              .RXPRBSERR0(),
              .RXPRBSERR1(),
              .RXRECCLK0(),
              .RXRECCLK1(),
              .RXRUNDISP0(),
              .RXRUNDISP1(),
              .RXSTATUS0(gt_rx_status_reg[3*i+2:3*i]),
              .RXSTATUS1(gt_rx_status_reg[3*i+5:3*i+3]),
              .RXVALID0(gt_rx_valid_reg[i+0]),
              .RXVALID1(gt_rx_valid_reg[i+1]),
              .TXBUFSTATUS0(),
              .TXBUFSTATUS1(),
              .TXKERR0(),
              .TXKERR1(),
              .TXN0(GT_TXN[i+0]),
              .TXN1(GT_TXN[i+1]),
              .TXOUTCLK0(gt_clk[i]),
              .TXOUTCLK1(),
              .TXP0(GT_TXP[i+0]),
              .TXP1(GT_TXP[i+1]),
              .TXRUNDISP0(),
              .TXRUNDISP1(),
              // GT_DUAL inputs
              .CLKIN(refclk),
              .DADDR(gt_daddr[7*i+6:7*i]),
              .DCLK(gt_dclk),
              .DEN(gt_den[i]),
              .DI(gt_di[16*i+15:16*i]),
              .DWE(gt_dwen[i]),
              .GTPRESET(gtreset),
              .INTDATAWIDTH(1'b1),
              .LOOPBACK0(3'b000),
              .LOOPBACK1( (NO_OF_LANES == 1) ?  3'b010 : 3'b000),
              .PLLLKDETEN(1'b1),
              .PLLPOWERDOWN(1'b0),
              .PRBSCNTRESET0(1'b0),
              .PRBSCNTRESET1(1'b0),
              .REFCLKPWRDNB(1'b1),
              .RXBUFRESET0(1'b0),
              .RXBUFRESET1(1'b0),
              .RXCDRRESET0(gt_pipe_reset_reg[i+0] & ~rst_pcie),
              .RXCDRRESET1(gt_pipe_reset_reg[i+1] & ~rst_pcie),
              .RXCHBONDI0(gt_rx_chbond_i[i]),
              .RXCHBONDI1(gt_rx_chbond_i[i+1]),
              .RXCOMMADETUSE0(1'b1),
              .RXCOMMADETUSE1(1'b1),
              .RXDATAWIDTH0(1'b0),
              .RXDATAWIDTH1(1'b0),
              .RXDEC8B10BUSE0(1'b1),
              .RXDEC8B10BUSE1(1'b1),
              .RXENCHANSYNC0(gt_rx_enchansync[i]),
              .RXENCHANSYNC1(gt_rx_enchansync[i+1]),
              .RXENEQB0(1'b1),
              .RXENEQB1(1'b1),
              .RXENMCOMMAALIGN0(1'b1),
              .RXENMCOMMAALIGN1(1'b1),
              .RXENPCOMMAALIGN0(1'b1),
              .RXENPCOMMAALIGN1(1'b1),
              .RXENPRBSTST0(2'b00),
              .RXENPRBSTST1(2'b00),
              .RXENSAMPLEALIGN0(1'b0),
              .RXENSAMPLEALIGN1(1'b0),
              .RXEQMIX0(2'b01),
              .RXEQMIX1(2'b01),
              .RXEQPOLE0(4'b0000),
              .RXEQPOLE1(4'b0000),
              .RXN0(GT_RXN[i+0]),
              .RXN1(GT_RXN[i+1]),
              .RXP0(GT_RXP[i+0]),
              .RXP1(GT_RXP[i+1]),
              .RXPMASETPHASE0(1'b0),
              .RXPMASETPHASE1(1'b0),
              .RXPOLARITY0(gt_rx_polarity_reg[i+0]),
              .RXPOLARITY1(gt_rx_polarity_reg[i+1]),
              .RXPOWERDOWN0(gt_rx_power_down_reg[2*i+1:2*i]),
              .RXPOWERDOWN1(gt_rx_power_down_reg[2*i+3:2*i+2]),
              .RXRESET0(rxreset_i & ~rst_pcie),
              .RXRESET1(rxreset_i & ~rst_pcie),
              .RXSLIDE0(1'b0),
              .RXSLIDE1(1'b0),
              .RXUSRCLK0(gt_usrclk),
              .RXUSRCLK1(gt_usrclk),
              .RXUSRCLK20(gt_usrclk),
              .RXUSRCLK21(gt_usrclk),

              .RXELECIDLERESET0(gt_rx_elec_idle_reset[i]),   
              .RXELECIDLERESET1(gt_rx_elec_idle_reset[i+1]), 
              .RXENELECIDLERESETB(gt_rx_en_elec_idle_resetb[i/2]), 
                   
              
              .TXBUFDIFFCTRL0(gt_txbuffctrl_0), //3'b100
              .TXBUFDIFFCTRL1(gt_txbuffctrl_1), //3'b100
              .TXBYPASS8B10B0(2'b00),
              .TXBYPASS8B10B1(2'b00),
              .TXCHARDISPMODE0({1'b0,gt_tx_compliance_reg[i+0]}),
              .TXCHARDISPMODE1({1'b0,gt_tx_compliance_reg[i+1]}),
              .TXCHARDISPVAL0(2'b00),
              .TXCHARDISPVAL1(2'b00),
              .TXCHARISK0({1'b0,gt_tx_data_k_reg[i+0]}),
              .TXCHARISK1({1'b0,gt_tx_data_k_reg[i+1]}),
              .TXCOMSTART0(1'b0),
              .TXCOMSTART1(1'b0),
              .TXCOMTYPE0(1'b0),
              .TXCOMTYPE1(1'b0),
              .TXDATA0({8'b0,gt_tx_data_reg[8*i+7:8*i]}),
              .TXDATA1({8'b0,gt_tx_data_reg[8*i+15:8*i+8]}),
              .TXDATAWIDTH0(1'b0),
              .TXDATAWIDTH1(1'b0),
              .TXDETECTRX0(gt_tx_detect_rx_loopback_reg[i+0]),
              .TXDETECTRX1(gt_tx_detect_rx_loopback_reg[i+1]),
              .TXDIFFCTRL0(gt_txdiffctrl_0), //3'b100
              .TXDIFFCTRL1(gt_txdiffctrl_1), //3'b100
              .TXELECIDLE0(gt_tx_elec_idle_reg[i+0]),
              .TXELECIDLE1(gt_tx_elec_idle_reg[i+1]),
              .TXENC8B10BUSE0(1'b1),
              .TXENC8B10BUSE1(1'b1),
              .TXENPMAPHASEALIGN(TXENPMAPHASEALIGN),
              .TXENPRBSTST0(2'b00),
              .TXENPRBSTST1(2'b00),
              .TXINHIBIT0(1'b0),
              .TXINHIBIT1(1'b0),
              .TXPMASETPHASE(TXPMASETPHASE),
              .TXPOLARITY0(1'b0),
              .TXPOLARITY1(1'b0),
              .TXPOWERDOWN0(gt_tx_power_down_reg[2*i+1:2*i]),
              .TXPOWERDOWN1(gt_tx_power_down_reg[2*i+3:2*i+2]),
              .TXPREEMPHASIS0(gt_txpreemphesis_0), //3'b111
              .TXPREEMPHASIS1(gt_txpreemphesis_1), //3'b111
              .TXRESET0(mgt_txreset & ~rst_pcie),
              .TXRESET1(mgt_txreset & ~rst_pcie),
              .TXUSRCLK0(gt_usrclk), 
              .TXUSRCLK1(gt_usrclk),
              .TXUSRCLK20(gt_usrclk),
              .TXUSRCLK21(gt_usrclk),
           
              .GTPTEST(4'b0)
              );             

           end
     endgenerate


   //---------------------------- TOGGLE TXRESET ------------------------------
   always @(posedge gt_usrclk)
   begin
      if (sync_done)
      begin
         if (mgt_txreset_cnt < 2'b11)
         begin
            mgt_txreset      <= 1'b1;
            mgt_txreset_cnt  <= mgt_txreset_cnt + 1;
         end
         else
            mgt_txreset      <= 1'b0;
      end
      else
      begin
         mgt_txreset         <= 1'b0;
         mgt_txreset_cnt     <= 2'b0;
      end
   end





    //---------------------------- TXSYNC module ------------------------------
    // The TXSYNC module performs phase synchronization for all the active TX datapaths. It
    // waits for the user clocks to be stable, then drives the phase align signals on each
    // GTP. When phase synchronization is complete, it asserts SYNC_DONE
    
    // Include the TX_SYNC module in your own design to perform phase synchronization if
    // your protocol bypasses the TX Buffers
    
    TX_SYNC_GTP tile0_txsync_i 
    (
        .TXENPMAPHASEALIGN(TXENPMAPHASEALIGN),
        .TXPMASETPHASE(TXPMASETPHASE),
        .SYNC_DONE(sync_done),
        .USER_CLK(gt_usrclk),
        .RESET(tx_sync_reset)
        //.RESET(~resetdone[0])

    );


    always @ (posedge gt_usrclk or posedge gtreset) begin
        if (gtreset === 1'b1 ) begin
            rst_pcie <=  1'b1;
        end else if (sync_done === 1'b1) begin
            rst_pcie <=  1'b0;
        end else begin
            rst_pcie <=  1'b1;
        end
    end

    assign tx_sync_reset = (pcie_reset == 1'b1) ? (~clock_lock) : 1'b0;
    assign pcie_reset = rst_pcie; 
  

///////////////////////////////////////////////////////////////////////////////////////////
// Logic for enabling L0s state
///////////////////////////////////////////////////////////////////////////////////////////

      
    always @(posedge gt_usrclk or posedge rst_init) begin
        if (rst_init) begin
          m1_delayed_elec_idle_reset <= 1'b0;
          m2_delayed_elec_idle_reset <= 1'b0;
          delayed_elec_idle_reset    <= 1'b0;
          rxreset <= 1'b0;
        end else begin
          // synchronize elec_idle_reset
          m1_delayed_elec_idle_reset <= gt_rx_elec_idle_reset[0];
          m2_delayed_elec_idle_reset <= m1_delayed_elec_idle_reset;
          delayed_elec_idle_reset    <= m2_delayed_elec_idle_reset;
          // create a one-cycle pulse on rxreset
          rxreset <= ~m2_delayed_elec_idle_reset & delayed_elec_idle_reset;
        end
    end
 
    assign rxreset_i = rxreset;

// Latch for CDRRESET for L0s 
     wire [7:0]        icdrreset;
     reg  [7:0]        cdrreset = 0;
     
     generate 
        genvar j;
          for (j=0; j < 8; j= j+1)
             begin: gen_cdrreset
             
                if (j < NO_OF_LANES) begin: for_GT
                   assign icdrreset[j] = resetdone[j] & gt_rx_elec_idle_reg[j];
                   
                   always @( icdrreset or gt_rx_valid_reg) begin : yes_latch
                       if ( icdrreset[j] & ~ gt_rx_valid_reg[j] ) begin
                           cdrreset[j] <= #50 1'b1;
                       end else if ( ~ icdrreset[j] ) begin
                           cdrreset[j] <= #50 1'b0;
                       end
                   end
                   
                   assign gt_rx_elec_idle_reset[j] = cdrreset[j];
                
                end else begin : for_tieoff
                   assign icdrreset[j] = 1'b0;
                   
                   //synthesis translate_off
                   initial cdrreset[j] <= 1'b0;
                   //synthesis translate_on
                   
                   assign gt_rx_elec_idle_reset[j] = 1'b0;
                end
             end
     endgenerate
     
     generate 
        genvar k;
          for (k=0; k < 8; k= k+2)
             begin: gen_resetb
                assign gt_rx_en_elec_idle_resetb[k/2] = ~ ( cdrreset[k] | cdrreset[k+1]);
             end
     endgenerate
   
///////////////////////////////////////////////////////////////////////////////////////////  
// Tying off signals on unused lanes
///////////////////////////////////////////////////////////////////////////////////////////
  
     generate
         if (NO_OF_LANES == 1 || NO_OF_LANES == 2) begin : laneslt4
           assign plllkdet_out[3:1] = 3'b0;
         end else if (NO_OF_LANES == 4) begin : laneseq4
           assign plllkdet_out[3:2] = 2'b0;
         end
      endgenerate


endmodule
