Commit 7c04cd9c authored by Alexey Grebenkin's avatar Alexey Grebenkin

Initial files with license agreement

parent 10d25413
# gtxe2_nosecureip
GTXE2_CHANNEL_GPL.v is a non-synthesizable open-source replacement for a propriate xilinx's primitive GTXE2_CHANNEL.v
For now only basic features are implemented : OOB, comma aligment, 10-8 encoding/decoding, clocking scheme.
Still, that is enough to run SATA protocol implementation simulation.
This diff is collapsed.
/*******************************************************************************
* Module: clock_divider
* Date: 2015-07-06
* Author: Alexey
* Description: Non-sinthesizable clock divider
*
* Copyright (c) 2015 Elphel, Inc.
* clock_divider.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* clock_divider.v file 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
/**
* Divides input clock either by input 'div' or by parameter 'divide_by' if divide_by_param
* was set to 1
**/
`ifndef CLOCK_DIVIDER_V
`define CLOCK_DIVIDER_V
// non synthesisable!
module clock_divider(
input wire clk_in,
output reg clk_out,
input wire [31:0] div
);
parameter divide_by = 1;
parameter divide_by_param = 1;
reg [31:0] cnt = 0;
reg [31:0] div_r;
initial
begin
cnt = 0;
clk_out = 1'b1;
forever
begin
if (divide_by_param == 0)
begin
if (div > 32'h0)
div_r = div;
else
div_r = 1;
repeat (div_r)
@ (clk_in);
end
else
begin
repeat (divide_by)
@ (clk_in);
end
clk_out = ~clk_out;
end
end
endmodule
`endif
This diff is collapsed.
/*******************************************************************************
* Module: gtxe2_chnl_clocking
* Date: 2015-07-06
* Author: Alexey
* Description: channel's clocking top-level. Places muxes, plls, dividers,
* as they're depicted @ xilinx's ug476 p.36, p.46, p. 150, p. 211
*
* Copyright (c) 2015 Elphel, Inc.
* gtxe2_chnl_clocking.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* gtxe2_chnl_clocking.v file 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
`include "gtxe2_chnl_cpll_inmux.v"
`include "gtxe2_chnl_outclk_mux.v"
`include "gtxe2_chnl_cpll.v"
`include "clock_divider.v"
module gtxe2_chnl_clocking(
// top-level interfaces
input wire [2:0] CPLLREFCLKSEL,
input wire GTREFCLK0,
input wire GTREFCLK1,
input wire GTNORTHREFCLK0,
input wire GTNORTHREFCLK1,
input wire GTSOUTHREFCLK0,
input wire GTSOUTHREFCLK1,
input wire GTGREFCLK,
input wire QPLLCLK,
input wire QPLLREFCLK,
input wire [1:0] RXSYSCLKSEL,
input wire [1:0] TXSYSCLKSEL,
input wire [2:0] TXOUTCLKSEL,
input wire [2:0] RXOUTCLKSEL,
input wire TXDLYBYPASS,
output wire GTREFCLKMONITOR,
input wire CPLLLOCKDETCLK,
input wire CPLLLOCKEN,
input wire CPLLPD,
input wire CPLLRESET,
output wire CPLLFBCLKLOST,
output wire CPLLLOCK,
output wire CPLLREFCLKLOST,
input wire [2:0] TXRATE,
input wire [2:0] RXRATE,
// phy-level interfaces
output wire TXOUTCLKPMA,
output wire TXOUTCLKPCS,
output wire TXOUTCLK,
output wire TXOUTCLKFABRIC,
output wire tx_serial_clk,
output wire tx_piso_clk,
output wire RXOUTCLKPMA,
output wire RXOUTCLKPCS,
output wire RXOUTCLK,
output wire RXOUTCLKFABRIC,
output wire rx_serial_clk,
output wire tx_sipo_clk
);
// CPLL
parameter [23:0] CPLL_CFG = 29'h00BC07DC;
parameter integer CPLL_FBDIV = 4;
parameter integer CPLL_FBDIV_45 = 5;
parameter [23:0] CPLL_INIT_CFG = 24'h00001E;
parameter [15:0] CPLL_LOCK_CFG = 16'h01E8;
parameter integer CPLL_REFCLK_DIV = 1;
parameter SATA_CPLL_CFG = "VCO_3000MHZ";
parameter [1:0] PMA_RSV3 = 1;
parameter TXOUT_DIV = 2;
//parameter TXRATE = 3'b000;
parameter RXOUT_DIV = 2;
//parameter RXRATE = 3'b000;
parameter TX_INT_DATAWIDTH = 0;
parameter TX_DATA_WIDTH = 20;
parameter RX_INT_DATAWIDTH = 0;
parameter RX_DATA_WIDTH = 20;
/*
localparam tx_serial_divider = TXRATE == 3'b001 ? 1
: TXRATE == 3'b010 ? 2
: TXRATE == 3'b011 ? 4
: TXRATE == 3'b100 ? 8
: TXRATE == 3'b101 ? 16 : TXOUT_DIV ;
localparam rx_serial_divider = RXRATE == 3'b001 ? 1
: RXRATE == 3'b010 ? 2
: RXRATE == 3'b011 ? 4
: RXRATE == 3'b100 ? 8
: RXRATE == 3'b101 ? 16 : RXOUT_DIV ;
*/
localparam tx_pma_divider1 = TX_INT_DATAWIDTH == 1 ? 4 : 2;
localparam tx_pcs_divider1 = tx_pma_divider1;
localparam tx_pma_divider2 = TX_DATA_WIDTH == 20 | TX_DATA_WIDTH == 40 | TX_DATA_WIDTH == 80 ? 5 : 4;
localparam tx_pcs_divider2 = tx_pma_divider2;
localparam rx_pma_divider1 = RX_INT_DATAWIDTH == 1 ? 4 : 2;
localparam rx_pma_divider2 = RX_DATA_WIDTH == 20 | RX_DATA_WIDTH == 40 | RX_DATA_WIDTH == 80 ? 5 : 4;
wire clk_mux_out;
wire cpll_clk_out;
wire tx_phy_clk;
wire rx_phy_clk;
wire TXPLLREFCLK_DIV1;
wire TXPLLREFCLK_DIV2;
wire RXPLLREFCLK_DIV1;
wire RXPLLREFCLK_DIV2;
assign tx_phy_clk = TXSYSCLKSEL[0] ? QPLLCLK : cpll_clk_out;
assign TXPLLREFCLK_DIV1 = TXSYSCLKSEL[1] ? QPLLREFCLK : clk_mux_out;
assign rx_phy_clk = RXSYSCLKSEL[0] ? QPLLCLK : cpll_clk_out;
assign RXPLLREFCLK_DIV1 = RXSYSCLKSEL[1] ? QPLLREFCLK : clk_mux_out;
assign tx_serial_clk = tx_phy_clk;
assign rx_serial_clk = rx_phy_clk;
// piso and sipo clocks
// are not used in the design - no need to use ddr mode during simulation. much easier just multi serial clk by 2
wire [31:0] tx_serial_divider;
wire [31:0] rx_serial_divider;
assign tx_serial_divider = TXRATE == 3'b001 ? 1
: TXRATE == 3'b010 ? 2
: TXRATE == 3'b011 ? 4
: TXRATE == 3'b100 ? 8
: TXRATE == 3'b101 ? 16 : TXOUT_DIV ;
assign rx_serial_divider = RXRATE == 3'b001 ? 1
: RXRATE == 3'b010 ? 2
: RXRATE == 3'b011 ? 4
: RXRATE == 3'b100 ? 8
: RXRATE == 3'b101 ? 16 : RXOUT_DIV ;
clock_divider #(
// .divide_by (tx_serial_divider),
.divide_by_param (0)
)
tx_toserialclk_div(
.clk_in (tx_phy_clk),
.clk_out (tx_piso_clk),
.div (tx_serial_divider)
);
clock_divider #(
// .divide_by (rx_serial_divider),
.divide_by_param (0)
)
rx_toserialclk_div(
.clk_in (rx_phy_clk),
.clk_out (rx_sipo_clk),
.div (rx_serial_divider)
);
// TXOUTCLKPCS/TXOUTCLKPMA generation
wire tx_pma_div1_clk;
assign TXOUTCLKPCS = TXOUTCLKPMA;
clock_divider #(
.divide_by (tx_pma_divider1)
)
tx_pma_div1(
.clk_in (tx_piso_clk),
.clk_out (tx_pma_div1_clk)
);
clock_divider #(
.divide_by (tx_pma_divider2)
)
tx_pma_div2(
.clk_in (tx_pma_div1_clk),
.clk_out (TXOUTCLKPMA)
);
// RXOUTCLKPCS/RXOUTCLKPMA generation
wire rx_pma_div1_clk;
assign RXOUTCLKPCS = RXOUTCLKPMA;
clock_divider #(
.divide_by (rx_pma_divider1)
)
rx_pma_div1(
.clk_in (rx_sipo_clk),
.clk_out (rx_pma_div1_clk)
);
clock_divider #(
.divide_by (rx_pma_divider2)
)
rx_pma_div2(
.clk_in (rx_pma_div1_clk),
.clk_out (RXOUTCLKPMA)
);
//
clock_divider #(
.divide_by (2)
)
txpllrefclk_div2(
.clk_in (TXPLLREFCLK_DIV1),
.clk_out (TXPLLREFCLK_DIV2)
);
clock_divider #(
.divide_by (2)
)
rxpllrefclk_div2(
.clk_in (RXPLLREFCLK_DIV1),
.clk_out (RXPLLREFCLK_DIV2)
);
gtxe2_chnl_outclk_mux tx_out_mux(
.TXPLLREFCLK_DIV1 (TXPLLREFCLK_DIV1),
.TXPLLREFCLK_DIV2 (TXPLLREFCLK_DIV2),
.TXOUTCLKPMA (TXOUTCLKPMA),
.TXOUTCLKPCS (TXOUTCLKPCS),
.TXOUTCLKSEL (TXOUTCLKSEL),
.TXDLYBYPASS (TXDLYBYPASS),
.TXOUTCLK (TXOUTCLK)
);
gtxe2_chnl_outclk_mux rx_out_mux(
.TXPLLREFCLK_DIV1 (RXPLLREFCLK_DIV1),
.TXPLLREFCLK_DIV2 (RXPLLREFCLK_DIV2),
.TXOUTCLKPMA (RXOUTCLKPMA),
.TXOUTCLKPCS (RXOUTCLKPCS),
.TXOUTCLKSEL (RXOUTCLKSEL),
.TXDLYBYPASS (RXDLYBYPASS),
.TXOUTCLK (RXOUTCLK)
);
gtxe2_chnl_cpll_inmux clk_mux(
.CPLLREFCLKSEL (CPLLREFCLKSEL),
.GTREFCLK0 (GTREFCLK0),
.GTREFCLK1 (GTREFCLK1),
.GTNORTHREFCLK0 (GTNORTHREFCLK0),
.GTNORTHREFCLK1 (GTNORTHREFCLK1),
.GTSOUTHREFCLK0 (GTSOUTHREFCLK0),
.GTSOUTHREFCLK1 (GTSOUTHREFCLK1),
.GTGREFCLK (GTGREFCLK),
.CPLL_MUX_CLK_OUT (clk_mux_out)
);
gtxe2_chnl_cpll #(
.CPLL_FBDIV (4),
.CPLL_FBDIV_45 (5),
.CPLL_REFCLK_DIV (1)
)
cpll(
.CPLLLOCKDETCLK (CPLLLOCKDETCLK),
.CPLLLOCKEN (CPLLLOCKEN),
.CPLLPD (CPLLPD),
.CPLLRESET (CPLLRESET),
.CPLLFBCLKLOST (CPLLFBCLKLOST),
.CPLLLOCK (CPLLLOCK),
.CPLLREFCLKLOST (CPLLREFCLKLOST),
.GTRSVD (GTRSVD),
.PCSRSVDIN (PCSRSVDIN),
.PCSRSVDIN2 (PCSRSVDIN2),
.PMARSVDIN (PMARSVDIN),
.PMARSVDIN2 (PMARSVDIN2),
.TSTIN (TSTIN),
.TSTOUT (TSTOUT),
.ref_clk (clk_mux_out),
.clk_out (cpll_clk_out),
.pll_locked (pll_locked)
);
endmodule
/*******************************************************************************
* Module: gtxe2_chnl_cpll
* Date: 2015-07-06
* Author: Alexey
* Description: non-synthesizable pll implementation
*
* Copyright (c) 2015 Elphel, Inc.
* gtxe2_chnl_cpll.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* gtxe2_chnl_cpll.v file 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
`include "gtxe2_chnl_cpll_def.v"
module gtxe2_chnl_cpll(
// top-level interfaces
input wire CPLLLOCKDETCLK,
input wire CPLLLOCKEN,
input wire CPLLPD,
input wire CPLLRESET, // active high
output wire CPLLFBCLKLOST,
output wire CPLLLOCK,
output wire CPLLREFCLKLOST,
input wire GTRSVD,
input wire PCSRSVDIN,
input wire PCSRSVDIN2,
input wire PMARSVDIN,
input wire PMARSVDIN2,
input wire TSTIN,
output wire TSTOUT,
// internal
input wire ref_clk,
output wire clk_out,
output wire pll_locked // equals CPLLLOCK
);
parameter [23:0] CPLL_CFG = 29'h00BC07DC;
parameter integer CPLL_FBDIV = 4;
parameter integer CPLL_FBDIV_45 = 5;
parameter [23:0] CPLL_INIT_CFG = 24'h00001E;
parameter [15:0] CPLL_LOCK_CFG = 16'h01E8;
parameter integer CPLL_REFCLK_DIV = 1;
parameter integer RXOUT_DIV = 2;
parameter integer TXOUT_DIV = 2;
parameter SATA_CPLL_CFG = "VCO_3000MHZ";
parameter [1:0] PMA_RSV3 = 1;
localparam multiplier = CPLL_FBDIV * CPLL_FBDIV_45;
localparam divider = CPLL_REFCLK_DIV;
assign pll_locked = locked;
assign CPLLLOCK = pll_locked;
wire fb_clk_out;
wire reset;
reg mult_clk;
reg mult_dev_clk;
assign clk_out = mult_dev_clk;
// generate internal async reset
assign reset = CPLLPD | CPLLRESET;
// apply multipliers
time last_edge; // reference clock edge's absolute time
time period; // reference clock's period
integer locked_f;
reg locked;
initial
begin
last_edge = 0;
period = 0;
forever @ (posedge ref_clk or posedge reset)
begin
period = reset ? 0 : $time - (last_edge == 0 ? $time : last_edge);
last_edge = reset ? 0 : $time;
end
end
reg tmp = 0;
initial
begin
@ (posedge reset);
forever @ (posedge ref_clk)
begin
tmp = ~tmp;
if (period > 0)
begin
locked_f = 1;
mult_clk = 1'b1;
repeat (multiplier * 2 - 1)
begin
#(period/multiplier/2)
mult_clk = ~mult_clk;
end
end
else
locked_f = 0;
end
end
// apply dividers
initial
begin
mult_dev_clk = 1'b1;
forever
begin
repeat (divider)
@ (mult_clk);
mult_dev_clk = ~mult_dev_clk;
end
end
// show if 'pll' is locked
reg [31:0] counter;
always @ (posedge ref_clk or posedge reset)
counter <= reset | locked_f == 0 ? 0 : counter == `GTXE2_CHNL_CPLL_LOCK_TIME ? counter : counter + 1;
always @ (posedge ref_clk)
locked <= counter == `GTXE2_CHNL_CPLL_LOCK_TIME;
/*
always @ (posedge ref_clk or posedge reset)
begin
if (locked_f == 1 && ~reset)
begin
repeat (`GTXE2_CHNL_CPLL_LOCK_TIME) @ (posedge ref_clk);
locked <= 1'b1;
end
else
locked <= 1'b0;
end*/
endmodule
/*******************************************************************************
* Module: gtxe2_chnl_cpll_inmux
* Date: 2015-07-06
* Author: Alexey
* Description: non-sinthesizable clock multiplexer, used in clocking scheme
*
* Copyright (c) 2015 Elphel, Inc.
* gtxe2_chnl_cpll_inmux.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* gtxe2_chnl_cpll_inmux.v file 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
// cpll reference clock mux
module gtxe2_chnl_cpll_inmux(
input wire [2:0] CPLLREFCLKSEL,
input wire GTREFCLK0,
input wire GTREFCLK1,
input wire GTNORTHREFCLK0,
input wire GTNORTHREFCLK1,
input wire GTSOUTHREFCLK0,
input wire GTSOUTHREFCLK1,
input wire GTGREFCLK,
output wire CPLL_MUX_CLK_OUT
);
// clock multiplexer - pre-syntesis simulation only
assign CPLL_MUX_CLK_OUT = CPLLREFCLKSEL == 3'b000 ? 1'b0 // reserved
: CPLLREFCLKSEL == 3'b001 ? GTREFCLK0
: CPLLREFCLKSEL == 3'b010 ? GTREFCLK1
: CPLLREFCLKSEL == 3'b011 ? GTNORTHREFCLK0
: CPLLREFCLKSEL == 3'b100 ? GTNORTHREFCLK1
: CPLLREFCLKSEL == 3'b101 ? GTSOUTHREFCLK0
: CPLLREFCLKSEL == 3'b110 ? GTSOUTHREFCLK1
: /*CPLLREFCLKSEL == 3'b111 ?*/ GTGREFCLK;
endmodule
/*******************************************************************************
* Module: gtxe2_chnl_cpll_outmux
* Date: 2015-07-06
* Author: Alexey
* Description: non-sinthesizable clock multiplexer, used in clocking scheme
*
* Copyright (c) 2015 Elphel, Inc.
* gtxe2_chnl_cpll_outmux.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* gtxe2_chnl_cpll_outmux.v file 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
module gtxe2_chnl_outclk_mux(
input wire TXPLLREFCLK_DIV1,
input wire TXPLLREFCLK_DIV2,
input wire TXOUTCLKPMA,
input wire TXOUTCLKPCS,
input wire [2:0] TXOUTCLKSEL,
input wire TXDLYBYPASS,
output wire TXOUTCLK
);
assign TXOUTCLK = TXOUTCLKSEL == 3'b001 ? TXOUTCLKPCS
: TXOUTCLKSEL == 3'b010 ? TXOUTCLKPMA
: TXOUTCLKSEL == 3'b011 ? TXPLLREFCLK_DIV1
: TXOUTCLKSEL == 3'b100 ? TXPLLREFCLK_DIV2
: /* 3'b000 */ 1'b1;
endmodule
/*******************************************************************************
* Module: gtxe2_chnl_rx
* Date: 2015-07-06
* Author: Alexey
* Description: reciever top-level. Also includes polarity-inversion logic
*
* Copyright (c) 2015 Elphel, Inc.
* gtxe2_chnl_rx.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* gtxe2_chnl_rx.v file 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
/**
* For now contains only deserializer, oob, 10x8 decoder, aligner and polarity invertor blocks
**/
`include "gtxe2_chnl_rx_des.v"
`include "gtxe2_chnl_rx_oob.v"
`include "gtxe2_chnl_rx_10x8dec.v"
`include "gtxe2_chnl_rx_align.v"
module gtxe2_chnl_rx(
input wire reset,
input wire RXP,
input wire RXN,
input wire RXUSRCLK,
input wire RXUSRCLK2,
output wire [63:0] RXDATA,
// oob
input wire [1:0] RXELECIDLEMODE,
output wire RXELECIDLE,
output wire RXCOMINITDET,
output wire RXCOMWAKEDET,
// polarity
input wire RXPOLARITY,
// aligner
output wire RXBYTEISALIGNED,
output wire RXBYTEREALIGN,
output wire RXCOMMADET,
input wire RXCOMMADETEN,
input wire RXPCOMMAALIGNEN,
input wire RXMCOMMAALIGNEN,
// 10/8 decoder
input wire RX8B10BEN,
output wire [7:0] RXCHARISCOMMA,
output wire [7:0] RXCHARISK,
output wire [7:0] RXDISPERR,
output wire [7:0] RXNOTINTABLE,
// internal
input wire serial_clk
);
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";
parameter [9:0] ALIGN_MCOMMA_VALUE = 10'b1010000011;
parameter ALIGN_MCOMMA_DET = "TRUE";
parameter [9:0] ALIGN_PCOMMA_VALUE = 10'b0101111100;
parameter ALIGN_PCOMMA_DET = "TRUE";
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;
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
end
endfunction
localparam internal_data_width = calc_idw(PRX8B10BEN, RX_INT_DATAWIDTH, RX_DATA_WIDTH);
// OOB
gtxe2_chnl_rx_oob #(
.width (internal_data_width)
)
rx_oob(
.reset (reset),
.clk (serial_clk),
.RXN (RXN),
.RXP (RXP),
.RXELECIDLEMODE (RXELECIDLEMODE),
.RXELECIDLE (RXELECIDLE),
.RXCOMINITDET (RXCOMINITDET),
.RXCOMWAKEDET (RXCOMWAKEDET)
);
// Polarity
// no need to invert data after a deserializer, no need to resync or make a buffer trigger for simulation
wire indata_ser;
assign indata_ser = RXPOLARITY ^ RXP;
// due to non-syntasisable usage, CDR is missing
// deserializer
wire [internal_data_width - 1:0] parallel_data;
gtxe2_chnl_rx_des #(
.width (internal_data_width)
)
des(
.reset (reset),
.inclk (serial_clk),
.outclk (RXUSRCLK),
.indata (indata_ser),
.outdata (parallel_data)
);
// aligner
wire [internal_data_width - 1:0] aligned_data;
gtxe2_chnl_rx_align #(
.width (internal_data_width),
.ALIGN_MCOMMA_VALUE (ALIGN_MCOMMA_VALUE),
.ALIGN_MCOMMA_DET (ALIGN_MCOMMA_DET),
.ALIGN_PCOMMA_VALUE (ALIGN_PCOMMA_VALUE),