Commit c4c7e576 authored by Alexey Grebenkin's avatar Alexey Grebenkin
Browse files

Ability to bypass aligner and 8/10 enc/dec added, flexible widths support

parent 9aabc22e
Loading
Loading
Loading
Loading
+251 −136

File changed.

Preview size limit exceeded, changes collapsed.

+0 −2
Original line number Diff line number Diff line
@@ -613,7 +613,6 @@ gtxe2_chnl #(

    .RX_DATA_WIDTH          (RX_DATA_WIDTH),
    .RX_INT_DATAWIDTH       (RX_INT_DATAWIDTH),
    .PRX8B10BEN             (1),

    .DEC_MCOMMA_DETECT      (DEC_MCOMMA_DETECT),
    .DEC_PCOMMA_DETECT      (DEC_PCOMMA_DETECT),
@@ -627,7 +626,6 @@ gtxe2_chnl #(

    .TX_DATA_WIDTH          (TX_DATA_WIDTH),
    .TX_INT_DATAWIDTH       (TX_INT_DATAWIDTH),
    .PTX8B10BEN             (1),

    .SATA_BURST_SEQ_LEN     (SATA_BURST_SEQ_LEN)
)
+0 −4
Original line number Diff line number Diff line
@@ -156,11 +156,9 @@ parameter RXOUT_DIV = 2;

parameter   integer TX_INT_DATAWIDTH    = 0;
parameter   integer TX_DATA_WIDTH       = 20;
parameter   integer PTX8B10BEN           = 1;

parameter   integer RX_DATA_WIDTH       = 20;
parameter   integer RX_INT_DATAWIDTH    = 0;
parameter   integer PRX8B10BEN           = 1;

