diff --git a/example/ZCU102/fpga/fpga/Makefile b/example/ZCU102/fpga/fpga/Makefile index 677a1f89..b13a5c7f 100644 --- a/example/ZCU102/fpga/fpga/Makefile +++ b/example/ZCU102/fpga/fpga/Makefile @@ -7,6 +7,7 @@ FPGA_ARCH = zynquplus # Files for synthesis SYN_FILES = rtl/fpga.v SYN_FILES += rtl/fpga_core.v +SYN_FILES += rtl/eth_xcvr_phy_wrapper.v SYN_FILES += rtl/debounce_switch.v SYN_FILES += rtl/sync_signal.v SYN_FILES += lib/eth/rtl/eth_mac_10g_fifo.v @@ -55,7 +56,7 @@ XDC_FILES += lib/eth/lib/axis/syn/vivado/axis_async_fifo.tcl XDC_FILES += lib/eth/lib/axis/syn/vivado/sync_reset.tcl # IP -IP_TCL_FILES = ip/gtwizard_ultrascale_0.tcl +IP_TCL_FILES += ip/eth_xcvr_gt.tcl include ../common/vivado.mk diff --git a/example/ZCU102/fpga/ip/eth_xcvr_gt.tcl b/example/ZCU102/fpga/ip/eth_xcvr_gt.tcl new file mode 100644 index 00000000..990b94c4 --- /dev/null +++ b/example/ZCU102/fpga/ip/eth_xcvr_gt.tcl @@ -0,0 +1,76 @@ +# Copyright (c) 2021 Alex Forencich +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +set base_name {eth_xcvr_gt} + +set preset {GTH-10GBASE-R} + +set freerun_freq {125} +set line_rate {10.3125} +set refclk_freq {156.25} +set qpll_fracn [expr {int(fmod($line_rate*1000/2 / $refclk_freq, 1)*pow(2, 24))}] +set user_data_width {64} +set int_data_width {32} +set extra_ports [list] +set extra_pll_ports [list {qpll0lock_out}] + +set config [dict create] + +dict set config TX_LINE_RATE $line_rate +dict set config TX_REFCLK_FREQUENCY $refclk_freq +dict set config TX_QPLL_FRACN_NUMERATOR $qpll_fracn +dict set config TX_USER_DATA_WIDTH $user_data_width +dict set config TX_INT_DATA_WIDTH $int_data_width +dict set config RX_LINE_RATE $line_rate +dict set config RX_REFCLK_FREQUENCY $refclk_freq +dict set config RX_QPLL_FRACN_NUMERATOR $qpll_fracn +dict set config RX_USER_DATA_WIDTH $user_data_width +dict set config RX_INT_DATA_WIDTH $int_data_width +dict set config ENABLE_OPTIONAL_PORTS $extra_ports +dict set config LOCATE_COMMON {CORE} +dict set config LOCATE_RESET_CONTROLLER {CORE} +dict set config LOCATE_TX_USER_CLOCKING {CORE} +dict set config LOCATE_RX_USER_CLOCKING {CORE} +dict set config LOCATE_USER_DATA_WIDTH_SIZING {CORE} +dict set config FREERUN_FREQUENCY $freerun_freq +dict set config DISABLE_LOC_XDC {1} + +proc create_gtwizard_ip {name preset config} { + create_ip -name gtwizard_ultrascale -vendor xilinx.com -library ip -module_name $name + set ip [get_ips $name] + set_property CONFIG.preset $preset $ip + set config_list {} + dict for {name value} $config { + lappend config_list "CONFIG.${name}" $value + } + set_property -dict $config_list $ip +} + +# variant with channel and common +dict set config ENABLE_OPTIONAL_PORTS [concat $extra_pll_ports $extra_ports] +dict set config LOCATE_COMMON {CORE} + +create_gtwizard_ip "${base_name}_full" $preset $config + +# variant with channel only +dict set config ENABLE_OPTIONAL_PORTS $extra_ports +dict set config LOCATE_COMMON {EXAMPLE_DESIGN} + +create_gtwizard_ip "${base_name}_channel" $preset $config diff --git a/example/ZCU102/fpga/ip/gtwizard_ultrascale_0.tcl b/example/ZCU102/fpga/ip/gtwizard_ultrascale_0.tcl deleted file mode 100644 index 66db7a0d..00000000 --- a/example/ZCU102/fpga/ip/gtwizard_ultrascale_0.tcl +++ /dev/null @@ -1,21 +0,0 @@ - -create_ip -name gtwizard_ultrascale -vendor xilinx.com -library ip -module_name gtwizard_ultrascale_0 - -set_property -dict [list CONFIG.preset {GTH-10GBASE-R}] [get_ips gtwizard_ultrascale_0] - -set_property -dict [list \ - CONFIG.CHANNEL_ENABLE {X1Y15 X1Y14 X1Y13 X1Y12} \ - CONFIG.TX_MASTER_CHANNEL {X1Y12} \ - CONFIG.RX_MASTER_CHANNEL {X1Y12} \ - CONFIG.TX_LINE_RATE {10.3125} \ - CONFIG.TX_REFCLK_FREQUENCY {156.25} \ - CONFIG.TX_USER_DATA_WIDTH {64} \ - CONFIG.TX_INT_DATA_WIDTH {32} \ - CONFIG.RX_LINE_RATE {10.3125} \ - CONFIG.RX_REFCLK_FREQUENCY {156.25} \ - CONFIG.RX_USER_DATA_WIDTH {64} \ - CONFIG.RX_INT_DATA_WIDTH {32} \ - CONFIG.RX_REFCLK_SOURCE {X1Y15 clk0 X1Y14 clk0 X1Y13 clk0 X1Y12 clk0} \ - CONFIG.TX_REFCLK_SOURCE {X1Y15 clk0 X1Y14 clk0 X1Y13 clk0 X1Y12 clk0} \ - CONFIG.FREERUN_FREQUENCY {125} \ -] [get_ips gtwizard_ultrascale_0] diff --git a/example/ZCU102/fpga/rtl/eth_xcvr_phy_wrapper.v b/example/ZCU102/fpga/rtl/eth_xcvr_phy_wrapper.v new file mode 100644 index 00000000..afbaddd0 --- /dev/null +++ b/example/ZCU102/fpga/rtl/eth_xcvr_phy_wrapper.v @@ -0,0 +1,295 @@ +/* + +Copyright (c) 2021 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * Transceiver and PHY wrapper + */ +module eth_xcvr_phy_wrapper # +( + parameter HAS_COMMON = 1, + parameter DATA_WIDTH = 64, + parameter CTRL_WIDTH = (DATA_WIDTH/8), + parameter HDR_WIDTH = 2, + parameter PRBS31_ENABLE = 0, + parameter TX_SERDES_PIPELINE = 0, + parameter RX_SERDES_PIPELINE = 0, + parameter BITSLIP_HIGH_CYCLES = 1, + parameter BITSLIP_LOW_CYCLES = 8, + parameter COUNT_125US = 125000/6.4 +) +( + input wire xcvr_ctrl_clk, + input wire xcvr_ctrl_rst, + + /* + * Common + */ + output wire xcvr_gtpowergood_out, + + /* + * PLL out + */ + input wire xcvr_gtrefclk00_in, + output wire xcvr_qpll0lock_out, + output wire xcvr_qpll0outclk_out, + output wire xcvr_qpll0outrefclk_out, + + /* + * PLL in + */ + input wire xcvr_qpll0lock_in, + output wire xcvr_qpll0reset_out, + input wire xcvr_qpll0clk_in, + input wire xcvr_qpll0refclk_in, + + /* + * Serial data + */ + output wire xcvr_txp, + output wire xcvr_txn, + input wire xcvr_rxp, + input wire xcvr_rxn, + + /* + * PHY connections + */ + output wire phy_tx_clk, + output wire phy_tx_rst, + input wire [DATA_WIDTH-1:0] phy_xgmii_txd, + input wire [CTRL_WIDTH-1:0] phy_xgmii_txc, + output wire phy_rx_clk, + output wire phy_rx_rst, + output wire [DATA_WIDTH-1:0] phy_xgmii_rxd, + output wire [CTRL_WIDTH-1:0] phy_xgmii_rxc, + output wire phy_tx_bad_block, + output wire [6:0] phy_rx_error_count, + output wire phy_rx_bad_block, + output wire phy_rx_sequence_error, + output wire phy_rx_block_lock, + output wire phy_rx_high_ber, + input wire phy_tx_prbs31_enable, + input wire phy_rx_prbs31_enable +); + +wire phy_rx_reset_req; + +wire gt_reset_tx_datapath = 1'b0; +wire gt_reset_rx_datapath = phy_rx_reset_req; + +wire gt_reset_tx_done; +wire gt_reset_rx_done; + +wire [5:0] gt_txheader; +wire [63:0] gt_txdata; +wire gt_rxgearboxslip; +wire [5:0] gt_rxheader; +wire [1:0] gt_rxheadervalid; +wire [63:0] gt_rxdata; +wire [1:0] gt_rxdatavalid; + +generate + +if (HAS_COMMON) begin : xcvr + + eth_xcvr_gt_full + eth_xcvr_gt_full_inst ( + // Common + .gtwiz_reset_clk_freerun_in(xcvr_ctrl_clk), + .gtwiz_reset_all_in(xcvr_ctrl_rst), + .gtpowergood_out(xcvr_gtpowergood_out), + + // PLL + .gtrefclk00_in(xcvr_gtrefclk00_in), + .qpll0lock_out(xcvr_qpll0lock_out), + .qpll0outclk_out(xcvr_qpll0outclk_out), + .qpll0outrefclk_out(xcvr_qpll0outrefclk_out), + + // Serial data + .gthtxp_out(xcvr_txp), + .gthtxn_out(xcvr_txn), + .gthrxp_in(xcvr_rxp), + .gthrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_reset_in(1'b0), + .gtwiz_userclk_tx_srcclk_out(), + .gtwiz_userclk_tx_usrclk_out(), + .gtwiz_userclk_tx_usrclk2_out(phy_tx_clk), + .gtwiz_userclk_tx_active_out(), + .gtwiz_reset_tx_pll_and_datapath_in(1'b0), + .gtwiz_reset_tx_datapath_in(gt_reset_tx_datapath), + .gtwiz_reset_tx_done_out(gt_reset_tx_done), + .txpmaresetdone_out(), + .txprgdivresetdone_out(), + + .gtwiz_userdata_tx_in(gt_txdata), + .txheader_in(gt_txheader), + .txsequence_in(7'b0), + + // Receive + .gtwiz_userclk_rx_reset_in(1'b0), + .gtwiz_userclk_rx_srcclk_out(), + .gtwiz_userclk_rx_usrclk_out(), + .gtwiz_userclk_rx_usrclk2_out(phy_rx_clk), + .gtwiz_userclk_rx_active_out(), + .gtwiz_reset_rx_pll_and_datapath_in(1'b0), + .gtwiz_reset_rx_datapath_in(gt_reset_rx_datapath), + .gtwiz_reset_rx_cdr_stable_out(), + .gtwiz_reset_rx_done_out(gt_reset_rx_done), + .rxpmaresetdone_out(), + .rxprgdivresetdone_out(), + + .rxgearboxslip_in(gt_rxgearboxslip), + .gtwiz_userdata_rx_out(gt_rxdata), + .rxdatavalid_out(gt_rxdatavalid), + .rxheader_out(gt_rxheader), + .rxheadervalid_out(gt_rxheadervalid), + .rxstartofseq_out() + ); + +end else begin : xcvr + + eth_xcvr_gt_channel + eth_xcvr_gt_channel_inst ( + // Common + .gtwiz_reset_clk_freerun_in(xcvr_ctrl_clk), + .gtwiz_reset_all_in(xcvr_ctrl_rst), + .gtpowergood_out(xcvr_gtpowergood_out), + + // PLL + .gtwiz_reset_qpll0lock_in(xcvr_qpll0lock_in), + .gtwiz_reset_qpll0reset_out(xcvr_qpll0reset_out), + .qpll0clk_in(xcvr_qpll0clk_in), + .qpll0refclk_in(xcvr_qpll0refclk_in), + .qpll1clk_in(1'b0), + .qpll1refclk_in(1'b0), + + // Serial data + .gthtxp_out(xcvr_txp), + .gthtxn_out(xcvr_txn), + .gthrxp_in(xcvr_rxp), + .gthrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_reset_in(1'b0), + .gtwiz_userclk_tx_srcclk_out(), + .gtwiz_userclk_tx_usrclk_out(), + .gtwiz_userclk_tx_usrclk2_out(phy_tx_clk), + .gtwiz_userclk_tx_active_out(), + .gtwiz_reset_tx_pll_and_datapath_in(1'b0), + .gtwiz_reset_tx_datapath_in(gt_reset_tx_datapath), + .gtwiz_reset_tx_done_out(gt_reset_tx_done), + .txpmaresetdone_out(), + .txprgdivresetdone_out(), + + .gtwiz_userdata_tx_in(gt_txdata), + .txheader_in(gt_txheader), + .txsequence_in(7'b0), + + // Receive + .gtwiz_userclk_rx_reset_in(1'b0), + .gtwiz_userclk_rx_srcclk_out(), + .gtwiz_userclk_rx_usrclk_out(), + .gtwiz_userclk_rx_usrclk2_out(phy_rx_clk), + .gtwiz_userclk_rx_active_out(), + .gtwiz_reset_rx_pll_and_datapath_in(1'b0), + .gtwiz_reset_rx_datapath_in(gt_reset_rx_datapath), + .gtwiz_reset_rx_cdr_stable_out(), + .gtwiz_reset_rx_done_out(gt_reset_rx_done), + .rxpmaresetdone_out(), + .rxprgdivresetdone_out(), + + .rxgearboxslip_in(gt_rxgearboxslip), + .gtwiz_userdata_rx_out(gt_rxdata), + .rxdatavalid_out(gt_rxdatavalid), + .rxheader_out(gt_rxheader), + .rxheadervalid_out(gt_rxheadervalid), + .rxstartofseq_out() + ); + +end + +endgenerate + +sync_reset #( + .N(4) +) +tx_reset_sync_inst ( + .clk(phy_tx_clk), + .rst(!gt_reset_tx_done), + .out(phy_tx_rst) +); + +sync_reset #( + .N(4) +) +rx_reset_sync_inst ( + .clk(phy_rx_clk), + .rst(!gt_reset_rx_done), + .out(phy_rx_rst) +); + +eth_phy_10g #( + .DATA_WIDTH(DATA_WIDTH), + .CTRL_WIDTH(CTRL_WIDTH), + .HDR_WIDTH(HDR_WIDTH), + .BIT_REVERSE(1), + .SCRAMBLER_DISABLE(0), + .PRBS31_ENABLE(PRBS31_ENABLE), + .TX_SERDES_PIPELINE(TX_SERDES_PIPELINE), + .RX_SERDES_PIPELINE(RX_SERDES_PIPELINE), + .BITSLIP_HIGH_CYCLES(BITSLIP_HIGH_CYCLES), + .BITSLIP_LOW_CYCLES(BITSLIP_LOW_CYCLES), + .COUNT_125US(COUNT_125US) +) +phy_inst ( + .tx_clk(phy_tx_clk), + .tx_rst(phy_tx_rst), + .rx_clk(phy_rx_clk), + .rx_rst(phy_rx_rst), + .xgmii_txd(phy_xgmii_txd), + .xgmii_txc(phy_xgmii_txc), + .xgmii_rxd(phy_xgmii_rxd), + .xgmii_rxc(phy_xgmii_rxc), + .serdes_tx_data(gt_txdata), + .serdes_tx_hdr(gt_txheader), + .serdes_rx_data(gt_rxdata), + .serdes_rx_hdr(gt_rxheader), + .serdes_rx_bitslip(gt_rxgearboxslip), + .serdes_rx_reset_req(phy_rx_reset_req), + .tx_bad_block(phy_tx_bad_block), + .rx_error_count(phy_rx_error_count), + .rx_bad_block(phy_rx_bad_block), + .rx_sequence_error(phy_rx_sequence_error), + .rx_block_lock(phy_rx_block_lock), + .rx_high_ber(phy_rx_high_ber), + .tx_prbs31_enable(phy_tx_prbs31_enable), + .rx_prbs31_enable(phy_rx_prbs31_enable) +); + +endmodule diff --git a/example/ZCU102/fpga/rtl/fpga.v b/example/ZCU102/fpga/rtl/fpga.v index 9685e7c2..d632913d 100644 --- a/example/ZCU102/fpga/rtl/fpga.v +++ b/example/ZCU102/fpga/rtl/fpga.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2020 Alex Forencich +Copyright (c) 2020-2021 Alex Forencich Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -276,347 +276,208 @@ wire sfp3_rx_rst_int; wire [63:0] sfp3_rxd_int; wire [7:0] sfp3_rxc_int; +assign clk_156mhz_int = sfp0_tx_clk_int; +assign rst_156mhz_int = sfp0_tx_rst_int; + wire sfp0_rx_block_lock; wire sfp1_rx_block_lock; -wire sfp2_rx_block_lock; -wire sfp3_rx_block_lock; -wire sfp_mgt_refclk; +wire sfp_mgt_refclk_0; -wire [3:0] gt_txclkout; -wire gt_txusrclk; -wire gt_txusrclk2; - -wire [3:0] gt_rxclkout; -wire [3:0] gt_rxusrclk; -wire [3:0] gt_rxusrclk2; - -wire gt_reset_tx_done; -wire gt_reset_rx_done; - -wire [3:0] gt_txprgdivresetdone; -wire [3:0] gt_txpmaresetdone; -wire [3:0] gt_rxprgdivresetdone; -wire [3:0] gt_rxpmaresetdone; - -wire gt_tx_reset = ~((>_txprgdivresetdone) & (>_txpmaresetdone)); -wire gt_rx_reset = ~>_rxpmaresetdone; - -reg gt_userclk_tx_active = 1'b0; -reg [3:0] gt_userclk_rx_active = 1'b0; - -IBUFDS_GTE4 ibufds_gte4_sfp_mgt_refclk_inst ( - .I (sfp_mgt_refclk_0_p), - .IB (sfp_mgt_refclk_0_n), - .CEB (1'b0), - .O (sfp_mgt_refclk), - .ODIV2 () +IBUFDS_GTE4 ibufds_gte4_sfp_mgt_refclk_0_inst ( + .I (sfp_mgt_refclk_0_p), + .IB (sfp_mgt_refclk_0_n), + .CEB (1'b0), + .O (sfp_mgt_refclk_0), + .ODIV2 () ); -BUFG_GT bufg_gt_tx_usrclk_inst ( - .CE (1'b1), - .CEMASK (1'b0), - .CLR (gt_tx_reset), - .CLRMASK (1'b0), - .DIV (3'd0), - .I (gt_txclkout[0]), - .O (gt_txusrclk) -); +wire sfp_qpll0lock; +wire sfp_qpll0outclk; +wire sfp_qpll0outrefclk; -BUFG_GT bufg_gt_tx_usrclk2_inst ( - .CE (1'b1), - .CEMASK (1'b0), - .CLR (gt_tx_reset), - .CLRMASK (1'b0), - .DIV (3'd1), - .I (gt_txclkout[0]), - .O (gt_txusrclk2) -); - -assign clk_156mhz_int = gt_txusrclk2; - -always @(posedge gt_txusrclk, posedge gt_tx_reset) begin - if (gt_tx_reset) begin - gt_userclk_tx_active <= 1'b0; - end else begin - gt_userclk_tx_active <= 1'b1; - end -end - -genvar n; - -generate - -for (n = 0 ; n < 4; n = n + 1) begin - - BUFG_GT bufg_gt_rx_usrclk_0_inst ( - .CE (1'b1), - .CEMASK (1'b0), - .CLR (gt_rx_reset), - .CLRMASK (1'b0), - .DIV (3'd0), - .I (gt_rxclkout[n]), - .O (gt_rxusrclk[n]) - ); - - BUFG_GT bufg_gt_rx_usrclk2_0_inst ( - .CE (1'b1), - .CEMASK (1'b0), - .CLR (gt_rx_reset), - .CLRMASK (1'b0), - .DIV (3'd1), - .I (gt_rxclkout[n]), - .O (gt_rxusrclk2[n]) - ); - - always @(posedge gt_rxusrclk[n], posedge gt_rx_reset) begin - if (gt_rx_reset) begin - gt_userclk_rx_active[n] <= 1'b0; - end else begin - gt_userclk_rx_active[n] <= 1'b1; - end - end - -end - -endgenerate - -sync_reset #( - .N(4) -) -sync_reset_156mhz_inst ( - .clk(clk_156mhz_int), - .rst(~gt_reset_tx_done), - .out(rst_156mhz_int) -); - -wire [5:0] sfp0_gt_txheader; -wire [63:0] sfp0_gt_txdata; -wire sfp0_gt_rxgearboxslip; -wire [5:0] sfp0_gt_rxheader; -wire [1:0] sfp0_gt_rxheadervalid; -wire [63:0] sfp0_gt_rxdata; -wire [1:0] sfp0_gt_rxdatavalid; - -wire [5:0] sfp1_gt_txheader; -wire [63:0] sfp1_gt_txdata; -wire sfp1_gt_rxgearboxslip; -wire [5:0] sfp1_gt_rxheader; -wire [1:0] sfp1_gt_rxheadervalid; -wire [63:0] sfp1_gt_rxdata; -wire [1:0] sfp1_gt_rxdatavalid; - -wire [5:0] sfp2_gt_txheader; -wire [63:0] sfp2_gt_txdata; -wire sfp2_gt_rxgearboxslip; -wire [5:0] sfp2_gt_rxheader; -wire [1:0] sfp2_gt_rxheadervalid; -wire [63:0] sfp2_gt_rxdata; -wire [1:0] sfp2_gt_rxdatavalid; - -wire [5:0] sfp3_gt_txheader; -wire [63:0] sfp3_gt_txdata; -wire sfp3_gt_rxgearboxslip; -wire [5:0] sfp3_gt_rxheader; -wire [1:0] sfp3_gt_rxheadervalid; -wire [63:0] sfp3_gt_rxdata; -wire [1:0] sfp3_gt_rxdatavalid; - -gtwizard_ultrascale_0 -sfp_gth_inst ( - .gtwiz_userclk_tx_active_in(>_userclk_tx_active), - .gtwiz_userclk_rx_active_in(>_userclk_rx_active), - - .gtwiz_reset_clk_freerun_in(clk_125mhz_int), - .gtwiz_reset_all_in(rst_125mhz_int), - - .gtwiz_reset_tx_pll_and_datapath_in(1'b0), - .gtwiz_reset_tx_datapath_in(1'b0), - - .gtwiz_reset_rx_pll_and_datapath_in(1'b0), - .gtwiz_reset_rx_datapath_in(1'b0), - - .gtwiz_reset_rx_cdr_stable_out(), - - .gtwiz_reset_tx_done_out(gt_reset_tx_done), - .gtwiz_reset_rx_done_out(gt_reset_rx_done), - - .gtrefclk00_in(sfp_mgt_refclk), - - .qpll0outclk_out(), - .qpll0outrefclk_out(), - - .gthrxn_in({sfp3_rx_n, sfp2_rx_n, sfp1_rx_n, sfp0_rx_n}), - .gthrxp_in({sfp3_rx_p, sfp2_rx_p, sfp1_rx_p, sfp0_rx_p}), - - .rxusrclk_in(gt_rxusrclk), - .rxusrclk2_in(gt_rxusrclk2), - - .gtwiz_userdata_tx_in({sfp3_gt_txdata, sfp2_gt_txdata, sfp1_gt_txdata, sfp0_gt_txdata}), - .txheader_in({sfp3_gt_txheader, sfp2_gt_txheader, sfp1_gt_txheader, sfp0_gt_txheader}), - .txsequence_in({4{7'b0}}), - - .txusrclk_in({4{gt_txusrclk}}), - .txusrclk2_in({4{gt_txusrclk2}}), - - .gtpowergood_out(), - - .gthtxn_out({sfp3_tx_n, sfp2_tx_n, sfp1_tx_n, sfp0_tx_n}), - .gthtxp_out({sfp3_tx_p, sfp2_tx_p, sfp1_tx_p, sfp0_tx_p}), - - .rxgearboxslip_in({sfp3_gt_rxgearboxslip, sfp2_gt_rxgearboxslip, sfp1_gt_rxgearboxslip, sfp0_gt_rxgearboxslip}), - .gtwiz_userdata_rx_out({sfp3_gt_rxdata, sfp2_gt_rxdata, sfp1_gt_rxdata, sfp0_gt_rxdata}), - .rxdatavalid_out({sfp3_gt_rxdatavalid, sfp2_gt_rxdatavalid, sfp1_gt_rxdatavalid, sfp0_gt_rxdatavalid}), - .rxheader_out({sfp3_gt_rxheader, sfp2_gt_rxheader, sfp1_gt_rxheader, sfp0_gt_rxheader}), - .rxheadervalid_out({sfp3_gt_rxheadervalid, sfp2_gt_rxheadervalid, sfp1_gt_rxheadervalid, sfp0_gt_rxheadervalid}), - .rxoutclk_out(gt_rxclkout), - .rxpmaresetdone_out(gt_rxpmaresetdone), - .rxprgdivresetdone_out(gt_rxprgdivresetdone), - .rxstartofseq_out(), - - .txoutclk_out(gt_txclkout), - .txpmaresetdone_out(gt_txpmaresetdone), - .txprgdivresetdone_out(gt_txprgdivresetdone) -); - -assign sfp0_tx_clk_int = clk_156mhz_int; -assign sfp0_tx_rst_int = rst_156mhz_int; - -assign sfp0_rx_clk_int = gt_rxusrclk2[0]; - -sync_reset #( - .N(4) -) -sfp0_rx_rst_reset_sync_inst ( - .clk(sfp0_rx_clk_int), - .rst(~gt_reset_rx_done), - .out(sfp0_rx_rst_int) -); - -eth_phy_10g #( - .BIT_REVERSE(1) +eth_xcvr_phy_wrapper #( + .HAS_COMMON(1) ) sfp0_phy_inst ( - .tx_clk(sfp0_tx_clk_int), - .tx_rst(sfp0_tx_rst_int), - .rx_clk(sfp0_rx_clk_int), - .rx_rst(sfp0_rx_rst_int), - .xgmii_txd(sfp0_txd_int), - .xgmii_txc(sfp0_txc_int), - .xgmii_rxd(sfp0_rxd_int), - .xgmii_rxc(sfp0_rxc_int), - .serdes_tx_data(sfp0_gt_txdata), - .serdes_tx_hdr(sfp0_gt_txheader), - .serdes_rx_data(sfp0_gt_rxdata), - .serdes_rx_hdr(sfp0_gt_rxheader), - .serdes_rx_bitslip(sfp0_gt_rxgearboxslip), - .rx_block_lock(sfp0_rx_block_lock), - .rx_high_ber() + .xcvr_ctrl_clk(clk_125mhz_int), + .xcvr_ctrl_rst(rst_125mhz_int), + + // Common + .xcvr_gtpowergood_out(), + + // PLL out + .xcvr_gtrefclk00_in(sfp_mgt_refclk_0), + .xcvr_qpll0lock_out(sfp_qpll0lock), + .xcvr_qpll0outclk_out(sfp_qpll0outclk), + .xcvr_qpll0outrefclk_out(sfp_qpll0outrefclk), + + // PLL in + .xcvr_qpll0lock_in(1'b0), + .xcvr_qpll0reset_out(), + .xcvr_qpll0clk_in(1'b0), + .xcvr_qpll0refclk_in(1'b0), + + // Serial data + .xcvr_txp(sfp0_tx_p), + .xcvr_txn(sfp0_tx_n), + .xcvr_rxp(sfp0_rx_p), + .xcvr_rxn(sfp0_rx_n), + + // PHY connections + .phy_tx_clk(sfp0_tx_clk_int), + .phy_tx_rst(sfp0_tx_rst_int), + .phy_xgmii_txd(sfp0_txd_int), + .phy_xgmii_txc(sfp0_txc_int), + .phy_rx_clk(sfp0_rx_clk_int), + .phy_rx_rst(sfp0_rx_rst_int), + .phy_xgmii_rxd(sfp0_rxd_int), + .phy_xgmii_rxc(sfp0_rxc_int), + .phy_rx_error_count(), + .phy_rx_bad_block(), + .phy_rx_sequence_error(), + .phy_rx_block_lock(sfp0_rx_block_lock), + .phy_rx_high_ber(), + .phy_tx_prbs31_enable(), + .phy_rx_prbs31_enable() ); -assign sfp1_tx_clk_int = clk_156mhz_int; -assign sfp1_tx_rst_int = rst_156mhz_int; - -assign sfp1_rx_clk_int = gt_rxusrclk2[1]; - -sync_reset #( - .N(4) -) -sfp1_rx_rst_reset_sync_inst ( - .clk(sfp1_rx_clk_int), - .rst(~gt_reset_rx_done), - .out(sfp1_rx_rst_int) -); - -eth_phy_10g #( - .BIT_REVERSE(1) +eth_xcvr_phy_wrapper #( + .HAS_COMMON(0) ) sfp1_phy_inst ( - .tx_clk(sfp1_tx_clk_int), - .tx_rst(sfp1_tx_rst_int), - .rx_clk(sfp1_rx_clk_int), - .rx_rst(sfp1_rx_rst_int), - .xgmii_txd(sfp1_txd_int), - .xgmii_txc(sfp1_txc_int), - .xgmii_rxd(sfp1_rxd_int), - .xgmii_rxc(sfp1_rxc_int), - .serdes_tx_data(sfp1_gt_txdata), - .serdes_tx_hdr(sfp1_gt_txheader), - .serdes_rx_data(sfp1_gt_rxdata), - .serdes_rx_hdr(sfp1_gt_rxheader), - .serdes_rx_bitslip(sfp1_gt_rxgearboxslip), - .rx_block_lock(sfp1_rx_block_lock), - .rx_high_ber() + .xcvr_ctrl_clk(clk_125mhz_int), + .xcvr_ctrl_rst(rst_125mhz_int), + + // Common + .xcvr_gtpowergood_out(), + + // PLL out + .xcvr_gtrefclk00_in(1'b0), + .xcvr_qpll0lock_out(), + .xcvr_qpll0outclk_out(), + .xcvr_qpll0outrefclk_out(), + + // PLL in + .xcvr_qpll0lock_in(sfp_qpll0lock), + .xcvr_qpll0reset_out(), + .xcvr_qpll0clk_in(sfp_qpll0outclk), + .xcvr_qpll0refclk_in(sfp_qpll0outrefclk), + + // Serial data + .xcvr_txp(sfp1_tx_p), + .xcvr_txn(sfp1_tx_n), + .xcvr_rxp(sfp1_rx_p), + .xcvr_rxn(sfp1_rx_n), + + // PHY connections + .phy_tx_clk(sfp1_tx_clk_int), + .phy_tx_rst(sfp1_tx_rst_int), + .phy_xgmii_txd(sfp1_txd_int), + .phy_xgmii_txc(sfp1_txc_int), + .phy_rx_clk(sfp1_rx_clk_int), + .phy_rx_rst(sfp1_rx_rst_int), + .phy_xgmii_rxd(sfp1_rxd_int), + .phy_xgmii_rxc(sfp1_rxc_int), + .phy_rx_error_count(), + .phy_rx_bad_block(), + .phy_rx_sequence_error(), + .phy_rx_block_lock(sfp1_rx_block_lock), + .phy_rx_high_ber(), + .phy_tx_prbs31_enable(), + .phy_rx_prbs31_enable() ); -assign sfp2_tx_clk_int = clk_156mhz_int; -assign sfp2_tx_rst_int = rst_156mhz_int; - -assign sfp2_rx_clk_int = gt_rxusrclk2[2]; - -sync_reset #( - .N(4) -) -sfp2_rx_rst_reset_sync_inst ( - .clk(sfp2_rx_clk_int), - .rst(~gt_reset_rx_done), - .out(sfp2_rx_rst_int) -); - -eth_phy_10g #( - .BIT_REVERSE(1) +eth_xcvr_phy_wrapper #( + .HAS_COMMON(0) ) sfp2_phy_inst ( - .tx_clk(sfp2_tx_clk_int), - .tx_rst(sfp2_tx_rst_int), - .rx_clk(sfp2_rx_clk_int), - .rx_rst(sfp2_rx_rst_int), - .xgmii_txd(sfp2_txd_int), - .xgmii_txc(sfp2_txc_int), - .xgmii_rxd(sfp2_rxd_int), - .xgmii_rxc(sfp2_rxc_int), - .serdes_tx_data(sfp2_gt_txdata), - .serdes_tx_hdr(sfp2_gt_txheader), - .serdes_rx_data(sfp2_gt_rxdata), - .serdes_rx_hdr(sfp2_gt_rxheader), - .serdes_rx_bitslip(sfp2_gt_rxgearboxslip), - .rx_block_lock(sfp2_rx_block_lock), - .rx_high_ber() + .xcvr_ctrl_clk(clk_125mhz_int), + .xcvr_ctrl_rst(rst_125mhz_int), + + // Common + .xcvr_gtpowergood_out(), + + // PLL out + .xcvr_gtrefclk00_in(1'b0), + .xcvr_qpll0lock_out(), + .xcvr_qpll0outclk_out(), + .xcvr_qpll0outrefclk_out(), + + // PLL in + .xcvr_qpll0lock_in(sfp_qpll0lock), + .xcvr_qpll0reset_out(), + .xcvr_qpll0clk_in(sfp_qpll0outclk), + .xcvr_qpll0refclk_in(sfp_qpll0outrefclk), + + // Serial data + .xcvr_txp(sfp2_tx_p), + .xcvr_txn(sfp2_tx_n), + .xcvr_rxp(sfp2_rx_p), + .xcvr_rxn(sfp2_rx_n), + + // PHY connections + .phy_tx_clk(sfp2_tx_clk_int), + .phy_tx_rst(sfp2_tx_rst_int), + .phy_xgmii_txd(sfp2_txd_int), + .phy_xgmii_txc(sfp2_txc_int), + .phy_rx_clk(sfp2_rx_clk_int), + .phy_rx_rst(sfp2_rx_rst_int), + .phy_xgmii_rxd(sfp2_rxd_int), + .phy_xgmii_rxc(sfp2_rxc_int), + .phy_rx_error_count(), + .phy_rx_bad_block(), + .phy_rx_sequence_error(), + .phy_rx_block_lock(sfp2_rx_block_lock), + .phy_rx_high_ber(), + .phy_tx_prbs31_enable(), + .phy_rx_prbs31_enable() ); -assign sfp3_tx_clk_int = clk_156mhz_int; -assign sfp3_tx_rst_int = rst_156mhz_int; - -assign sfp3_rx_clk_int = gt_rxusrclk2[3]; - -sync_reset #( - .N(4) -) -sfp3_rx_rst_reset_sync_inst ( - .clk(sfp3_rx_clk_int), - .rst(~gt_reset_rx_done), - .out(sfp3_rx_rst_int) -); - -eth_phy_10g #( - .BIT_REVERSE(1) +eth_xcvr_phy_wrapper #( + .HAS_COMMON(0) ) sfp3_phy_inst ( - .tx_clk(sfp3_tx_clk_int), - .tx_rst(sfp3_tx_rst_int), - .rx_clk(sfp3_rx_clk_int), - .rx_rst(sfp3_rx_rst_int), - .xgmii_txd(sfp3_txd_int), - .xgmii_txc(sfp3_txc_int), - .xgmii_rxd(sfp3_rxd_int), - .xgmii_rxc(sfp3_rxc_int), - .serdes_tx_data(sfp3_gt_txdata), - .serdes_tx_hdr(sfp3_gt_txheader), - .serdes_rx_data(sfp3_gt_rxdata), - .serdes_rx_hdr(sfp3_gt_rxheader), - .serdes_rx_bitslip(sfp3_gt_rxgearboxslip), - .rx_block_lock(sfp3_rx_block_lock), - .rx_high_ber() + .xcvr_ctrl_clk(clk_125mhz_int), + .xcvr_ctrl_rst(rst_125mhz_int), + + // Common + .xcvr_gtpowergood_out(), + + // PLL out + .xcvr_gtrefclk00_in(1'b0), + .xcvr_qpll0lock_out(), + .xcvr_qpll0outclk_out(), + .xcvr_qpll0outrefclk_out(), + + // PLL in + .xcvr_qpll0lock_in(sfp_qpll0lock), + .xcvr_qpll0reset_out(), + .xcvr_qpll0clk_in(sfp_qpll0outclk), + .xcvr_qpll0refclk_in(sfp_qpll0outrefclk), + + // Serial data + .xcvr_txp(sfp3_tx_p), + .xcvr_txn(sfp3_tx_n), + .xcvr_rxp(sfp3_rx_p), + .xcvr_rxn(sfp3_rx_n), + + // PHY connections + .phy_tx_clk(sfp3_tx_clk_int), + .phy_tx_rst(sfp3_tx_rst_int), + .phy_xgmii_txd(sfp3_txd_int), + .phy_xgmii_txc(sfp3_txc_int), + .phy_rx_clk(sfp3_rx_clk_int), + .phy_rx_rst(sfp3_rx_rst_int), + .phy_xgmii_rxd(sfp3_rxd_int), + .phy_xgmii_rxc(sfp3_rxc_int), + .phy_rx_error_count(), + .phy_rx_bad_block(), + .phy_rx_sequence_error(), + .phy_rx_block_lock(sfp3_rx_block_lock), + .phy_rx_high_ber(), + .phy_tx_prbs31_enable(), + .phy_rx_prbs31_enable() ); fpga_core diff --git a/example/ZCU102/fpga/rtl/fpga_core.v b/example/ZCU102/fpga/rtl/fpga_core.v index b55cd06d..b181d52f 100644 --- a/example/ZCU102/fpga/rtl/fpga_core.v +++ b/example/ZCU102/fpga/rtl/fpga_core.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2020 Alex Forencich +Copyright (c) 2020-2021 Alex Forencich Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal