module sv_xcvr_data_adapter #(

     parameter lanes             = 1,         //Number of lanes chosen by user. legal value: 1+

     parameter channel_interface = 0,         //legal value: (0,1) 1-Enable channel reconfiguration

     parameter ser_base_factor   = 8,         // (8,10)

     parameter ser_words         = 1,         // (1,2,4)

     parameter skip_word         = 1          // (1,2)

) (

     input   wire    [(channel_interface? 44: ser_base_factor*ser_words)*lanes-1:0]   tx_parallel_data,

     input   wire    [ser_words*lanes                 -1:0]   tx_datak,

     input   tri0    [ser_words*lanes                 -1:0]   tx_forcedisp,

     input   wire    [ser_words*lanes                 -1:0]   tx_dispval,



     output  tri0    [64*lanes                        -1:0]   tx_datain_from_pld,

     input   tri0    [64*lanes                        -1:0]   rx_dataout_to_pld,

     output  wire    [(channel_interface? 64: ser_base_factor*ser_words)*lanes-1:0]   rx_parallel_data,

     output  wire    [ser_words*lanes                 -1:0]   rx_datak,

     output  wire    [ser_words*lanes                 -1:0]   rx_errdetect,

     output  wire    [ser_words*lanes                 -1:0]   rx_syncstatus,

     output  wire    [ser_words*lanes                 -1:0]   rx_disperr,

     output  wire    [ser_words*lanes                 -1:0]   rx_patterndetect,

     output  wire    [ser_words*lanes                 -1:0]   rx_rmfifodatainserted,

     output  wire    [ser_words*lanes                 -1:0]   rx_rmfifodatadeleted,

     output  wire    [ser_words*lanes                 -1:0]   rx_runningdisp,

     output  wire    [ser_words*lanes                 -1:0]   rx_a1a2sizeout

);



 localparam tx_data_bundle_size = 11; // TX PLD to PCS interface groups data and control in 11-bit bundles

 localparam rx_data_bundle_size = 16; // RX PCS to PLD interface groups data and status in 16-bit bundles

 

 generate begin         

    genvar num_ch;

    genvar num_word;

    for (num_ch=0; num_ch < lanes; num_ch = num_ch + 1) begin:channel

    

      if (channel_interface == 0) begin

        for (num_word=0; num_word < ser_words; num_word=num_word+1) begin:word

          //***************************************************************

          //*********************** TX assignments ************************

          //With 8B/10B enabled, Tx datain from PLD to PCS has 8-bit data + 3 controls in 11-bit bundles

          //For 1 lane, [7:0] = data

            //              [8] = k char

            //              [9] = force disparity

            //             [10] = disparity value (Tx Elec Idle for PIPE Gen1 & 2)

     

          assign tx_datain_from_pld[64*num_ch+num_word*tx_data_bundle_size*skip_word +: ser_base_factor] = tx_parallel_data[ser_base_factor*ser_words*num_ch+num_word*ser_base_factor +: ser_base_factor];

        

          if (ser_base_factor == 8) begin

            assign tx_datain_from_pld[64*num_ch+num_word*tx_data_bundle_size*skip_word +  8] = tx_datak        [ser_words*num_ch+num_word];

            assign tx_datain_from_pld[64*num_ch+num_word*tx_data_bundle_size*skip_word +  9] = tx_forcedisp    [ser_words*num_ch+num_word];  

            assign tx_datain_from_pld[64*num_ch+num_word*tx_data_bundle_size*skip_word + 10] = tx_dispval      [ser_words*num_ch+num_word];

          end

          

          //***************************************************************

          //*********************** RX assignments ************************

            //With 8B/10B enabled, Rx dataout from PCS to PLD has 8-bit data + 8 controls in 16-bit bundles

            //For 1 lane, [7:0] = data

            //              [8] = k char

            //              [9] = code violation

            //             [10] = word aligner status

            //             [11] = disparity error

            //             [12] = pattern detect  

            //          [14:13] = rate match FIFO status

            //             [15] = running disparity   

               

          assign rx_parallel_data[ser_base_factor*ser_words*num_ch+num_word*ser_base_factor +: ser_base_factor]

                                                            = rx_dataout_to_pld[64*num_ch+num_word*rx_data_bundle_size*skip_word +: ser_base_factor];

          assign rx_datak        [ser_words*num_ch+num_word]  = rx_dataout_to_pld[64*num_ch+num_word*rx_data_bundle_size*skip_word +  8]; 

          assign rx_errdetect    [ser_words*num_ch+num_word]  = rx_dataout_to_pld[64*num_ch+num_word*rx_data_bundle_size*skip_word +  9];

          assign rx_syncstatus   [ser_words*num_ch+num_word]  = rx_dataout_to_pld[64*num_ch+num_word*rx_data_bundle_size*skip_word + 10];

          assign rx_disperr      [ser_words*num_ch+num_word]  = rx_dataout_to_pld[64*num_ch+num_word*rx_data_bundle_size*skip_word + 11];

          assign rx_patterndetect[ser_words*num_ch+num_word]  = rx_dataout_to_pld[64*num_ch+num_word*rx_data_bundle_size*skip_word + 12];

          // rate-match FIFO status is encoded as 2 bits at offsets 13,14 within a bundle

          // 00: Normal data, 01: Deletion, 10: Insertion (or Underflow with 9'h1FE or 9'h1F7), 11: Overflow

          assign rx_rmfifodatainserted[ser_words*num_ch+num_word]  =    rx_dataout_to_pld[64*num_ch+num_word*rx_data_bundle_size*skip_word + 14]

                                                                   & ~rx_dataout_to_pld[64*num_ch+num_word*rx_data_bundle_size*skip_word + 13];

          assign rx_rmfifodatadeleted [ser_words*num_ch+num_word]  =   ~rx_dataout_to_pld[64*num_ch+num_word*rx_data_bundle_size*skip_word + 14]

                                                                   &  rx_dataout_to_pld[64*num_ch+num_word*rx_data_bundle_size*skip_word + 13];



          assign rx_runningdisp   [ser_words*num_ch+num_word] = rx_dataout_to_pld[64*num_ch+num_word*rx_data_bundle_size*skip_word + 15];

          assign rx_a1a2sizeout   [ser_words*num_ch+num_word] = rx_dataout_to_pld[64*num_ch+num_word*rx_data_bundle_size*skip_word +  8];

        end //for word

      end

      else begin

        assign tx_datain_from_pld [64*num_ch    +: 44] = tx_parallel_data [44*num_ch +: 44];

        assign tx_datain_from_pld [64*num_ch+44 +: 20] = {20{1'b0}};

        assign rx_parallel_data   [64*num_ch    +: 64] = rx_dataout_to_pld[64*num_ch +: 64];

        // Drive unused outputs

        assign rx_datak               =  {(ser_words*lanes){1'b0}};

        assign rx_errdetect           =  {(ser_words*lanes){1'b0}};

        assign rx_syncstatus          =  {(ser_words*lanes){1'b0}};

        assign rx_disperr             =  {(ser_words*lanes){1'b0}};

        assign rx_patterndetect       =  {(ser_words*lanes){1'b0}};

        assign rx_rmfifodatainserted  =  {(ser_words*lanes){1'b0}};

        assign rx_rmfifodatadeleted   =  {(ser_words*lanes){1'b0}};

        assign rx_runningdisp         =  {(ser_words*lanes){1'b0}};

        assign rx_a1a2sizeout         =  {(ser_words*lanes){1'b0}};

      end

    end //for channel   

  end

 endgenerate

endmodule