parameter   DEC_MCOMMA_DETECT = "TRUE";
parameter   DEC_PCOMMA_DETECT = "TRUE";
@@ -179,7 +177,6 @@ parameter SATA_CPLL_CFG = "VCO_3000MHZ";
gtxe2_chnl_tx #(
    .TX_DATA_WIDTH      (TX_DATA_WIDTH),
    .TX_INT_DATAWIDTH   (TX_INT_DATAWIDTH),
    .PTX8B10BEN         (PTX8B10BEN),
    .SATA_BURST_SEQ_LEN (SATA_BURST_SEQ_LEN),
    .SATA_CPLL_CFG      (SATA_CPLL_CFG)
)
@@ -217,7 +214,6 @@ tx(
gtxe2_chnl_rx #(
    .RX_DATA_WIDTH          (RX_DATA_WIDTH),
    .RX_INT_DATAWIDTH       (RX_INT_DATAWIDTH),
    .PRX8B10BEN             (PRX8B10BEN),

    .DEC_MCOMMA_DETECT      (DEC_MCOMMA_DETECT),
    .DEC_PCOMMA_DETECT      (DEC_PCOMMA_DETECT),
+72 −44
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
 /**
  * For now contains only deserializer, oob, 10x8 decoder, aligner and polarity invertor blocks
  **/
// TODO resync all output signals
`include "gtxe2_chnl_rx_des.v"
`include "gtxe2_chnl_rx_oob.v"
`include "gtxe2_chnl_rx_10x8dec.v"
@@ -70,7 +71,6 @@ module gtxe2_chnl_rx(

parameter   integer RX_DATA_WIDTH       = 20;
parameter   integer RX_INT_DATAWIDTH    = 0;
parameter   integer PRX8B10BEN           = 1;

parameter   DEC_MCOMMA_DETECT = "TRUE";
parameter   DEC_PCOMMA_DETECT = "TRUE";
@@ -83,27 +83,29 @@ parameter [9:0] ALIGN_COMMA_ENABLE = 10'b1111111111;
parameter           ALIGN_COMMA_DOUBLE  = "FALSE";

function integer calc_idw;
    input   RX8B10BEN;
    input   RX_INT_DATAWIDTH;
    input   RX_DATA_WIDTH;
    input   dummy;
    begin
        if (RX8B10BEN == 1)
        calc_idw = RX_INT_DATAWIDTH == 1 ? 40 : 20;
        else
        begin
            if (RX_INT_DATAWIDTH == 1)
                calc_idw    = RX_DATA_WIDTH == 32 ? 32
                            : RX_DATA_WIDTH == 40 ? 40
                            : RX_DATA_WIDTH == 64 ? 32 : 40;
            else
                calc_idw    = RX_DATA_WIDTH == 16 ? 16  
                            : RX_DATA_WIDTH == 20 ? 20 
                            : RX_DATA_WIDTH == 32 ? 16 : 20;
    end
endfunction

function integer calc_ifdw;
    input   dummy;
    begin
       calc_ifdw = RX_DATA_WIDTH == 16 ? 20 :
                   RX_DATA_WIDTH == 32 ? 40 :
                   RX_DATA_WIDTH == 64 ? 80 : RX_DATA_WIDTH;
    end
endfunction

localparam  internal_data_width = calc_idw(PRX8B10BEN, RX_INT_DATAWIDTH, RX_DATA_WIDTH);
// can be 20 or 40, if it shall be 16 or 32, extra bits wont be used
localparam  internal_data_width     = calc_idw(1);
localparam  interface_data_width    = calc_ifdw(1);
localparam  internal_isk_width      = internal_data_width / 10;
localparam  interface_isk_width     = interface_data_width / 10;
// used in case of TX8B10BEN = 0
localparam  data_width_odd          = RX_DATA_WIDTH == 16 | RX_DATA_WIDTH == 32 | RX_DATA_WIDTH == 64;


// OOB
gtxe2_chnl_rx_oob #(
@@ -131,12 +133,13 @@ assign indata_ser = RXPOLARITY ^ RXP;
// due to non-syntasisable usage, CDR is missing

// deserializer
wire    [internal_data_width - 1:0] parallel_data;
wire    [internal_data_width - 1:0] parallel_data; // in trimmed case highest bites shall be 'x'
gtxe2_chnl_rx_des #(
    .width      (internal_data_width)
)
des(
    .reset      (reset),
    .trim       (data_width_odd & ~RX8B10BEN),
    .inclk      (serial_clk),
    .outclk     (RXUSRCLK),
    .indata     (indata_ser),
@@ -171,12 +174,19 @@ aligner(
    .RXMCOMMAALIGNEN    (RXMCOMMAALIGNEN)
);

wire [data_width - 1:0] internal_data;
wire [isk_width  - 1:0] internal_isk;
localparam  iface_databus_width = interface_data_width * 8 / 10;
localparam  intern_databus_width = internal_data_width * 8 / 10;

wire [intern_databus_width - 1:0] internal_data;
wire [internal_isk_width  - 1:0]  internal_isk;
wire [internal_isk_width  - 1:0]  internal_chariscomma;
wire [internal_isk_width  - 1:0]  internal_notintable;
wire [internal_isk_width  - 1:0]  internal_disperr;
// 10x8 decoder
gtxe2_chnl_rx_10x8dec #(
    .iwidth             (internal_data_width),
    .owidth             (RX_DATA_WIDTH),
    .iskwidth           (internal_isk_width),
    .owidth             (intern_databus_width),
    .DEC_MCOMMA_DETECT  (DEC_MCOMMA_DETECT),
    .DEC_PCOMMA_DETECT  (DEC_PCOMMA_DETECT)
)
@@ -185,43 +195,61 @@ decoder_10x8(
    .rst            (reset),
    .indata         (aligned_data),
    .RX8B10BEN      (RX8B10BEN),
    .data_width_odd (data_width_odd),

    .RXCHARISCOMMA  (RXCHARISCOMMA),
    .RXCHARISK      (internal_isk),
    .RXDISPERR      (RXDISPERR),
    .RXNOTINTABLE   (RXNOTINTABLE),
    .rxchariscomma  (internal_chariscomma),
    .rxcharisk      (internal_isk),
    .rxdisperr      (internal_disperr),
    .rxnotintable   (internal_notintable),

    .outdata        (),
    .RXDATA         (internal_data)
    .outdata        (internal_data)
);

// fit data width
// TODO make parameters awesome
localparam data_width = 16;
localparam if_data_width = 32;
localparam isk_width = 2;
localparam if_isk_width = 4;

localparam outdiv = interface_data_width / internal_data_width;
// if something is written into dataiface_data_in _except_ internal_data and internal_isk => count all extra bits in this parameter
localparam internal_data_extra = 4;
localparam interface_data_extra = outdiv * internal_data_extra;

wire [interface_data_width - 1 + interface_data_extra:0]  dataiface_data_out;
wire [internal_data_width - 1 + internal_data_extra:0]   dataiface_data_in;

assign  dataiface_data_in  = {internal_notintable, internal_chariscomma, internal_disperr, internal_isk, internal_data};

genvar ii;
generate
for (ii = 1; ii < (outdiv + 1); ii = ii + 1)
begin: asdadfdsf
    assign  RXDATA[ii*intern_databus_width - 1 -: intern_databus_width]    = dataiface_data_out[(ii-1)*(internal_data_width + internal_data_extra) + intern_databus_width - 1 -: intern_databus_width];
    assign  RXCHARISK[ii*internal_isk_width - 1 -: internal_isk_width]     = dataiface_data_out[(ii-1)*(internal_data_width + internal_data_extra) + intern_databus_width - 1 + internal_isk_width -: internal_isk_width];
    assign  RXDISPERR[ii*internal_isk_width - 1 -: internal_isk_width]     = dataiface_data_out[(ii-1)*(internal_data_width + internal_data_extra) + intern_databus_width - 1 + internal_isk_width*2 -: internal_isk_width];
    assign  RXCHARISCOMMA[ii*internal_isk_width - 1 -: internal_isk_width] = dataiface_data_out[(ii-1)*(internal_data_width + internal_data_extra) + intern_databus_width - 1 + internal_isk_width*3 -: internal_isk_width];
    assign  RXNOTINTABLE[ii*internal_isk_width - 1 -: internal_isk_width]  = dataiface_data_out[(ii-1)*(internal_data_width + internal_data_extra) + intern_databus_width - 1 + internal_isk_width*4 -: internal_isk_width];
end
endgenerate
assign  RXDATA[63:iface_databus_width]       = {64 - iface_databus_width{1'bx}};
assign  RXDISPERR[7:interface_isk_width]     = {7 - interface_isk_width{1'bx}};
assign  RXCHARISK[7:interface_isk_width]     = {7 - interface_isk_width{1'bx}};
assign  RXCHARISCOMMA[7:interface_isk_width] = {7 - interface_isk_width{1'bx}};
assign  RXNOTINTABLE[7:interface_isk_width]  = {7 - interface_isk_width{1'bx}};

gtxe2_chnl_rx_dataiface #(
    .internal_data_width    (data_width),
    .interface_data_width   (if_data_width),
    .internal_isk_width     (isk_width),
    .interface_isk_width    (if_isk_width)
    .internal_data_width    (internal_data_width + internal_data_extra),
    .interface_data_width   (interface_data_width + interface_data_extra),
    .internal_isk_width     (internal_isk_width),
    .interface_isk_width    (interface_isk_width)
)
dataiface
(
    .usrclk     (RXUSRCLK),
    .usrclk2    (RXUSRCLK2),
    .reset      (reset),
    .indata     (internal_data),
    .inisk      (internal_isk),
    .outdata    (RXDATA[if_data_width - 1:0]),
    .outisk     (RXCHARISK[if_isk_width - 1:0]),
    .indata     (dataiface_data_in),
    .inisk      (internal_isk), // not used actually
    .outdata    (dataiface_data_out),
    .outisk     (),
    .realign    (RXBYTEREALIGN === 1'bx ? 1'b0 : RXBYTEREALIGN)
);

assign  RXDATA[63:if_data_width]    = 0;
assign  RXCHARISK[7:if_isk_width]   = 0;

endmodule
+55 −41
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
// always enabled, wasnt tested with width parameters, disctinct from 20
module gtxe2_chnl_rx_10x8dec #(
    parameter iwidth = 20,
    parameter iskwidth = 2,
    parameter owidth = 20,

    parameter DEC_MCOMMA_DETECT = "TRUE",
@@ -31,16 +32,18 @@ module gtxe2_chnl_rx_10x8dec #(
    input   wire                        rst,
    input   wire    [iwidth - 1:0]      indata,
    input   wire                        RX8B10BEN,
    input   wire                        data_width_odd,

    output  wire    [7:0]           RXCHARISCOMMA,
    output  wire    [7:0]           RXCHARISK,
    output  wire    [7:0]           RXDISPERR,
    output  wire    [7:0]           RXNOTINTABLE,
    output  wire    [iskwidth - 1:0]    rxchariscomma,
    output  wire    [iskwidth - 1:0]    rxcharisk,
    output  wire    [iskwidth - 1:0]    rxdisperr,
    output  wire    [iskwidth - 1:0]    rxnotintable,

    output  wire    [owidth - 1:0]  outdata,
    output  wire    [63:0]          RXDATA
    output  wire    [owidth - 1:0]      outdata
);

wire    [iskwidth - 1:0]    rxcharisk_dec;
wire    [iskwidth - 1:0]    rxdisperr_dec;
wire    [owidth - 1:0]      outdata_dec;

localparam word_count = iwidth / 10;
localparam add_2out_bits = owidth == 20 | owidth == 40 | owidth == 80 ? "TRUE" : "FALSE";
@@ -63,7 +66,7 @@ begin: asdf
    //data = {1'(is in table) + 3'(decoded 4/3) + 1'(is in table) + 5'(decoded 6/5)}

    //6/5 decoding
    assign  data[ii*10+5:ii*10] = RXCHARISK[ii] ? (
    assign  data[ii*10+5:ii*10] = rxcharisk_dec[ii] ? (
                                  indata[ii*10 + 9:ii*10] == 10'b0010111100 | indata[ii*10 + 9:ii*10] == 10'b1101000011 ? 6'b011100 :
                                  indata[ii*10 + 9:ii*10] == 10'b1001111100 | indata[ii*10 + 9:ii*10] == 10'b0110000011 ? 6'b011100 :
                                  indata[ii*10 + 9:ii*10] == 10'b1010111100 | indata[ii*10 + 9:ii*10] == 10'b0101000011 ? 6'b011100 :
@@ -124,7 +127,7 @@ begin: asdf
                                  indata[ii*10 + 5:ii*10] == 6'b011110 | indata[ii*10 + 5:ii*10] == 6'b100001 ? 6'b011110 :*/
                                                                                                                6'b100000); // not in a table
    //4/3 decoding                                                                                                 
    assign  data[ii*10+ 9:ii*10+ 6] = RXCHARISK[ii] ? (
    assign  data[ii*10+ 9:ii*10+ 6] = rxcharisk_dec[ii] ? (
                                      indata[ii*10 + 9:ii*10] == 10'b0010111100 | indata[ii*10 + 9:ii*10] == 10'b1101000011 ? 4'b0000 :
                                      indata[ii*10 + 9:ii*10] == 10'b1001111100 | indata[ii*10 + 9:ii*10] == 10'b0110000011 ? 4'b0001 :
                                      indata[ii*10 + 9:ii*10] == 10'b1010111100 | indata[ii*10 + 9:ii*10] == 10'b0101000011 ? 4'b0010 :
@@ -164,27 +167,38 @@ begin: asdf

    assign  pure_data[ii*8 + 7:ii*8] = {data[ii*10 + 8:ii*10 + 6], data[ii*10 + 4:ii*10]};

    if (add_2out_bits == "TRUE")
        assign  outdata[ii*10 + 9:ii*10]= {RXDISPERR[ii], RXCHARISK[ii], pure_data[ii*8 + 7:ii*8]};
    assign  outdata_dec[ii*8 + 7:ii*8]  = pure_data[ii*8 + 7:ii*8];

    assign  outdata[ii*8 + 7:ii*8]  = RX8B10BEN ? outdata_dec[ii*8 + 7:ii*8]   : ~data_width_odd ? indata[ii*10 + 7:ii*10]  : indata[ii*8 + 7:ii*8];
    assign  rxcharisk[ii]           = RX8B10BEN ? rxcharisk_dec[ii] : ~data_width_odd ? indata[ii*10 + 8]        : 1'bx;
    assign  rxdisperr[ii]           = RX8B10BEN ? rxdisperr_dec[ii] : ~data_width_odd ? indata[ii*10 + 9]        : 1'bx; 
/*    if (RX8B10BEN) begin
    end
    else 
        assign  outdata[ii*8 + 7:ii*8]  = pure_data[ii*8 + 7:ii*8];
    if (data_width_odd) begin
        assign  outdata[ii*8 + 7:ii*8]  = indata[ii*8 + 7:ii*8];
        assign  rxcharisk[ii]           = 1'bx;
        assign  rxdisperr[ii]           = 1'bx; 
    end
    else begin
        assign  outdata[ii*8 + 7:ii*8]  = indata[ii*10 + 7:ii*10];
        assign  rxcharisk[ii]           = indata[ii*10 + 8];
        assign  rxdisperr[ii]           = indata[ii*10 + 9];
    end*/
end
endgenerate

//disperr[ii] = no_disp_word[ii] ? 1'b0 : ~disp_word[ii] ^ disp[ii-1];
//disp[ii] = no_disp_word[ii] ? disp[ii-1] : disp_word[ii]
assign  disp_err = ~no_disp_word & (~disp_word ^ {disp[word_count - 2:0], disp_init});
assign  disp     = ~no_disp_word & disp_word | no_disp_word & {disp[word_count - 2:0], disp_init};


generate 
for (ii = 0; ii < 8; ii = ii + 1)
for (ii = 0; ii < word_count; ii = ii + 1)
begin:dfsga
    assign  RXDATA[ii*8+7:ii*8] = ii >= word_count ? 8'h0 : pure_data[ii*8+7:ii*8];
    assign  RXNOTINTABLE[ii]    = ii >= word_count ? 1'b0 : data[ii*10 + 9] | data[ii*10 + 5];
    assign  rxnotintable[ii]    = ii >= word_count ? 1'b0 : data[ii*10 + 9] | data[ii*10 + 5];

    assign  RXDISPERR[ii]   = ii >= word_count ?  1'b0 : disp_err[ii];
    assign  RXCHARISK[ii]   = ii >= word_count ?  1'b0 :
    assign  rxdisperr_dec[ii]   = ii >= word_count ?  1'b0 : disp_err[ii];
    assign  rxcharisk_dec[ii]   = ii >= word_count ?  1'b0 :
                                                      indata[ii*10 + 9:ii*10] == 10'b0010111100 | indata[ii*10 + 9:ii*10] == 10'b1101000011 |
                                                      indata[ii*10 + 9:ii*10] == 10'b1001111100 | indata[ii*10 + 9:ii*10] == 10'b0110000011 |
                                                      indata[ii*10 + 9:ii*10] == 10'b1010111100 | indata[ii*10 + 9:ii*10] == 10'b0101000011 |
@@ -198,7 +212,7 @@ begin:dfsga
                                                      indata[ii*10 + 9:ii*10] == 10'b0001011101 | indata[ii*10 + 9:ii*10] == 10'b1110100010 |
                                                      indata[ii*10 + 9:ii*10] == 10'b0001011110 | indata[ii*10 + 9:ii*10] == 10'b1110100001;

    assign  RXCHARISCOMMA[ii] = ii >= word_count ?  1'b0 :
    assign  rxchariscomma[ii] = ii >= word_count ?  1'b0 :
                                                   (indata[ii*10 + 9:ii*10] == 10'b1001111100 | 
                                                    indata[ii*10 + 9:ii*10] == 10'b0101111100 | 
                                                    indata[ii*10 + 9:ii*10] == 10'b0001111100) & DEC_PCOMMA_DETECT |
Loading