diff --git a/src/eth/rtl/us/taxi_eth_mac_25g_us.f b/src/eth/rtl/us/taxi_eth_mac_25g_us.f index e5cd83a..338d0e2 100644 --- a/src/eth/rtl/us/taxi_eth_mac_25g_us.f +++ b/src/eth/rtl/us/taxi_eth_mac_25g_us.f @@ -2,6 +2,8 @@ taxi_eth_mac_25g_us.sv taxi_eth_mac_25g_us_ch.sv taxi_eth_phy_25g_us_gt.f taxi_eth_phy_25g_us_gt_ll.f +taxi_eth_phy_10g_us_gt.f +taxi_eth_phy_10g_us_gt_ll.f ../taxi_eth_mac_phy_10g.f ../taxi_eth_mac_10g.f ../taxi_eth_phy_10g.f diff --git a/src/eth/rtl/us/taxi_eth_mac_25g_us_ch.sv b/src/eth/rtl/us/taxi_eth_mac_25g_us_ch.sv index 32671c3..c7cafb1 100644 --- a/src/eth/rtl/us/taxi_eth_mac_25g_us_ch.sv +++ b/src/eth/rtl/us/taxi_eth_mac_25g_us_ch.sv @@ -297,7 +297,7 @@ wire [HDR_W-1:0] serdes_rx_hdr; wire serdes_rx_hdr_valid; wire serdes_rx_bitslip; -if (CFG_LOW_LATENCY) begin : gt +if (DATA_W == 64 && CFG_LOW_LATENCY) begin : gt taxi_eth_phy_25g_us_gt_ll #( .SIM(SIM), @@ -406,7 +406,7 @@ if (CFG_LOW_LATENCY) begin : gt .serdes_rx_bitslip(serdes_rx_bitslip) ); -end else begin : gt +end else if (DATA_W == 64 && !CFG_LOW_LATENCY) begin : gt taxi_eth_phy_25g_us_gt #( .SIM(SIM), @@ -515,6 +515,228 @@ end else begin : gt .serdes_rx_bitslip(serdes_rx_bitslip) ); +end else if (DATA_W == 32 && CFG_LOW_LATENCY) begin : gt + + taxi_eth_phy_10g_us_gt_ll #( + .SIM(SIM), + .VENDOR(VENDOR), + .FAMILY(FAMILY), + + .HAS_COMMON(HAS_COMMON), + + // GT type + .GT_TYPE(GT_TYPE), + + // PLL parameters + .QPLL0_PD(QPLL0_PD), + .QPLL1_PD(QPLL1_PD), + .QPLL0_EXT_CTRL(QPLL0_EXT_CTRL), + .QPLL1_EXT_CTRL(QPLL1_EXT_CTRL), + + // GT parameters + .GT_TX_PD(GT_TX_PD), + .GT_TX_QPLL_SEL(GT_TX_QPLL_SEL), + .GT_TX_POLARITY(GT_TX_POLARITY), + .GT_TX_ELECIDLE(GT_TX_ELECIDLE), + .GT_TX_INHIBIT(GT_TX_INHIBIT), + .GT_TX_DIFFCTRL(GT_TX_DIFFCTRL), + .GT_TX_MAINCURSOR(GT_TX_MAINCURSOR), + .GT_TX_POSTCURSOR(GT_TX_POSTCURSOR), + .GT_TX_PRECURSOR(GT_TX_PRECURSOR), + .GT_RX_PD(GT_RX_PD), + .GT_RX_QPLL_SEL(GT_RX_QPLL_SEL), + .GT_RX_LPM_EN(GT_RX_LPM_EN), + .GT_RX_POLARITY(GT_RX_POLARITY), + + // MAC/PHY parameters + .DATA_W(DATA_W), + .HDR_W(HDR_W) + ) + gt_inst ( + .xcvr_ctrl_clk(xcvr_ctrl_clk), + .xcvr_ctrl_rst(xcvr_ctrl_rst), + + /* + * Common + */ + .xcvr_gtpowergood_out(xcvr_gtpowergood_out), + + /* + * PLL out + */ + .xcvr_gtrefclk00_in(xcvr_gtrefclk00_in), + .xcvr_qpll0pd_in(xcvr_qpll0pd_in), + .xcvr_qpll0reset_in(xcvr_qpll0reset_in), + .xcvr_qpll0pcierate_in(xcvr_qpll0pcierate_in), + .xcvr_qpll0lock_out(xcvr_qpll0lock_out), + .xcvr_qpll0clk_out(xcvr_qpll0clk_out), + .xcvr_qpll0refclk_out(xcvr_qpll0refclk_out), + .xcvr_gtrefclk01_in(xcvr_gtrefclk01_in), + .xcvr_qpll1pd_in(xcvr_qpll1pd_in), + .xcvr_qpll1reset_in(xcvr_qpll1reset_in), + .xcvr_qpll1pcierate_in(xcvr_qpll1pcierate_in), + .xcvr_qpll1lock_out(xcvr_qpll1lock_out), + .xcvr_qpll1clk_out(xcvr_qpll1clk_out), + .xcvr_qpll1refclk_out(xcvr_qpll1refclk_out), + + /* + * PLL in + */ + .xcvr_qpll0lock_in(xcvr_qpll0lock_in), + .xcvr_qpll0clk_in(xcvr_qpll0clk_in), + .xcvr_qpll0refclk_in(xcvr_qpll0refclk_in), + .xcvr_qpll1lock_in(xcvr_qpll1lock_in), + .xcvr_qpll1clk_in(xcvr_qpll1clk_in), + .xcvr_qpll1refclk_in(xcvr_qpll1refclk_in), + + /* + * Serial data + */ + .xcvr_txp(xcvr_txp), + .xcvr_txn(xcvr_txn), + .xcvr_rxp(xcvr_rxp), + .xcvr_rxn(xcvr_rxn), + + /* + * GT user clocks + */ + .rx_clk(rx_clk), + .rx_rst_in(rx_rst_in || rx_reset_req), + .rx_rst_out(rx_rst_out), + .tx_clk(tx_clk), + .tx_rst_in(tx_rst_in), + .tx_rst_out(tx_rst_out), + + /* + * Serdes interface + */ + .serdes_tx_data(serdes_tx_data), + .serdes_tx_data_valid(serdes_tx_data_valid), + .serdes_tx_hdr(serdes_tx_hdr), + .serdes_tx_hdr_valid(serdes_tx_hdr_valid), + .serdes_tx_gbx_req_sync(serdes_tx_gbx_req_sync), + .serdes_tx_gbx_req_stall(serdes_tx_gbx_req_stall), + .serdes_tx_gbx_sync(serdes_tx_gbx_sync), + .serdes_rx_data(serdes_rx_data), + .serdes_rx_data_valid(serdes_rx_data_valid), + .serdes_rx_hdr(serdes_rx_hdr), + .serdes_rx_hdr_valid(serdes_rx_hdr_valid), + .serdes_rx_bitslip(serdes_rx_bitslip) + ); + +end else if (DATA_W == 32 && !CFG_LOW_LATENCY) begin : gt + + taxi_eth_phy_10g_us_gt #( + .SIM(SIM), + .VENDOR(VENDOR), + .FAMILY(FAMILY), + + .HAS_COMMON(HAS_COMMON), + + // GT type + .GT_TYPE(GT_TYPE), + + // PLL parameters + .QPLL0_PD(QPLL0_PD), + .QPLL1_PD(QPLL1_PD), + .QPLL0_EXT_CTRL(QPLL0_EXT_CTRL), + .QPLL1_EXT_CTRL(QPLL1_EXT_CTRL), + + // GT parameters + .GT_TX_PD(GT_TX_PD), + .GT_TX_QPLL_SEL(GT_TX_QPLL_SEL), + .GT_TX_POLARITY(GT_TX_POLARITY), + .GT_TX_ELECIDLE(GT_TX_ELECIDLE), + .GT_TX_INHIBIT(GT_TX_INHIBIT), + .GT_TX_DIFFCTRL(GT_TX_DIFFCTRL), + .GT_TX_MAINCURSOR(GT_TX_MAINCURSOR), + .GT_TX_POSTCURSOR(GT_TX_POSTCURSOR), + .GT_TX_PRECURSOR(GT_TX_PRECURSOR), + .GT_RX_PD(GT_RX_PD), + .GT_RX_QPLL_SEL(GT_RX_QPLL_SEL), + .GT_RX_LPM_EN(GT_RX_LPM_EN), + .GT_RX_POLARITY(GT_RX_POLARITY), + + // MAC/PHY parameters + .DATA_W(DATA_W), + .HDR_W(HDR_W) + ) + gt_inst ( + .xcvr_ctrl_clk(xcvr_ctrl_clk), + .xcvr_ctrl_rst(xcvr_ctrl_rst), + + /* + * Common + */ + .xcvr_gtpowergood_out(xcvr_gtpowergood_out), + + /* + * PLL out + */ + .xcvr_gtrefclk00_in(xcvr_gtrefclk00_in), + .xcvr_qpll0pd_in(xcvr_qpll0pd_in), + .xcvr_qpll0reset_in(xcvr_qpll0reset_in), + .xcvr_qpll0pcierate_in(xcvr_qpll0pcierate_in), + .xcvr_qpll0lock_out(xcvr_qpll0lock_out), + .xcvr_qpll0clk_out(xcvr_qpll0clk_out), + .xcvr_qpll0refclk_out(xcvr_qpll0refclk_out), + .xcvr_gtrefclk01_in(xcvr_gtrefclk01_in), + .xcvr_qpll1pd_in(xcvr_qpll1pd_in), + .xcvr_qpll1reset_in(xcvr_qpll1reset_in), + .xcvr_qpll1pcierate_in(xcvr_qpll1pcierate_in), + .xcvr_qpll1lock_out(xcvr_qpll1lock_out), + .xcvr_qpll1clk_out(xcvr_qpll1clk_out), + .xcvr_qpll1refclk_out(xcvr_qpll1refclk_out), + + /* + * PLL in + */ + .xcvr_qpll0lock_in(xcvr_qpll0lock_in), + .xcvr_qpll0clk_in(xcvr_qpll0clk_in), + .xcvr_qpll0refclk_in(xcvr_qpll0refclk_in), + .xcvr_qpll1lock_in(xcvr_qpll1lock_in), + .xcvr_qpll1clk_in(xcvr_qpll1clk_in), + .xcvr_qpll1refclk_in(xcvr_qpll1refclk_in), + + /* + * Serial data + */ + .xcvr_txp(xcvr_txp), + .xcvr_txn(xcvr_txn), + .xcvr_rxp(xcvr_rxp), + .xcvr_rxn(xcvr_rxn), + + /* + * GT user clocks + */ + .rx_clk(rx_clk), + .rx_rst_in(rx_rst_in || rx_reset_req), + .rx_rst_out(rx_rst_out), + .tx_clk(tx_clk), + .tx_rst_in(tx_rst_in), + .tx_rst_out(tx_rst_out), + + /* + * Serdes interface + */ + .serdes_tx_data(serdes_tx_data), + .serdes_tx_data_valid(serdes_tx_data_valid), + .serdes_tx_hdr(serdes_tx_hdr), + .serdes_tx_hdr_valid(serdes_tx_hdr_valid), + .serdes_tx_gbx_req_sync(serdes_tx_gbx_req_sync), + .serdes_tx_gbx_req_stall(serdes_tx_gbx_req_stall), + .serdes_tx_gbx_sync(serdes_tx_gbx_sync), + .serdes_rx_data(serdes_rx_data), + .serdes_rx_data_valid(serdes_rx_data_valid), + .serdes_rx_hdr(serdes_rx_hdr), + .serdes_rx_hdr_valid(serdes_rx_hdr_valid), + .serdes_rx_bitslip(serdes_rx_bitslip) + ); + +end else begin + + $fatal(0, "Error: invalid configuration (%m)"); + end if (COMBINED_MAC_PCS) begin : mac diff --git a/src/eth/rtl/us/taxi_eth_phy_10g_us_gt.f b/src/eth/rtl/us/taxi_eth_phy_10g_us_gt.f new file mode 100644 index 0000000..6be9982 --- /dev/null +++ b/src/eth/rtl/us/taxi_eth_phy_10g_us_gt.f @@ -0,0 +1,6 @@ +taxi_eth_phy_10g_us_gt.sv +../../lib/taxi/src/sync/rtl/taxi_sync_reset.sv +../../lib/taxi/src/sync/rtl/taxi_sync_signal.sv +../../lib/taxi/src/hip/rtl/us/taxi_gt_qpll_reset.sv +../../lib/taxi/src/hip/rtl/us/taxi_gt_rx_reset.sv +../../lib/taxi/src/hip/rtl/us/taxi_gt_tx_reset.sv diff --git a/src/eth/rtl/us/taxi_eth_phy_10g_us_gt.sv b/src/eth/rtl/us/taxi_eth_phy_10g_us_gt.sv new file mode 100644 index 0000000..2f76785 --- /dev/null +++ b/src/eth/rtl/us/taxi_eth_phy_10g_us_gt.sv @@ -0,0 +1,1006 @@ +// SPDX-License-Identifier: CERN-OHL-S-2.0 +/* + +Copyright (c) 2025 FPGA Ninja, LLC + +Authors: +- Alex Forencich + +*/ + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * Transceiver wrapper for UltraScale/UltraScale+ + */ +module taxi_eth_phy_10g_us_gt # +( + parameter logic SIM = 1'b0, + parameter string VENDOR = "XILINX", + parameter string FAMILY = "virtexuplus", + + parameter logic HAS_COMMON = 1'b1, + + // GT type + parameter string GT_TYPE = "GTY", + + // PLL parameters + parameter logic QPLL0_PD = 1'b0, + parameter logic QPLL1_PD = 1'b1, + parameter logic QPLL0_EXT_CTRL = 1'b0, + parameter logic QPLL1_EXT_CTRL = 1'b0, + + // GT parameters + parameter logic GT_TX_PD = 1'b0, + parameter logic GT_TX_QPLL_SEL = 1'b0, + parameter logic GT_TX_POLARITY = 1'b0, + parameter logic GT_TX_ELECIDLE = 1'b0, + parameter logic GT_TX_INHIBIT = 1'b0, + parameter logic [4:0] GT_TX_DIFFCTRL = 5'd16, + parameter logic [6:0] GT_TX_MAINCURSOR = 7'd64, + parameter logic [4:0] GT_TX_POSTCURSOR = 5'd0, + parameter logic [4:0] GT_TX_PRECURSOR = 5'd0, + parameter logic GT_RX_PD = 1'b0, + parameter logic GT_RX_QPLL_SEL = 1'b0, + parameter logic GT_RX_LPM_EN = 1'b0, + parameter logic GT_RX_POLARITY = 1'b0, + + // MAC/PHY parameters + parameter DATA_W = 32, + parameter HDR_W = 2 +) +( + input wire logic xcvr_ctrl_clk, + input wire logic xcvr_ctrl_rst, + + /* + * Common + */ + output wire logic xcvr_gtpowergood_out, + + /* + * PLL out + */ + input wire logic xcvr_gtrefclk00_in = 1'b0, + input wire logic xcvr_qpll0pd_in = 1'b0, + input wire logic xcvr_qpll0reset_in = 1'b0, + input wire logic [2:0] xcvr_qpll0pcierate_in = 3'd0, + output wire logic xcvr_qpll0lock_out, + output wire logic xcvr_qpll0clk_out, + output wire logic xcvr_qpll0refclk_out, + input wire logic xcvr_gtrefclk01_in = 1'b0, + input wire logic xcvr_qpll1pd_in = 1'b0, + input wire logic xcvr_qpll1reset_in = 1'b0, + input wire logic [2:0] xcvr_qpll1pcierate_in = 3'd0, + output wire logic xcvr_qpll1lock_out, + output wire logic xcvr_qpll1clk_out, + output wire logic xcvr_qpll1refclk_out, + + /* + * PLL in + */ + input wire logic xcvr_qpll0lock_in = 1'b0, + input wire logic xcvr_qpll0clk_in = 1'b0, + input wire logic xcvr_qpll0refclk_in = 1'b0, + input wire logic xcvr_qpll1lock_in = 1'b0, + input wire logic xcvr_qpll1clk_in = 1'b0, + input wire logic xcvr_qpll1refclk_in = 1'b0, + + /* + * Serial data + */ + output wire logic xcvr_txp, + output wire logic xcvr_txn, + input wire logic xcvr_rxp, + input wire logic xcvr_rxn, + + /* + * GT user clocks + */ + output wire logic rx_clk, + input wire logic rx_rst_in = 1'b0, + output wire logic rx_rst_out, + output wire logic tx_clk, + input wire logic tx_rst_in = 1'b0, + output wire logic tx_rst_out, + + /* + * Serdes interface + */ + input wire logic [DATA_W-1:0] serdes_tx_data, + input wire logic serdes_tx_data_valid, + input wire logic [HDR_W-1:0] serdes_tx_hdr, + input wire logic serdes_tx_hdr_valid, + output wire logic serdes_tx_gbx_req_sync, + output wire logic serdes_tx_gbx_req_stall, + input wire logic serdes_tx_gbx_sync, + output wire logic [DATA_W-1:0] serdes_rx_data, + output wire logic serdes_rx_data_valid, + output wire logic [HDR_W-1:0] serdes_rx_hdr, + output wire logic serdes_rx_hdr_valid, + input wire logic serdes_rx_bitslip +); + +localparam GT_USP = FAMILY == "kintexuplus" || FAMILY == "virtexuplus" || FAMILY == "virtexuplusHBM" + || FAMILY == "virtexuplus58G" || FAMILY == "zynquplus" || FAMILY == "zynquplusRFSOC"; + +// check configuration +if (DATA_W != 32) + $fatal(0, "Error: Interface width must be 32"); + +if (HDR_W != 2) + $fatal(0, "Error: HDR_W must be 2"); + +wire xcvr_ctrl_rst_sync; + +taxi_sync_reset #( + .N(4) +) +reset_sync_inst ( + .clk(xcvr_ctrl_clk), + .rst(xcvr_ctrl_rst), + .out(xcvr_ctrl_rst_sync) +); + +wire gt_qpll0_pd; +wire gt_qpll0_reset; +wire gt_qpll1_pd; +wire gt_qpll1_reset; + +wire qpll0_lock; +wire qpll1_lock; + +if (HAS_COMMON) begin : common_ctrl + + taxi_gt_qpll_reset #( + .QPLL_PD(QPLL0_PD), + .CNT_W(8) + ) + qpll0_reset_inst ( + .clk(xcvr_ctrl_clk), + .rst(xcvr_ctrl_rst_sync), + + /* + * GT + */ + .gt_qpll_reset_out(gt_qpll0_reset), + .gt_qpll_pd_out(gt_qpll0_pd), + .gt_qpll_lock_in(xcvr_qpll0lock_out), + + /* + * Control/status + */ + .qpll_reset_in(1'b0), + .qpll_pd_in(QPLL0_PD), + .qpll_lock_out(qpll0_lock) + ); + + taxi_gt_qpll_reset #( + .QPLL_PD(QPLL1_PD), + .CNT_W(8) + ) + qpll1_reset_inst ( + .clk(xcvr_ctrl_clk), + .rst(xcvr_ctrl_rst_sync), + + /* + * GT + */ + .gt_qpll_reset_out(gt_qpll1_reset), + .gt_qpll_pd_out(gt_qpll1_pd), + .gt_qpll_lock_in(xcvr_qpll1lock_out), + + /* + * Control/status + */ + .qpll_reset_in(1'b0), + .qpll_pd_in(QPLL1_PD), + .qpll_lock_out(qpll1_lock) + ); + +end else begin : common_ctrl + + assign gt_qpll0_pd = 1'b1; + assign gt_qpll0_reset = 1'b1; + assign gt_qpll1_pd = 1'b1; + assign gt_qpll1_reset = 1'b1; + + taxi_sync_signal #( + .WIDTH(2), + .N(2) + ) + qpll_lock_sync_inst ( + .clk(xcvr_ctrl_clk), + .in({xcvr_qpll1lock_in, xcvr_qpll0lock_in}), + .out({qpll1_lock, qpll0_lock}) + ); + +end + +wire gt_tx_pd; +wire gt_tx_reset; +wire gt_tx_reset_done; +wire gt_userclk_tx_active; +wire gt_tx_pma_reset; +wire gt_tx_pcs_reset; +wire gt_tx_pma_reset_done; +wire gt_tx_prgdiv_reset; +wire gt_tx_prgdiv_reset_done; +wire gt_tx_qpll_sel; +wire gt_tx_userrdy; + +wire tx_reset_done; + +taxi_sync_reset #( + .N(4) +) +tx_reset_sync_inst ( + .clk(tx_clk), + .rst(!tx_reset_done || tx_rst_in), + .out(tx_rst_out) +); + +taxi_gt_tx_reset #( + .GT_TX_PD(GT_TX_PD), + .GT_TX_QPLL_SEL(GT_TX_QPLL_SEL), + .CNT_W(8) +) +gt_tx_reset_inst ( + .clk(xcvr_ctrl_clk), + .rst(xcvr_ctrl_rst_sync), + + /* + * GT + */ + .gt_tx_pd_out(gt_tx_pd), + .gt_tx_reset_out(gt_tx_reset), + .gt_tx_reset_done_in(gt_tx_reset_done), + .gt_userclk_tx_active_in(gt_userclk_tx_active), + .gt_tx_pma_reset_out(gt_tx_pma_reset), + .gt_tx_pcs_reset_out(gt_tx_pcs_reset), + .gt_tx_pma_reset_done_in(gt_tx_pma_reset_done), + .gt_tx_prgdiv_reset_out(gt_tx_prgdiv_reset), + .gt_tx_prgdiv_reset_done_in(gt_tx_prgdiv_reset_done), + .gt_tx_qpll_sel_out(gt_tx_qpll_sel), + .gt_tx_userrdy_out(gt_tx_userrdy), + + /* + * Control/status + */ + .qpll0_lock_in(qpll0_lock), + .qpll1_lock_in(qpll1_lock), + .tx_reset_in(tx_rst_in), + .tx_reset_done_out(tx_reset_done), + .tx_pma_reset_in(1'b0), + .tx_pma_reset_done_out(), + .tx_prgdiv_reset_done_out(), + .tx_pcs_reset_in(1'b0), + .tx_pd_in(GT_TX_PD), + .tx_qpll_sel_in(GT_TX_QPLL_SEL) +); + +wire gt_rx_pd; +wire gt_rx_reset; +wire gt_rx_reset_done; +wire gt_userclk_rx_active; +wire gt_rx_pma_reset; +wire gt_rx_dfe_lpm_reset; +wire gt_rx_eyescan_reset; +wire gt_rx_pcs_reset; +wire gt_rx_pma_reset_done; +wire gt_rx_prgdiv_reset; +wire gt_rx_prgdiv_reset_done; +wire gt_rx_qpll_sel; +wire gt_rx_userrdy; +wire gt_rx_cdr_lock; +wire gt_rx_lpm_en; + +wire rx_reset_done; + +taxi_sync_reset #( + .N(4) +) +rx_reset_sync_inst ( + .clk(rx_clk), + .rst(!rx_reset_done || rx_rst_in), + .out(rx_rst_out) +); + +taxi_gt_rx_reset #( + .GT_RX_PD(GT_RX_PD), + .GT_RX_QPLL_SEL(GT_RX_QPLL_SEL), + .GT_RX_LPM_EN(GT_RX_LPM_EN), + .CNT_W(8), + .CDR_CNT_W(20) +) +gt_rx_reset_inst ( + .clk(xcvr_ctrl_clk), + .rst(xcvr_ctrl_rst_sync), + + /* + * GT + */ + .gt_rx_pd_out(gt_rx_pd), + .gt_rx_reset_out(gt_rx_reset), + .gt_rx_reset_done_in(gt_rx_reset_done), + .gt_userclk_rx_active_in(gt_userclk_rx_active), + .gt_rx_pma_reset_out(gt_rx_pma_reset), + .gt_rx_dfe_lpm_reset_out(gt_rx_dfe_lpm_reset), + .gt_rx_eyescan_reset_out(gt_rx_eyescan_reset), + .gt_rx_pcs_reset_out(gt_rx_pcs_reset), + .gt_rx_pma_reset_done_in(gt_rx_pma_reset_done), + .gt_rx_prgdiv_reset_out(gt_rx_prgdiv_reset), + .gt_rx_prgdiv_reset_done_in(gt_rx_prgdiv_reset_done), + .gt_rx_qpll_sel_out(gt_rx_qpll_sel), + .gt_rx_userrdy_out(gt_rx_userrdy), + .gt_rx_cdr_lock_in(gt_rx_cdr_lock), + .gt_rx_lpm_en_out(gt_rx_lpm_en), + + /* + * Control/status + */ + .qpll0_lock_in(qpll0_lock), + .qpll1_lock_in(qpll1_lock), + .rx_reset_in(rx_rst_in), + .rx_reset_done_out(rx_reset_done), + .rx_pma_reset_in(1'b0), + .rx_pma_reset_done_out(), + .rx_prgdiv_reset_done_out(), + .rx_pcs_reset_in(1'b0), + .rx_dfe_lpm_reset_in(1'b0), + .eyescan_reset_in(1'b0), + .rx_pd_in(GT_RX_PD), + .rx_qpll_sel_in(GT_RX_QPLL_SEL), + .rx_lpm_en_in(GT_RX_LPM_EN) +); + +wire [6:0] gt_txsequence; +wire [5:0] gt_txheader; +wire [31:0] gt_txdata; +wire gt_rxgearboxslip; +wire [1:0] gt_rxstartofseq; +wire [5:0] gt_rxheader; +wire [1:0] gt_rxheadervalid; +wire [31:0] gt_rxdata; +wire [1:0] gt_rxdatavalid; + +assign gt_txsequence = {6'd0, ~serdes_tx_hdr_valid}; +assign gt_txdata = serdes_tx_data; +assign gt_txheader = {4'd0, serdes_tx_hdr}; +assign gt_rxgearboxslip = serdes_rx_bitslip; + +if (!SIM) begin + assign serdes_rx_data = gt_rxdata; + assign serdes_rx_data_valid = gt_rxdatavalid; + assign serdes_rx_hdr = gt_rxheader[1:0]; + assign serdes_rx_hdr_valid = gt_rxheadervalid[0]; +end + +assign serdes_tx_gbx_req_sync = 1'b0; +assign serdes_tx_gbx_req_stall = 1'b0; + +if (SIM) begin : xcvr + // simulation (no GT core) + + assign xcvr_gtpowergood_out = 1'b1; + + assign xcvr_qpll0lock_out = !gt_qpll0_reset && !gt_qpll0_pd; + assign xcvr_qpll0clk_out = 1'b0; + assign xcvr_qpll0refclk_out = xcvr_gtrefclk00_in; + + assign xcvr_qpll1lock_out = !gt_qpll1_reset && !gt_qpll0_pd; + assign xcvr_qpll1clk_out = 1'b0; + assign xcvr_qpll1refclk_out = xcvr_gtrefclk01_in; + + assign gt_tx_reset_done = !gt_tx_reset; + assign gt_userclk_tx_active = gt_tx_qpll_sel ? qpll1_lock : qpll0_lock; + assign gt_tx_pma_reset_done = gt_tx_reset_done; + assign gt_tx_prgdiv_reset_done = gt_tx_reset_done; + + assign gt_rx_reset_done = !gt_rx_reset; + assign gt_userclk_rx_active = gt_rx_qpll_sel ? qpll1_lock : qpll0_lock; + assign gt_rx_pma_reset_done = gt_rx_reset_done; + assign gt_rx_prgdiv_reset_done = gt_rx_reset_done; + assign gt_rx_cdr_lock = gt_rx_reset_done; + +end else if (HAS_COMMON && GT_TYPE == "GTY" && GT_USP) begin : xcvr + // UltraScale+ GTY (with common) + + taxi_eth_phy_10g_us_gty_full + taxi_eth_phy_10g_us_gty_full_inst ( + // Common + .gtpowergood_out(xcvr_gtpowergood_out), + + // PLL + .gtrefclk00_in(xcvr_gtrefclk00_in), + .qpll0lock_out(xcvr_qpll0lock_out), + .qpll0outclk_out(xcvr_qpll0clk_out), + .qpll0outrefclk_out(xcvr_qpll0refclk_out), + .gtrefclk01_in(xcvr_gtrefclk01_in), + .qpll1lock_out(xcvr_qpll1lock_out), + .qpll1outclk_out(xcvr_qpll1clk_out), + .qpll1outrefclk_out(xcvr_qpll1refclk_out), + + .qpll0pd_in(QPLL0_EXT_CTRL ? xcvr_qpll0pd_in : gt_qpll0_pd), + .qpll0reset_in(QPLL0_EXT_CTRL ? xcvr_qpll0reset_in : gt_qpll0_reset), + .qpll1pd_in(QPLL1_EXT_CTRL ? xcvr_qpll1pd_in : gt_qpll1_pd), + .qpll1reset_in(QPLL1_EXT_CTRL ? xcvr_qpll1reset_in : gt_qpll1_reset), + + .pcierateqpll0_in(QPLL0_EXT_CTRL ? xcvr_qpll0pcierate_in : 3'd0), + .pcierateqpll1_in(QPLL1_EXT_CTRL ? xcvr_qpll1pcierate_in : 3'd0), + + // Serial data + .gtytxp_out(xcvr_txp), + .gtytxn_out(xcvr_txn), + .gtyrxp_in(xcvr_rxp), + .gtyrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_reset_in(gt_tx_reset), + .gtwiz_userclk_tx_srcclk_out(), + .gtwiz_userclk_tx_usrclk_out(), + .gtwiz_userclk_tx_usrclk2_out(tx_clk), + .gtwiz_userclk_tx_active_out(gt_userclk_tx_active), + .gtwiz_reset_tx_done_in(tx_reset_done), + .txpdelecidlemode_in(1'b1), + .txpd_in(gt_tx_pd ? 2'b11 : 2'b00), + .gttxreset_in(gt_tx_reset), + .txpmareset_in(gt_tx_pma_reset), + .txpcsreset_in(gt_tx_pcs_reset), + .txresetdone_out(gt_tx_reset_done), + .txpmaresetdone_out(gt_tx_pma_reset_done), + .txprogdivreset_in(gt_tx_prgdiv_reset), + .txprgdivresetdone_out(gt_tx_prgdiv_reset_done), + .txpllclksel_in(gt_tx_qpll_sel ? 2'b10 : 2'b11), + .txsysclksel_in(gt_tx_qpll_sel ? 2'b11 : 2'b10), + .txuserrdy_in(gt_tx_userrdy), + + .txpolarity_in(GT_TX_POLARITY), + .txelecidle_in(GT_TX_ELECIDLE), + .txinhibit_in(GT_TX_INHIBIT), + .txdiffctrl_in(GT_TX_DIFFCTRL), + .txmaincursor_in(GT_TX_MAINCURSOR), + .txprecursor_in(GT_TX_PRECURSOR), + .txpostcursor_in(GT_TX_POSTCURSOR), + + .gtwiz_userdata_tx_in(gt_txdata), + .txheader_in(gt_txheader), + .txsequence_in(gt_txsequence), + + // Receive + .gtwiz_userclk_rx_reset_in(gt_rx_reset), + .gtwiz_userclk_rx_srcclk_out(), + .gtwiz_userclk_rx_usrclk_out(), + .gtwiz_userclk_rx_usrclk2_out(rx_clk), + .gtwiz_userclk_rx_active_out(gt_userclk_rx_active), + .gtwiz_reset_rx_done_in(rx_reset_done), + .rxpd_in(gt_rx_pd ? 2'b11 : 2'b00), + .gtrxreset_in(gt_rx_reset), + .rxpmareset_in(gt_rx_pma_reset), + .rxdfelpmreset_in(gt_rx_dfe_lpm_reset), + .eyescanreset_in(gt_rx_eyescan_reset), + .rxpcsreset_in(gt_rx_pcs_reset), + .rxresetdone_out(gt_rx_reset_done), + .rxpmaresetdone_out(gt_rx_pma_reset_done), + .rxprogdivreset_in(gt_rx_prgdiv_reset), + .rxprgdivresetdone_out(gt_rx_prgdiv_reset_done), + .rxpllclksel_in(gt_rx_qpll_sel ? 2'b10 : 2'b11), + .rxsysclksel_in(gt_rx_qpll_sel ? 2'b11 : 2'b10), + .rxuserrdy_in(gt_rx_userrdy), + + .rxcdrlock_out(gt_rx_cdr_lock), + .rxcdrhold_in(1'b0), + .rxcdrovrden_in(1'b0), + + .rxlpmen_in(gt_rx_lpm_en), + + .rxpolarity_in(GT_RX_POLARITY), + + .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 if (HAS_COMMON && GT_TYPE == "GTH" && GT_USP) begin : xcvr + // UltraScale+ GTH (with common) + + taxi_eth_phy_10g_us_gth_full + taxi_eth_phy_10g_us_gth_full_inst ( + // Common + .gtpowergood_out(xcvr_gtpowergood_out), + + // PLL + .gtrefclk00_in(xcvr_gtrefclk00_in), + .qpll0lock_out(xcvr_qpll0lock_out), + .qpll0outclk_out(xcvr_qpll0clk_out), + .qpll0outrefclk_out(xcvr_qpll0refclk_out), + .gtrefclk01_in(xcvr_gtrefclk01_in), + .qpll1lock_out(xcvr_qpll1lock_out), + .qpll1outclk_out(xcvr_qpll1clk_out), + .qpll1outrefclk_out(xcvr_qpll1refclk_out), + + .qpll0pd_in(QPLL0_EXT_CTRL ? xcvr_qpll0pd_in : gt_qpll0_pd), + .qpll0reset_in(QPLL0_EXT_CTRL ? xcvr_qpll0reset_in : gt_qpll0_reset), + .qpll1pd_in(QPLL1_EXT_CTRL ? xcvr_qpll1pd_in : gt_qpll1_pd), + .qpll1reset_in(QPLL1_EXT_CTRL ? xcvr_qpll1reset_in : gt_qpll1_reset), + + .pcierateqpll0_in(QPLL0_EXT_CTRL ? xcvr_qpll0pcierate_in : 3'd0), + .pcierateqpll1_in(QPLL1_EXT_CTRL ? xcvr_qpll1pcierate_in : 3'd0), + + // Serial data + .gthtxp_out(xcvr_txp), + .gthtxn_out(xcvr_txn), + .gthrxp_in(xcvr_rxp), + .gthrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_reset_in(gt_tx_reset), + .gtwiz_userclk_tx_srcclk_out(), + .gtwiz_userclk_tx_usrclk_out(), + .gtwiz_userclk_tx_usrclk2_out(tx_clk), + .gtwiz_userclk_tx_active_out(gt_userclk_tx_active), + .gtwiz_reset_tx_done_in(tx_reset_done), + .txpdelecidlemode_in(1'b1), + .txpd_in(gt_tx_pd ? 2'b11 : 2'b00), + .gttxreset_in(gt_tx_reset), + .txpmareset_in(gt_tx_pma_reset), + .txpcsreset_in(gt_tx_pcs_reset), + .txresetdone_out(gt_tx_reset_done), + .txpmaresetdone_out(gt_tx_pma_reset_done), + .txprogdivreset_in(gt_tx_prgdiv_reset), + .txprgdivresetdone_out(gt_tx_prgdiv_reset_done), + .txpllclksel_in(gt_tx_qpll_sel ? 2'b10 : 2'b11), + .txsysclksel_in(gt_tx_qpll_sel ? 2'b11 : 2'b10), + .txuserrdy_in(gt_tx_userrdy), + + .txpolarity_in(GT_TX_POLARITY), + .txelecidle_in(GT_TX_ELECIDLE), + .txinhibit_in(GT_TX_INHIBIT), + .txdiffctrl_in(GT_TX_DIFFCTRL), + .txmaincursor_in(GT_TX_MAINCURSOR), + .txprecursor_in(GT_TX_PRECURSOR), + .txpostcursor_in(GT_TX_POSTCURSOR), + + .gtwiz_userdata_tx_in(gt_txdata), + .txheader_in(gt_txheader), + .txsequence_in(gt_txsequence), + + // Receive + .gtwiz_userclk_rx_reset_in(gt_rx_reset), + .gtwiz_userclk_rx_srcclk_out(), + .gtwiz_userclk_rx_usrclk_out(), + .gtwiz_userclk_rx_usrclk2_out(rx_clk), + .gtwiz_userclk_rx_active_out(gt_userclk_rx_active), + .gtwiz_reset_rx_done_in(rx_reset_done), + .rxpd_in(gt_rx_pd ? 2'b11 : 2'b00), + .gtrxreset_in(gt_rx_reset), + .rxpmareset_in(gt_rx_pma_reset), + .rxdfelpmreset_in(gt_rx_dfe_lpm_reset), + .eyescanreset_in(gt_rx_eyescan_reset), + .rxpcsreset_in(gt_rx_pcs_reset), + .rxresetdone_out(gt_rx_reset_done), + .rxpmaresetdone_out(gt_rx_pma_reset_done), + .rxprogdivreset_in(gt_rx_prgdiv_reset), + .rxprgdivresetdone_out(gt_rx_prgdiv_reset_done), + .rxpllclksel_in(gt_rx_qpll_sel ? 2'b10 : 2'b11), + .rxsysclksel_in(gt_rx_qpll_sel ? 2'b11 : 2'b10), + .rxuserrdy_in(gt_rx_userrdy), + + .rxcdrlock_out(gt_rx_cdr_lock), + .rxcdrhold_in(1'b0), + .rxcdrovrden_in(1'b0), + + .rxlpmen_in(gt_rx_lpm_en), + + .rxpolarity_in(GT_RX_POLARITY), + + .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 if (HAS_COMMON && GT_TYPE == "GTY" && !GT_USP) begin : xcvr + // UltraScale GTY (with common) + + taxi_eth_phy_10g_us_gty_full + taxi_eth_phy_10g_us_gty_full_inst ( + // Common + .gtpowergood_out(xcvr_gtpowergood_out), + + // PLL + .gtrefclk00_in(xcvr_gtrefclk00_in), + .qpll0lock_out(xcvr_qpll0lock_out), + .qpll0outclk_out(xcvr_qpll0clk_out), + .qpll0outrefclk_out(xcvr_qpll0refclk_out), + .gtrefclk01_in(xcvr_gtrefclk01_in), + .qpll1lock_out(xcvr_qpll1lock_out), + .qpll1outclk_out(xcvr_qpll1clk_out), + .qpll1outrefclk_out(xcvr_qpll1refclk_out), + + .qpll0pd_in(QPLL0_EXT_CTRL ? xcvr_qpll0pd_in : gt_qpll0_pd), + .qpll0reset_in(QPLL0_EXT_CTRL ? xcvr_qpll0reset_in : gt_qpll0_reset), + .qpll1pd_in(QPLL1_EXT_CTRL ? xcvr_qpll1pd_in : gt_qpll1_pd), + .qpll1reset_in(QPLL1_EXT_CTRL ? xcvr_qpll1reset_in : gt_qpll1_reset), + + .qpllrsvd2_in(QPLL0_EXT_CTRL ? {2'd0, xcvr_qpll0pcierate_in} : 5'd0), // [2:0] : QPLL0 rate + .qpllrsvd3_in(QPLL1_EXT_CTRL ? {2'd0, xcvr_qpll1pcierate_in} : 5'd0), // [2:0] : QPLL1 rate + + // Serial data + .gtytxp_out(xcvr_txp), + .gtytxn_out(xcvr_txn), + .gtyrxp_in(xcvr_rxp), + .gtyrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_reset_in(gt_tx_reset), + .gtwiz_userclk_tx_srcclk_out(), + .gtwiz_userclk_tx_usrclk_out(), + .gtwiz_userclk_tx_usrclk2_out(tx_clk), + .gtwiz_userclk_tx_active_out(gt_userclk_tx_active), + .gtwiz_reset_tx_done_in(tx_reset_done), + .txpdelecidlemode_in(1'b1), + .txpd_in(gt_tx_pd ? 2'b11 : 2'b00), + .gttxreset_in(gt_tx_reset), + .txpmareset_in(gt_tx_pma_reset), + .txpcsreset_in(gt_tx_pcs_reset), + .txresetdone_out(gt_tx_reset_done), + .txpmaresetdone_out(gt_tx_pma_reset_done), + .txprogdivreset_in(gt_tx_prgdiv_reset), + .txprgdivresetdone_out(gt_tx_prgdiv_reset_done), + .txpllclksel_in(gt_tx_qpll_sel ? 2'b10 : 2'b11), + .txsysclksel_in(gt_tx_qpll_sel ? 2'b11 : 2'b10), + .txuserrdy_in(gt_tx_userrdy), + + .txpolarity_in(GT_TX_POLARITY), + .txelecidle_in(GT_TX_ELECIDLE), + .txinhibit_in(GT_TX_INHIBIT), + .txdiffctrl_in(GT_TX_DIFFCTRL), + .txmaincursor_in(GT_TX_MAINCURSOR), + .txprecursor_in(GT_TX_PRECURSOR), + .txpostcursor_in(GT_TX_POSTCURSOR), + + .gtwiz_userdata_tx_in(gt_txdata), + .txheader_in(gt_txheader), + .txsequence_in(gt_txsequence), + + // Receive + .gtwiz_userclk_rx_reset_in(gt_rx_reset), + .gtwiz_userclk_rx_srcclk_out(), + .gtwiz_userclk_rx_usrclk_out(), + .gtwiz_userclk_rx_usrclk2_out(rx_clk), + .gtwiz_userclk_rx_active_out(gt_userclk_rx_active), + .gtwiz_reset_rx_done_in(rx_reset_done), + .rxpd_in(gt_rx_pd ? 2'b11 : 2'b00), + .gtrxreset_in(gt_rx_reset), + .rxpmareset_in(gt_rx_pma_reset), + .rxdfelpmreset_in(gt_rx_dfe_lpm_reset), + .eyescanreset_in(gt_rx_eyescan_reset), + .rxpcsreset_in(gt_rx_pcs_reset), + .rxresetdone_out(gt_rx_reset_done), + .rxpmaresetdone_out(gt_rx_pma_reset_done), + .rxprogdivreset_in(gt_rx_prgdiv_reset), + .rxprgdivresetdone_out(gt_rx_prgdiv_reset_done), + .rxpllclksel_in(gt_rx_qpll_sel ? 2'b10 : 2'b11), + .rxsysclksel_in(gt_rx_qpll_sel ? 2'b11 : 2'b10), + .rxuserrdy_in(gt_rx_userrdy), + + .rxcdrlock_out(gt_rx_cdr_lock), + .rxcdrhold_in(1'b0), + .rxcdrovrden_in(1'b0), + + .rxlpmen_in(gt_rx_lpm_en), + + .rxpolarity_in(GT_RX_POLARITY), + + .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 if (HAS_COMMON && GT_TYPE == "GTH" && !GT_USP) begin : xcvr + // UltraScale GTH (with common) + + taxi_eth_phy_10g_us_gth_full + taxi_eth_phy_10g_us_gth_full_inst ( + // Common + .gtpowergood_out(xcvr_gtpowergood_out), + + // PLL + .gtrefclk00_in(xcvr_gtrefclk00_in), + .qpll0lock_out(xcvr_qpll0lock_out), + .qpll0outclk_out(xcvr_qpll0clk_out), + .qpll0outrefclk_out(xcvr_qpll0refclk_out), + .gtrefclk01_in(xcvr_gtrefclk01_in), + .qpll1lock_out(xcvr_qpll1lock_out), + .qpll1outclk_out(xcvr_qpll1clk_out), + .qpll1outrefclk_out(xcvr_qpll1refclk_out), + + .qpll0pd_in(QPLL0_EXT_CTRL ? xcvr_qpll0pd_in : gt_qpll0_pd), + .qpll0reset_in(QPLL0_EXT_CTRL ? xcvr_qpll0reset_in : gt_qpll0_reset), + .qpll1pd_in(QPLL1_EXT_CTRL ? xcvr_qpll1pd_in : gt_qpll1_pd), + .qpll1reset_in(QPLL1_EXT_CTRL ? xcvr_qpll1reset_in : gt_qpll1_reset), + + .qpllrsvd2_in(QPLL0_EXT_CTRL ? {2'd0, xcvr_qpll0pcierate_in} : 5'd0), // [2:0] : QPLL0 rate + .qpllrsvd3_in(QPLL1_EXT_CTRL ? {2'd0, xcvr_qpll1pcierate_in} : 5'd0), // [2:0] : QPLL1 rate + + // Serial data + .gthtxp_out(xcvr_txp), + .gthtxn_out(xcvr_txn), + .gthrxp_in(xcvr_rxp), + .gthrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_reset_in(gt_tx_reset), + .gtwiz_userclk_tx_srcclk_out(), + .gtwiz_userclk_tx_usrclk_out(), + .gtwiz_userclk_tx_usrclk2_out(tx_clk), + .gtwiz_userclk_tx_active_out(gt_userclk_tx_active), + .gtwiz_reset_tx_done_in(tx_reset_done), + .txpdelecidlemode_in(1'b1), + .txpd_in(gt_tx_pd ? 2'b11 : 2'b00), + .gttxreset_in(gt_tx_reset), + .txpmareset_in(gt_tx_pma_reset), + .txpcsreset_in(gt_tx_pcs_reset), + .txresetdone_out(gt_tx_reset_done), + .txpmaresetdone_out(gt_tx_pma_reset_done), + .txprogdivreset_in(gt_tx_prgdiv_reset), + .txprgdivresetdone_out(gt_tx_prgdiv_reset_done), + .txpllclksel_in(gt_tx_qpll_sel ? 2'b10 : 2'b11), + .txsysclksel_in(gt_tx_qpll_sel ? 2'b11 : 2'b10), + .txuserrdy_in(gt_tx_userrdy), + + .txpolarity_in(GT_TX_POLARITY), + .txelecidle_in(GT_TX_ELECIDLE), + .txinhibit_in(GT_TX_INHIBIT), + .txdiffctrl_in(GT_TX_DIFFCTRL), + .txmaincursor_in(GT_TX_MAINCURSOR), + .txprecursor_in(GT_TX_PRECURSOR), + .txpostcursor_in(GT_TX_POSTCURSOR), + + .gtwiz_userdata_tx_in(gt_txdata), + .txheader_in(gt_txheader), + .txsequence_in(gt_txsequence), + + // Receive + .gtwiz_userclk_rx_reset_in(gt_rx_reset), + .gtwiz_userclk_rx_srcclk_out(), + .gtwiz_userclk_rx_usrclk_out(), + .gtwiz_userclk_rx_usrclk2_out(rx_clk), + .gtwiz_userclk_rx_active_out(gt_userclk_rx_active), + .gtwiz_reset_rx_done_in(rx_reset_done), + .rxpd_in(gt_rx_pd ? 2'b11 : 2'b00), + .gtrxreset_in(gt_rx_reset), + .rxpmareset_in(gt_rx_pma_reset), + .rxdfelpmreset_in(gt_rx_dfe_lpm_reset), + .eyescanreset_in(gt_rx_eyescan_reset), + .rxpcsreset_in(gt_rx_pcs_reset), + .rxresetdone_out(gt_rx_reset_done), + .rxpmaresetdone_out(gt_rx_pma_reset_done), + .rxprogdivreset_in(gt_rx_prgdiv_reset), + .rxprgdivresetdone_out(gt_rx_prgdiv_reset_done), + .rxpllclksel_in(gt_rx_qpll_sel ? 2'b10 : 2'b11), + .rxsysclksel_in(gt_rx_qpll_sel ? 2'b11 : 2'b10), + .rxuserrdy_in(gt_rx_userrdy), + + .rxcdrlock_out(gt_rx_cdr_lock), + .rxcdrhold_in(1'b0), + .rxcdrovrden_in(1'b0), + + .rxlpmen_in(gt_rx_lpm_en), + + .rxpolarity_in(GT_RX_POLARITY), + + .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 if (!HAS_COMMON && GT_TYPE == "GTY") begin : xcvr + // UltraScale/UltraScale+ GTY (channel only) + + taxi_eth_phy_10g_us_gty_ch + taxi_eth_phy_10g_us_gty_ch_inst ( + // Common + .gtpowergood_out(xcvr_gtpowergood_out), + + // PLL + .qpll0clk_in(xcvr_qpll0clk_in), + .qpll0refclk_in(xcvr_qpll0refclk_in), + .qpll1clk_in(xcvr_qpll1clk_in), + .qpll1refclk_in(xcvr_qpll1refclk_in), + + // Serial data + .gtytxp_out(xcvr_txp), + .gtytxn_out(xcvr_txn), + .gtyrxp_in(xcvr_rxp), + .gtyrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_reset_in(gt_tx_reset), + .gtwiz_userclk_tx_srcclk_out(), + .gtwiz_userclk_tx_usrclk_out(), + .gtwiz_userclk_tx_usrclk2_out(tx_clk), + .gtwiz_userclk_tx_active_out(gt_userclk_tx_active), + .gtwiz_reset_tx_done_in(tx_reset_done), + .txpdelecidlemode_in(1'b1), + .txpd_in(gt_tx_pd ? 2'b11 : 2'b00), + .gttxreset_in(gt_tx_reset), + .txpmareset_in(gt_tx_pma_reset), + .txpcsreset_in(gt_tx_pcs_reset), + .txresetdone_out(gt_tx_reset_done), + .txpmaresetdone_out(gt_tx_pma_reset_done), + .txprogdivreset_in(gt_tx_prgdiv_reset), + .txprgdivresetdone_out(gt_tx_prgdiv_reset_done), + .txpllclksel_in(gt_tx_qpll_sel ? 2'b10 : 2'b11), + .txsysclksel_in(gt_tx_qpll_sel ? 2'b11 : 2'b10), + .txuserrdy_in(gt_tx_userrdy), + + .txpolarity_in(GT_TX_POLARITY), + .txelecidle_in(GT_TX_ELECIDLE), + .txinhibit_in(GT_TX_INHIBIT), + .txdiffctrl_in(GT_TX_DIFFCTRL), + .txmaincursor_in(GT_TX_MAINCURSOR), + .txprecursor_in(GT_TX_PRECURSOR), + .txpostcursor_in(GT_TX_POSTCURSOR), + + .gtwiz_userdata_tx_in(gt_txdata), + .txheader_in(gt_txheader), + .txsequence_in(gt_txsequence), + + // Receive + .gtwiz_userclk_rx_reset_in(gt_rx_reset), + .gtwiz_userclk_rx_srcclk_out(), + .gtwiz_userclk_rx_usrclk_out(), + .gtwiz_userclk_rx_usrclk2_out(rx_clk), + .gtwiz_userclk_rx_active_out(gt_userclk_rx_active), + .gtwiz_reset_rx_done_in(rx_reset_done), + .rxpd_in(gt_rx_pd ? 2'b11 : 2'b00), + .gtrxreset_in(gt_rx_reset), + .rxpmareset_in(gt_rx_pma_reset), + .rxdfelpmreset_in(gt_rx_dfe_lpm_reset), + .eyescanreset_in(gt_rx_eyescan_reset), + .rxpcsreset_in(gt_rx_pcs_reset), + .rxresetdone_out(gt_rx_reset_done), + .rxpmaresetdone_out(gt_rx_pma_reset_done), + .rxprogdivreset_in(gt_rx_prgdiv_reset), + .rxprgdivresetdone_out(gt_rx_prgdiv_reset_done), + .rxpllclksel_in(gt_rx_qpll_sel ? 2'b10 : 2'b11), + .rxsysclksel_in(gt_rx_qpll_sel ? 2'b11 : 2'b10), + .rxuserrdy_in(gt_rx_userrdy), + + .rxcdrlock_out(gt_rx_cdr_lock), + .rxcdrhold_in(1'b0), + .rxcdrovrden_in(1'b0), + + .rxlpmen_in(gt_rx_lpm_en), + + .rxpolarity_in(GT_RX_POLARITY), + + .rxgearboxslip_in(gt_rxgearboxslip), + .gtwiz_userdata_rx_out(gt_rxdata), + .rxdatavalid_out(gt_rxdatavalid), + .rxheader_out(gt_rxheader), + .rxheadervalid_out(gt_rxheadervalid), + .rxstartofseq_out() + ); + + assign xcvr_qpll0lock_out = 1'b0; + assign xcvr_qpll0clk_out = 1'b0; + assign xcvr_qpll0refclk_out = 1'b0; + +end else if (!HAS_COMMON && GT_TYPE == "GTH") begin : xcvr + // UltraScale/UltraScale+ GTH (channel only) + + taxi_eth_phy_10g_us_gth_ch + taxi_eth_phy_10g_us_gth_ch_inst ( + // Common + .gtpowergood_out(xcvr_gtpowergood_out), + + // PLL + .qpll0clk_in(xcvr_qpll0clk_in), + .qpll0refclk_in(xcvr_qpll0refclk_in), + .qpll1clk_in(xcvr_qpll1clk_in), + .qpll1refclk_in(xcvr_qpll1refclk_in), + + // Serial data + .gthtxp_out(xcvr_txp), + .gthtxn_out(xcvr_txn), + .gthrxp_in(xcvr_rxp), + .gthrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_reset_in(gt_tx_reset), + .gtwiz_userclk_tx_srcclk_out(), + .gtwiz_userclk_tx_usrclk_out(), + .gtwiz_userclk_tx_usrclk2_out(tx_clk), + .gtwiz_userclk_tx_active_out(gt_userclk_tx_active), + .gtwiz_reset_tx_done_in(tx_reset_done), + .txpdelecidlemode_in(1'b1), + .txpd_in(gt_tx_pd ? 2'b11 : 2'b00), + .gttxreset_in(gt_tx_reset), + .txpmareset_in(gt_tx_pma_reset), + .txpcsreset_in(gt_tx_pcs_reset), + .txresetdone_out(gt_tx_reset_done), + .txpmaresetdone_out(gt_tx_pma_reset_done), + .txprogdivreset_in(gt_tx_prgdiv_reset), + .txprgdivresetdone_out(gt_tx_prgdiv_reset_done), + .txpllclksel_in(gt_tx_qpll_sel ? 2'b10 : 2'b11), + .txsysclksel_in(gt_tx_qpll_sel ? 2'b11 : 2'b10), + .txuserrdy_in(gt_tx_userrdy), + + .txpolarity_in(GT_TX_POLARITY), + .txelecidle_in(GT_TX_ELECIDLE), + .txinhibit_in(GT_TX_INHIBIT), + .txdiffctrl_in(GT_TX_DIFFCTRL), + .txmaincursor_in(GT_TX_MAINCURSOR), + .txprecursor_in(GT_TX_PRECURSOR), + .txpostcursor_in(GT_TX_POSTCURSOR), + + .gtwiz_userdata_tx_in(gt_txdata), + .txheader_in(gt_txheader), + .txsequence_in(gt_txsequence), + + // Receive + .gtwiz_userclk_rx_reset_in(gt_rx_reset), + .gtwiz_userclk_rx_srcclk_out(), + .gtwiz_userclk_rx_usrclk_out(), + .gtwiz_userclk_rx_usrclk2_out(rx_clk), + .gtwiz_userclk_rx_active_out(gt_userclk_rx_active), + .gtwiz_reset_rx_done_in(rx_reset_done), + .rxpd_in(gt_rx_pd ? 2'b11 : 2'b00), + .gtrxreset_in(gt_rx_reset), + .rxpmareset_in(gt_rx_pma_reset), + .rxdfelpmreset_in(gt_rx_dfe_lpm_reset), + .eyescanreset_in(gt_rx_eyescan_reset), + .rxpcsreset_in(gt_rx_pcs_reset), + .rxresetdone_out(gt_rx_reset_done), + .rxpmaresetdone_out(gt_rx_pma_reset_done), + .rxprogdivreset_in(gt_rx_prgdiv_reset), + .rxprgdivresetdone_out(gt_rx_prgdiv_reset_done), + .rxpllclksel_in(gt_rx_qpll_sel ? 2'b10 : 2'b11), + .rxsysclksel_in(gt_rx_qpll_sel ? 2'b11 : 2'b10), + .rxuserrdy_in(gt_rx_userrdy), + + .rxcdrlock_out(gt_rx_cdr_lock), + .rxcdrhold_in(1'b0), + .rxcdrovrden_in(1'b0), + + .rxlpmen_in(gt_rx_lpm_en), + + .rxpolarity_in(GT_RX_POLARITY), + + .rxgearboxslip_in(gt_rxgearboxslip), + .gtwiz_userdata_rx_out(gt_rxdata), + .rxdatavalid_out(gt_rxdatavalid), + .rxheader_out(gt_rxheader), + .rxheadervalid_out(gt_rxheadervalid), + .rxstartofseq_out() + ); + + assign xcvr_qpll0lock_out = 1'b0; + assign xcvr_qpll0clk_out = 1'b0; + assign xcvr_qpll0refclk_out = 1'b0; + +end else begin + + $fatal(0, "Error: invalid configuration (%m)"); + +end + +endmodule + +`resetall diff --git a/src/eth/rtl/us/taxi_eth_phy_10g_us_gt_ll.f b/src/eth/rtl/us/taxi_eth_phy_10g_us_gt_ll.f new file mode 100644 index 0000000..e0687e9 --- /dev/null +++ b/src/eth/rtl/us/taxi_eth_phy_10g_us_gt_ll.f @@ -0,0 +1,6 @@ +taxi_eth_phy_10g_us_gt_ll.sv +../../lib/taxi/src/sync/rtl/taxi_sync_reset.sv +../../lib/taxi/src/sync/rtl/taxi_sync_signal.sv +../../lib/taxi/src/hip/rtl/us/taxi_gt_qpll_reset.sv +../../lib/taxi/src/hip/rtl/us/taxi_gt_rx_reset.sv +../../lib/taxi/src/hip/rtl/us/taxi_gt_tx_reset.sv diff --git a/src/eth/rtl/us/taxi_eth_phy_10g_us_gt_ll.sv b/src/eth/rtl/us/taxi_eth_phy_10g_us_gt_ll.sv new file mode 100644 index 0000000..4dbe00a --- /dev/null +++ b/src/eth/rtl/us/taxi_eth_phy_10g_us_gt_ll.sv @@ -0,0 +1,1090 @@ +// SPDX-License-Identifier: CERN-OHL-S-2.0 +/* + +Copyright (c) 2025 FPGA Ninja, LLC + +Authors: +- Alex Forencich + +*/ + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * Transceiver wrapper for UltraScale/UltraScale+ (low latency) + */ +module taxi_eth_phy_10g_us_gt_ll # +( + parameter logic SIM = 1'b0, + parameter string VENDOR = "XILINX", + parameter string FAMILY = "virtexuplus", + + parameter logic HAS_COMMON = 1'b1, + + // GT type + parameter string GT_TYPE = "GTY", + + // PLL parameters + parameter logic QPLL0_PD = 1'b0, + parameter logic QPLL1_PD = 1'b1, + parameter logic QPLL0_EXT_CTRL = 1'b0, + parameter logic QPLL1_EXT_CTRL = 1'b0, + + // GT parameters + parameter logic GT_TX_PD = 1'b0, + parameter logic GT_TX_QPLL_SEL = 1'b0, + parameter logic GT_TX_POLARITY = 1'b0, + parameter logic GT_TX_ELECIDLE = 1'b0, + parameter logic GT_TX_INHIBIT = 1'b0, + parameter logic [4:0] GT_TX_DIFFCTRL = 5'd16, + parameter logic [6:0] GT_TX_MAINCURSOR = 7'd64, + parameter logic [4:0] GT_TX_POSTCURSOR = 5'd0, + parameter logic [4:0] GT_TX_PRECURSOR = 5'd0, + parameter logic GT_RX_PD = 1'b0, + parameter logic GT_RX_QPLL_SEL = 1'b0, + parameter logic GT_RX_LPM_EN = 1'b0, + parameter logic GT_RX_POLARITY = 1'b0, + + // MAC/PHY parameters + parameter DATA_W = 64, + parameter HDR_W = 2 +) +( + input wire logic xcvr_ctrl_clk, + input wire logic xcvr_ctrl_rst, + + /* + * Common + */ + output wire logic xcvr_gtpowergood_out, + + /* + * PLL out + */ + input wire logic xcvr_gtrefclk00_in = 1'b0, + input wire logic xcvr_qpll0pd_in = 1'b0, + input wire logic xcvr_qpll0reset_in = 1'b0, + input wire logic [2:0] xcvr_qpll0pcierate_in = 3'd0, + output wire logic xcvr_qpll0lock_out, + output wire logic xcvr_qpll0clk_out, + output wire logic xcvr_qpll0refclk_out, + input wire logic xcvr_gtrefclk01_in = 1'b0, + input wire logic xcvr_qpll1pd_in = 1'b0, + input wire logic xcvr_qpll1reset_in = 1'b0, + input wire logic [2:0] xcvr_qpll1pcierate_in = 3'd0, + output wire logic xcvr_qpll1lock_out, + output wire logic xcvr_qpll1clk_out, + output wire logic xcvr_qpll1refclk_out, + + /* + * PLL in + */ + input wire logic xcvr_qpll0lock_in = 1'b0, + input wire logic xcvr_qpll0clk_in = 1'b0, + input wire logic xcvr_qpll0refclk_in = 1'b0, + input wire logic xcvr_qpll1lock_in = 1'b0, + input wire logic xcvr_qpll1clk_in = 1'b0, + input wire logic xcvr_qpll1refclk_in = 1'b0, + + /* + * Serial data + */ + output wire logic xcvr_txp, + output wire logic xcvr_txn, + input wire logic xcvr_rxp, + input wire logic xcvr_rxn, + + /* + * GT user clocks + */ + output wire logic rx_clk, + input wire logic rx_rst_in = 1'b0, + output wire logic rx_rst_out, + output wire logic tx_clk, + input wire logic tx_rst_in = 1'b0, + output wire logic tx_rst_out, + + /* + * Serdes interface + */ + input wire logic [DATA_W-1:0] serdes_tx_data, + input wire logic serdes_tx_data_valid, + input wire logic [HDR_W-1:0] serdes_tx_hdr, + input wire logic serdes_tx_hdr_valid, + output wire logic serdes_tx_gbx_req_sync, + output wire logic serdes_tx_gbx_req_stall, + input wire logic serdes_tx_gbx_sync, + output wire logic [DATA_W-1:0] serdes_rx_data, + output wire logic serdes_rx_data_valid, + output wire logic [HDR_W-1:0] serdes_rx_hdr, + output wire logic serdes_rx_hdr_valid, + input wire logic serdes_rx_bitslip +); + +localparam GT_USP = FAMILY == "kintexuplus" || FAMILY == "virtexuplus" || FAMILY == "virtexuplusHBM" + || FAMILY == "virtexuplus58G" || FAMILY == "zynquplus" || FAMILY == "zynquplusRFSOC"; + +// check configuration +if (DATA_W != 32) + $fatal(0, "Error: Interface width must be 32"); + +if (HDR_W != 2) + $fatal(0, "Error: HDR_W must be 2"); + +wire xcvr_ctrl_rst_sync; + +taxi_sync_reset #( + .N(4) +) +reset_sync_inst ( + .clk(xcvr_ctrl_clk), + .rst(xcvr_ctrl_rst), + .out(xcvr_ctrl_rst_sync) +); + +wire gt_qpll0_pd; +wire gt_qpll0_reset; +wire gt_qpll1_pd; +wire gt_qpll1_reset; + +wire qpll0_lock; +wire qpll1_lock; + +if (HAS_COMMON) begin : common_ctrl + + taxi_gt_qpll_reset #( + .QPLL_PD(QPLL0_PD), + .CNT_W(8) + ) + qpll0_reset_inst ( + .clk(xcvr_ctrl_clk), + .rst(xcvr_ctrl_rst_sync), + + /* + * GT + */ + .gt_qpll_reset_out(gt_qpll0_reset), + .gt_qpll_pd_out(gt_qpll0_pd), + .gt_qpll_lock_in(xcvr_qpll0lock_out), + + /* + * Control/status + */ + .qpll_reset_in(1'b0), + .qpll_pd_in(QPLL0_PD), + .qpll_lock_out(qpll0_lock) + ); + + taxi_gt_qpll_reset #( + .QPLL_PD(QPLL1_PD), + .CNT_W(8) + ) + qpll1_reset_inst ( + .clk(xcvr_ctrl_clk), + .rst(xcvr_ctrl_rst_sync), + + /* + * GT + */ + .gt_qpll_reset_out(gt_qpll1_reset), + .gt_qpll_pd_out(gt_qpll1_pd), + .gt_qpll_lock_in(xcvr_qpll1lock_out), + + /* + * Control/status + */ + .qpll_reset_in(1'b0), + .qpll_pd_in(QPLL1_PD), + .qpll_lock_out(qpll1_lock) + ); + +end else begin : common_ctrl + + assign gt_qpll0_pd = 1'b1; + assign gt_qpll0_reset = 1'b1; + assign gt_qpll1_pd = 1'b1; + assign gt_qpll1_reset = 1'b1; + + taxi_sync_signal #( + .WIDTH(2), + .N(2) + ) + qpll_lock_sync_inst ( + .clk(xcvr_ctrl_clk), + .in({xcvr_qpll1lock_in, xcvr_qpll0lock_in}), + .out({qpll1_lock, qpll0_lock}) + ); + +end + +wire gt_tx_pd; +wire gt_tx_reset; +wire gt_tx_reset_done; +wire gt_userclk_tx_active; +wire gt_tx_pma_reset; +wire gt_tx_pcs_reset; +wire gt_tx_pma_reset_done; +wire gt_tx_prgdiv_reset; +wire gt_tx_prgdiv_reset_done; +wire gt_tx_qpll_sel; +wire gt_tx_userrdy; + +wire tx_reset_done; + +taxi_sync_reset #( + .N(4) +) +tx_reset_sync_inst ( + .clk(tx_clk), + .rst(!tx_reset_done || tx_rst_in), + .out(tx_rst_out) +); + +taxi_gt_tx_reset #( + .GT_TX_PD(GT_TX_PD), + .GT_TX_QPLL_SEL(GT_TX_QPLL_SEL), + .CNT_W(8) +) +gt_tx_reset_inst ( + .clk(xcvr_ctrl_clk), + .rst(xcvr_ctrl_rst_sync), + + /* + * GT + */ + .gt_tx_pd_out(gt_tx_pd), + .gt_tx_reset_out(gt_tx_reset), + .gt_tx_reset_done_in(gt_tx_reset_done), + .gt_userclk_tx_active_in(gt_userclk_tx_active), + .gt_tx_pma_reset_out(gt_tx_pma_reset), + .gt_tx_pcs_reset_out(gt_tx_pcs_reset), + .gt_tx_pma_reset_done_in(gt_tx_pma_reset_done), + .gt_tx_prgdiv_reset_out(gt_tx_prgdiv_reset), + .gt_tx_prgdiv_reset_done_in(gt_tx_prgdiv_reset_done), + .gt_tx_qpll_sel_out(gt_tx_qpll_sel), + .gt_tx_userrdy_out(gt_tx_userrdy), + + /* + * Control/status + */ + .qpll0_lock_in(qpll0_lock), + .qpll1_lock_in(qpll1_lock), + .tx_reset_in(tx_rst_in), + .tx_reset_done_out(tx_reset_done), + .tx_pma_reset_in(1'b0), + .tx_pma_reset_done_out(), + .tx_prgdiv_reset_done_out(), + .tx_pcs_reset_in(1'b0), + .tx_pd_in(GT_TX_PD), + .tx_qpll_sel_in(GT_TX_QPLL_SEL) +); + +wire gt_rx_pd; +wire gt_rx_reset; +wire gt_rx_reset_done; +wire gt_userclk_rx_active; +wire gt_rx_pma_reset; +wire gt_rx_dfe_lpm_reset; +wire gt_rx_eyescan_reset; +wire gt_rx_pcs_reset; +wire gt_rx_pma_reset_done; +wire gt_rx_prgdiv_reset; +wire gt_rx_prgdiv_reset_done; +wire gt_rx_qpll_sel; +wire gt_rx_userrdy; +wire gt_rx_cdr_lock; +wire gt_rx_lpm_en; + +wire rx_reset_done; + +taxi_sync_reset #( + .N(4) +) +rx_reset_sync_inst ( + .clk(rx_clk), + .rst(!rx_reset_done || rx_rst_in), + .out(rx_rst_out) +); + +taxi_gt_rx_reset #( + .GT_RX_PD(GT_RX_PD), + .GT_RX_QPLL_SEL(GT_RX_QPLL_SEL), + .GT_RX_LPM_EN(GT_RX_LPM_EN), + .CNT_W(8), + .CDR_CNT_W(20) +) +gt_rx_reset_inst ( + .clk(xcvr_ctrl_clk), + .rst(xcvr_ctrl_rst_sync), + + /* + * GT + */ + .gt_rx_pd_out(gt_rx_pd), + .gt_rx_reset_out(gt_rx_reset), + .gt_rx_reset_done_in(gt_rx_reset_done), + .gt_userclk_rx_active_in(gt_userclk_rx_active), + .gt_rx_pma_reset_out(gt_rx_pma_reset), + .gt_rx_dfe_lpm_reset_out(gt_rx_dfe_lpm_reset), + .gt_rx_eyescan_reset_out(gt_rx_eyescan_reset), + .gt_rx_pcs_reset_out(gt_rx_pcs_reset), + .gt_rx_pma_reset_done_in(gt_rx_pma_reset_done), + .gt_rx_prgdiv_reset_out(gt_rx_prgdiv_reset), + .gt_rx_prgdiv_reset_done_in(gt_rx_prgdiv_reset_done), + .gt_rx_qpll_sel_out(gt_rx_qpll_sel), + .gt_rx_userrdy_out(gt_rx_userrdy), + .gt_rx_cdr_lock_in(gt_rx_cdr_lock), + .gt_rx_lpm_en_out(gt_rx_lpm_en), + + /* + * Control/status + */ + .qpll0_lock_in(qpll0_lock), + .qpll1_lock_in(qpll1_lock), + .rx_reset_in(rx_rst_in), + .rx_reset_done_out(rx_reset_done), + .rx_pma_reset_in(1'b0), + .rx_pma_reset_done_out(), + .rx_prgdiv_reset_done_out(), + .rx_pcs_reset_in(1'b0), + .rx_dfe_lpm_reset_in(1'b0), + .eyescan_reset_in(1'b0), + .rx_pd_in(GT_RX_PD), + .rx_qpll_sel_in(GT_RX_QPLL_SEL), + .rx_lpm_en_in(GT_RX_LPM_EN) +); + +wire [6:0] gt_txsequence; +wire [5:0] gt_txheader; +wire [31:0] gt_txdata; +wire gt_rxgearboxslip; +wire [1:0] gt_rxstartofseq; +wire [5:0] gt_rxheader; +wire [1:0] gt_rxheadervalid; +wire [31:0] gt_rxdata; +wire [1:0] gt_rxdatavalid; + +assign gt_txdata = serdes_tx_data; +assign gt_txheader = {4'd0, serdes_tx_hdr}; +assign gt_rxgearboxslip = serdes_rx_bitslip; + +if (!SIM) begin + assign serdes_rx_data = gt_rxdata; + assign serdes_rx_data_valid = gt_rxdatavalid; + assign serdes_rx_hdr = gt_rxheader[1:0]; + assign serdes_rx_hdr_valid = gt_rxheadervalid[0]; +end + +// 66 clock cycle sequence, with two stalls on cycles 64 and 65 +// 32-bit internal, 32-bit external datapath width + +// Generate gearbox request signals +logic [6:0] tx_seq_gen_reg = '0; +logic tx_req_sync_reg = 1'b0; +logic tx_req_stall_reg = 1'b0; + +assign serdes_tx_gbx_req_sync = tx_req_sync_reg; +assign serdes_tx_gbx_req_stall = tx_req_stall_reg; + +always @(posedge tx_clk) begin + tx_req_sync_reg <= 1'b0; + tx_req_stall_reg <= 1'b0; + + tx_seq_gen_reg <= tx_seq_gen_reg - 1; + if (tx_seq_gen_reg == 0) begin + tx_seq_gen_reg <= 65; + tx_req_sync_reg <= 1'b1; + end + if (tx_seq_gen_reg == 2 || tx_seq_gen_reg == 1) begin + tx_req_stall_reg <= 1'b1; + end +end + +// Generate TX sequence +logic [6:0] tx_seq_reg = '0; + +assign gt_txsequence = {1'b0, tx_seq_reg[6:1]}; + +always @(posedge tx_clk) begin + tx_seq_reg <= tx_seq_reg + 1; + if (tx_seq_reg == 65) begin + tx_seq_reg <= '0; + end + if (serdes_tx_gbx_sync) begin + tx_seq_reg <= 1; + end +end + +if (SIM) begin : xcvr + // simulation (no GT core) + + assign xcvr_gtpowergood_out = 1'b1; + + assign xcvr_qpll0lock_out = !gt_qpll0_reset && !gt_qpll0_pd; + assign xcvr_qpll0clk_out = 1'b0; + assign xcvr_qpll0refclk_out = xcvr_gtrefclk00_in; + + assign xcvr_qpll1lock_out = !gt_qpll1_reset && !gt_qpll0_pd; + assign xcvr_qpll1clk_out = 1'b0; + assign xcvr_qpll1refclk_out = xcvr_gtrefclk01_in; + + assign gt_tx_reset_done = !gt_tx_reset; + assign gt_userclk_tx_active = gt_tx_qpll_sel ? qpll1_lock : qpll0_lock; + assign gt_tx_pma_reset_done = gt_tx_reset_done; + assign gt_tx_prgdiv_reset_done = gt_tx_reset_done; + + assign gt_rx_reset_done = !gt_rx_reset; + assign gt_userclk_rx_active = gt_rx_qpll_sel ? qpll1_lock : qpll0_lock; + assign gt_rx_pma_reset_done = gt_rx_reset_done; + assign gt_rx_prgdiv_reset_done = gt_rx_reset_done; + assign gt_rx_cdr_lock = gt_rx_reset_done; + +end else if (HAS_COMMON && GT_TYPE == "GTY" && GT_USP) begin : xcvr + // UltraScale+ GTY (with common) + + taxi_eth_phy_10g_us_gty_ll_full + taxi_eth_phy_10g_us_gty_ll_full_inst ( + // Common + .gtpowergood_out(xcvr_gtpowergood_out), + + // PLL + .gtrefclk00_in(xcvr_gtrefclk00_in), + .qpll0lock_out(xcvr_qpll0lock_out), + .qpll0outclk_out(xcvr_qpll0clk_out), + .qpll0outrefclk_out(xcvr_qpll0refclk_out), + .gtrefclk01_in(xcvr_gtrefclk01_in), + .qpll1lock_out(xcvr_qpll1lock_out), + .qpll1outclk_out(xcvr_qpll1clk_out), + .qpll1outrefclk_out(xcvr_qpll1refclk_out), + + .qpll0pd_in(QPLL0_EXT_CTRL ? xcvr_qpll0pd_in : gt_qpll0_pd), + .qpll0reset_in(QPLL0_EXT_CTRL ? xcvr_qpll0reset_in : gt_qpll0_reset), + .qpll1pd_in(QPLL1_EXT_CTRL ? xcvr_qpll1pd_in : gt_qpll1_pd), + .qpll1reset_in(QPLL1_EXT_CTRL ? xcvr_qpll1reset_in : gt_qpll1_reset), + + .pcierateqpll0_in(QPLL0_EXT_CTRL ? xcvr_qpll0pcierate_in : 3'd0), + .pcierateqpll1_in(QPLL1_EXT_CTRL ? xcvr_qpll1pcierate_in : 3'd0), + + // Serial data + .gtytxp_out(xcvr_txp), + .gtytxn_out(xcvr_txn), + .gtyrxp_in(xcvr_rxp), + .gtyrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_reset_in(gt_tx_reset), + .gtwiz_userclk_tx_srcclk_out(), + .gtwiz_userclk_tx_usrclk_out(), + .gtwiz_userclk_tx_usrclk2_out(tx_clk), + .gtwiz_userclk_tx_active_out(gt_userclk_tx_active), + .gtwiz_reset_tx_done_in(tx_reset_done), + .gtwiz_buffbypass_tx_reset_in(1'b0), + .gtwiz_buffbypass_tx_start_user_in(1'b0), + .gtwiz_buffbypass_tx_done_out(), + .gtwiz_buffbypass_tx_error_out(), + .txpdelecidlemode_in(1'b1), + .txpd_in(gt_tx_pd ? 2'b11 : 2'b00), + .gttxreset_in(gt_tx_reset), + .txpmareset_in(gt_tx_pma_reset), + .txpcsreset_in(gt_tx_pcs_reset), + .txresetdone_out(gt_tx_reset_done), + .txpmaresetdone_out(gt_tx_pma_reset_done), + .txprogdivreset_in(gt_tx_prgdiv_reset), + .txprgdivresetdone_out(gt_tx_prgdiv_reset_done), + .txpllclksel_in(gt_tx_qpll_sel ? 2'b10 : 2'b11), + .txsysclksel_in(gt_tx_qpll_sel ? 2'b11 : 2'b10), + .txuserrdy_in(gt_tx_userrdy), + + .txpolarity_in(GT_TX_POLARITY), + .txelecidle_in(GT_TX_ELECIDLE), + .txinhibit_in(GT_TX_INHIBIT), + .txdiffctrl_in(GT_TX_DIFFCTRL), + .txmaincursor_in(GT_TX_MAINCURSOR), + .txprecursor_in(GT_TX_PRECURSOR), + .txpostcursor_in(GT_TX_POSTCURSOR), + + .gtwiz_userdata_tx_in(gt_txdata), + .txheader_in(gt_txheader), + .txsequence_in(gt_txsequence), + + // Receive + .gtwiz_userclk_rx_reset_in(gt_rx_reset), + .gtwiz_userclk_rx_srcclk_out(), + .gtwiz_userclk_rx_usrclk_out(), + .gtwiz_userclk_rx_usrclk2_out(rx_clk), + .gtwiz_userclk_rx_active_out(gt_userclk_rx_active), + .gtwiz_reset_rx_done_in(rx_reset_done), + .gtwiz_buffbypass_rx_reset_in(1'b0), + .gtwiz_buffbypass_rx_start_user_in(1'b0), + .gtwiz_buffbypass_rx_done_out(), + .gtwiz_buffbypass_rx_error_out(), + .rxpd_in(gt_rx_pd ? 2'b11 : 2'b00), + .gtrxreset_in(gt_rx_reset), + .rxpmareset_in(gt_rx_pma_reset), + .rxdfelpmreset_in(gt_rx_dfe_lpm_reset), + .eyescanreset_in(gt_rx_eyescan_reset), + .rxpcsreset_in(gt_rx_pcs_reset), + .rxresetdone_out(gt_rx_reset_done), + .rxpmaresetdone_out(gt_rx_pma_reset_done), + .rxprogdivreset_in(gt_rx_prgdiv_reset), + .rxprgdivresetdone_out(gt_rx_prgdiv_reset_done), + .rxpllclksel_in(gt_rx_qpll_sel ? 2'b10 : 2'b11), + .rxsysclksel_in(gt_rx_qpll_sel ? 2'b11 : 2'b10), + .rxuserrdy_in(gt_rx_userrdy), + + .rxcdrlock_out(gt_rx_cdr_lock), + .rxcdrhold_in(1'b0), + .rxcdrovrden_in(1'b0), + + .rxlpmen_in(gt_rx_lpm_en), + + .rxpolarity_in(GT_RX_POLARITY), + + .rxgearboxslip_in(gt_rxgearboxslip), + .gtwiz_userdata_rx_out(gt_rxdata), + .rxdatavalid_out(gt_rxdatavalid), + .rxheader_out(gt_rxheader), + .rxheadervalid_out(gt_rxheadervalid), + .rxstartofseq_out(gt_rxstartofseq) + ); + +end else if (HAS_COMMON && GT_TYPE == "GTH" && GT_USP) begin : xcvr + // UltraScale+ GTH (with common) + + taxi_eth_phy_10g_us_gth_ll_full + taxi_eth_phy_10g_us_gth_ll_full_inst ( + // Common + .gtpowergood_out(xcvr_gtpowergood_out), + + // PLL + .gtrefclk00_in(xcvr_gtrefclk00_in), + .qpll0lock_out(xcvr_qpll0lock_out), + .qpll0outclk_out(xcvr_qpll0clk_out), + .qpll0outrefclk_out(xcvr_qpll0refclk_out), + .gtrefclk01_in(xcvr_gtrefclk01_in), + .qpll1lock_out(xcvr_qpll1lock_out), + .qpll1outclk_out(xcvr_qpll1clk_out), + .qpll1outrefclk_out(xcvr_qpll1refclk_out), + + .qpll0pd_in(QPLL0_EXT_CTRL ? xcvr_qpll0pd_in : gt_qpll0_pd), + .qpll0reset_in(QPLL0_EXT_CTRL ? xcvr_qpll0reset_in : gt_qpll0_reset), + .qpll1pd_in(QPLL1_EXT_CTRL ? xcvr_qpll1pd_in : gt_qpll1_pd), + .qpll1reset_in(QPLL1_EXT_CTRL ? xcvr_qpll1reset_in : gt_qpll1_reset), + + .pcierateqpll0_in(QPLL0_EXT_CTRL ? xcvr_qpll0pcierate_in : 3'd0), + .pcierateqpll1_in(QPLL1_EXT_CTRL ? xcvr_qpll1pcierate_in : 3'd0), + + // Serial data + .gthtxp_out(xcvr_txp), + .gthtxn_out(xcvr_txn), + .gthrxp_in(xcvr_rxp), + .gthrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_reset_in(gt_tx_reset), + .gtwiz_userclk_tx_srcclk_out(), + .gtwiz_userclk_tx_usrclk_out(), + .gtwiz_userclk_tx_usrclk2_out(tx_clk), + .gtwiz_userclk_tx_active_out(gt_userclk_tx_active), + .gtwiz_reset_tx_done_in(tx_reset_done), + .gtwiz_buffbypass_tx_reset_in(1'b0), + .gtwiz_buffbypass_tx_start_user_in(1'b0), + .gtwiz_buffbypass_tx_done_out(), + .gtwiz_buffbypass_tx_error_out(), + .txpdelecidlemode_in(1'b1), + .txpd_in(gt_tx_pd ? 2'b11 : 2'b00), + .gttxreset_in(gt_tx_reset), + .txpmareset_in(gt_tx_pma_reset), + .txpcsreset_in(gt_tx_pcs_reset), + .txresetdone_out(gt_tx_reset_done), + .txpmaresetdone_out(gt_tx_pma_reset_done), + .txprogdivreset_in(gt_tx_prgdiv_reset), + .txprgdivresetdone_out(gt_tx_prgdiv_reset_done), + .txpllclksel_in(gt_tx_qpll_sel ? 2'b10 : 2'b11), + .txsysclksel_in(gt_tx_qpll_sel ? 2'b11 : 2'b10), + .txuserrdy_in(gt_tx_userrdy), + + .txpolarity_in(GT_TX_POLARITY), + .txelecidle_in(GT_TX_ELECIDLE), + .txinhibit_in(GT_TX_INHIBIT), + .txdiffctrl_in(GT_TX_DIFFCTRL), + .txmaincursor_in(GT_TX_MAINCURSOR), + .txprecursor_in(GT_TX_PRECURSOR), + .txpostcursor_in(GT_TX_POSTCURSOR), + + .gtwiz_userdata_tx_in(gt_txdata), + .txheader_in(gt_txheader), + .txsequence_in(gt_txsequence), + + // Receive + .gtwiz_userclk_rx_reset_in(gt_rx_reset), + .gtwiz_userclk_rx_srcclk_out(), + .gtwiz_userclk_rx_usrclk_out(), + .gtwiz_userclk_rx_usrclk2_out(rx_clk), + .gtwiz_userclk_rx_active_out(gt_userclk_rx_active), + .gtwiz_reset_rx_done_in(rx_reset_done), + .gtwiz_buffbypass_rx_reset_in(1'b0), + .gtwiz_buffbypass_rx_start_user_in(1'b0), + .gtwiz_buffbypass_rx_done_out(), + .gtwiz_buffbypass_rx_error_out(), + .rxpd_in(gt_rx_pd ? 2'b11 : 2'b00), + .gtrxreset_in(gt_rx_reset), + .rxpmareset_in(gt_rx_pma_reset), + .rxdfelpmreset_in(gt_rx_dfe_lpm_reset), + .eyescanreset_in(gt_rx_eyescan_reset), + .rxpcsreset_in(gt_rx_pcs_reset), + .rxresetdone_out(gt_rx_reset_done), + .rxpmaresetdone_out(gt_rx_pma_reset_done), + .rxprogdivreset_in(gt_rx_prgdiv_reset), + .rxprgdivresetdone_out(gt_rx_prgdiv_reset_done), + .rxpllclksel_in(gt_rx_qpll_sel ? 2'b10 : 2'b11), + .rxsysclksel_in(gt_rx_qpll_sel ? 2'b11 : 2'b10), + .rxuserrdy_in(gt_rx_userrdy), + + .rxcdrlock_out(gt_rx_cdr_lock), + .rxcdrhold_in(1'b0), + .rxcdrovrden_in(1'b0), + + .rxlpmen_in(gt_rx_lpm_en), + + .rxpolarity_in(GT_RX_POLARITY), + + .rxgearboxslip_in(gt_rxgearboxslip), + .gtwiz_userdata_rx_out(gt_rxdata), + .rxdatavalid_out(gt_rxdatavalid), + .rxheader_out(gt_rxheader), + .rxheadervalid_out(gt_rxheadervalid), + .rxstartofseq_out(gt_rxstartofseq) + ); + +end else if (HAS_COMMON && GT_TYPE == "GTY" && !GT_USP) begin : xcvr + // UltraScale GTY (with common) + + taxi_eth_phy_10g_us_gty_ll_full + taxi_eth_phy_10g_us_gty_ll_full_inst ( + // Common + .gtpowergood_out(xcvr_gtpowergood_out), + + // PLL + .gtrefclk00_in(xcvr_gtrefclk00_in), + .qpll0lock_out(xcvr_qpll0lock_out), + .qpll0outclk_out(xcvr_qpll0clk_out), + .qpll0outrefclk_out(xcvr_qpll0refclk_out), + .gtrefclk01_in(xcvr_gtrefclk01_in), + .qpll1lock_out(xcvr_qpll1lock_out), + .qpll1outclk_out(xcvr_qpll1clk_out), + .qpll1outrefclk_out(xcvr_qpll1refclk_out), + + .qpll0pd_in(QPLL0_EXT_CTRL ? xcvr_qpll0pd_in : gt_qpll0_pd), + .qpll0reset_in(QPLL0_EXT_CTRL ? xcvr_qpll0reset_in : gt_qpll0_reset), + .qpll1pd_in(QPLL1_EXT_CTRL ? xcvr_qpll1pd_in : gt_qpll1_pd), + .qpll1reset_in(QPLL1_EXT_CTRL ? xcvr_qpll1reset_in : gt_qpll1_reset), + + .qpllrsvd2_in(QPLL0_EXT_CTRL ? {2'd0, xcvr_qpll0pcierate_in} : 5'd0), // [2:0] : QPLL0 rate + .qpllrsvd3_in(QPLL1_EXT_CTRL ? {2'd0, xcvr_qpll1pcierate_in} : 5'd0), // [2:0] : QPLL1 rate + + // Serial data + .gtytxp_out(xcvr_txp), + .gtytxn_out(xcvr_txn), + .gtyrxp_in(xcvr_rxp), + .gtyrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_reset_in(gt_tx_reset), + .gtwiz_userclk_tx_srcclk_out(), + .gtwiz_userclk_tx_usrclk_out(), + .gtwiz_userclk_tx_usrclk2_out(tx_clk), + .gtwiz_userclk_tx_active_out(gt_userclk_tx_active), + .gtwiz_reset_tx_done_in(tx_reset_done), + .gtwiz_buffbypass_tx_reset_in(1'b0), + .gtwiz_buffbypass_tx_start_user_in(1'b0), + .gtwiz_buffbypass_tx_done_out(), + .gtwiz_buffbypass_tx_error_out(), + .txpdelecidlemode_in(1'b1), + .txpd_in(gt_tx_pd ? 2'b11 : 2'b00), + .gttxreset_in(gt_tx_reset), + .txpmareset_in(gt_tx_pma_reset), + .txpcsreset_in(gt_tx_pcs_reset), + .txresetdone_out(gt_tx_reset_done), + .txpmaresetdone_out(gt_tx_pma_reset_done), + .txprogdivreset_in(gt_tx_prgdiv_reset), + .txprgdivresetdone_out(gt_tx_prgdiv_reset_done), + .txpllclksel_in(gt_tx_qpll_sel ? 2'b10 : 2'b11), + .txsysclksel_in(gt_tx_qpll_sel ? 2'b11 : 2'b10), + .txuserrdy_in(gt_tx_userrdy), + + .txpolarity_in(GT_TX_POLARITY), + .txelecidle_in(GT_TX_ELECIDLE), + .txinhibit_in(GT_TX_INHIBIT), + .txdiffctrl_in(GT_TX_DIFFCTRL), + .txmaincursor_in(GT_TX_MAINCURSOR), + .txprecursor_in(GT_TX_PRECURSOR), + .txpostcursor_in(GT_TX_POSTCURSOR), + + .gtwiz_userdata_tx_in(gt_txdata), + .txheader_in(gt_txheader), + .txsequence_in(gt_txsequence), + + // Receive + .gtwiz_userclk_rx_reset_in(gt_rx_reset), + .gtwiz_userclk_rx_srcclk_out(), + .gtwiz_userclk_rx_usrclk_out(), + .gtwiz_userclk_rx_usrclk2_out(rx_clk), + .gtwiz_userclk_rx_active_out(gt_userclk_rx_active), + .gtwiz_reset_rx_done_in(rx_reset_done), + .gtwiz_buffbypass_rx_reset_in(1'b0), + .gtwiz_buffbypass_rx_start_user_in(1'b0), + .gtwiz_buffbypass_rx_done_out(), + .gtwiz_buffbypass_rx_error_out(), + .rxpd_in(gt_rx_pd ? 2'b11 : 2'b00), + .gtrxreset_in(gt_rx_reset), + .rxpmareset_in(gt_rx_pma_reset), + .rxdfelpmreset_in(gt_rx_dfe_lpm_reset), + .eyescanreset_in(gt_rx_eyescan_reset), + .rxpcsreset_in(gt_rx_pcs_reset), + .rxresetdone_out(gt_rx_reset_done), + .rxpmaresetdone_out(gt_rx_pma_reset_done), + .rxprogdivreset_in(gt_rx_prgdiv_reset), + .rxprgdivresetdone_out(gt_rx_prgdiv_reset_done), + .rxpllclksel_in(gt_rx_qpll_sel ? 2'b10 : 2'b11), + .rxsysclksel_in(gt_rx_qpll_sel ? 2'b11 : 2'b10), + .rxuserrdy_in(gt_rx_userrdy), + + .rxcdrlock_out(gt_rx_cdr_lock), + .rxcdrhold_in(1'b0), + .rxcdrovrden_in(1'b0), + + .rxlpmen_in(gt_rx_lpm_en), + + .rxpolarity_in(GT_RX_POLARITY), + + .rxgearboxslip_in(gt_rxgearboxslip), + .gtwiz_userdata_rx_out(gt_rxdata), + .rxdatavalid_out(gt_rxdatavalid), + .rxheader_out(gt_rxheader), + .rxheadervalid_out(gt_rxheadervalid), + .rxstartofseq_out(gt_rxstartofseq) + ); + +end else if (HAS_COMMON && GT_TYPE == "GTH" && !GT_USP) begin : xcvr + // UltraScale GTH (with common) + + taxi_eth_phy_10g_us_gth_ll_full + taxi_eth_phy_10g_us_gth_ll_full_inst ( + // Common + .gtpowergood_out(xcvr_gtpowergood_out), + + // PLL + .gtrefclk00_in(xcvr_gtrefclk00_in), + .qpll0lock_out(xcvr_qpll0lock_out), + .qpll0outclk_out(xcvr_qpll0clk_out), + .qpll0outrefclk_out(xcvr_qpll0refclk_out), + .gtrefclk01_in(xcvr_gtrefclk01_in), + .qpll1lock_out(xcvr_qpll1lock_out), + .qpll1outclk_out(xcvr_qpll1clk_out), + .qpll1outrefclk_out(xcvr_qpll1refclk_out), + + .qpll0pd_in(QPLL0_EXT_CTRL ? xcvr_qpll0pd_in : gt_qpll0_pd), + .qpll0reset_in(QPLL0_EXT_CTRL ? xcvr_qpll0reset_in : gt_qpll0_reset), + .qpll1pd_in(QPLL1_EXT_CTRL ? xcvr_qpll1pd_in : gt_qpll1_pd), + .qpll1reset_in(QPLL1_EXT_CTRL ? xcvr_qpll1reset_in : gt_qpll1_reset), + + .qpllrsvd2_in(QPLL0_EXT_CTRL ? {2'd0, xcvr_qpll0pcierate_in} : 5'd0), // [2:0] : QPLL0 rate + .qpllrsvd3_in(QPLL1_EXT_CTRL ? {2'd0, xcvr_qpll1pcierate_in} : 5'd0), // [2:0] : QPLL1 rate + + // Serial data + .gthtxp_out(xcvr_txp), + .gthtxn_out(xcvr_txn), + .gthrxp_in(xcvr_rxp), + .gthrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_reset_in(gt_tx_reset), + .gtwiz_userclk_tx_srcclk_out(), + .gtwiz_userclk_tx_usrclk_out(), + .gtwiz_userclk_tx_usrclk2_out(tx_clk), + .gtwiz_userclk_tx_active_out(gt_userclk_tx_active), + .gtwiz_reset_tx_done_in(tx_reset_done), + .gtwiz_buffbypass_tx_reset_in(1'b0), + .gtwiz_buffbypass_tx_start_user_in(1'b0), + .gtwiz_buffbypass_tx_done_out(), + .gtwiz_buffbypass_tx_error_out(), + .txpdelecidlemode_in(1'b1), + .txpd_in(gt_tx_pd ? 2'b11 : 2'b00), + .gttxreset_in(gt_tx_reset), + .txpmareset_in(gt_tx_pma_reset), + .txpcsreset_in(gt_tx_pcs_reset), + .txresetdone_out(gt_tx_reset_done), + .txpmaresetdone_out(gt_tx_pma_reset_done), + .txprogdivreset_in(gt_tx_prgdiv_reset), + .txprgdivresetdone_out(gt_tx_prgdiv_reset_done), + .txpllclksel_in(gt_tx_qpll_sel ? 2'b10 : 2'b11), + .txsysclksel_in(gt_tx_qpll_sel ? 2'b11 : 2'b10), + .txuserrdy_in(gt_tx_userrdy), + + .txpolarity_in(GT_TX_POLARITY), + .txelecidle_in(GT_TX_ELECIDLE), + .txinhibit_in(GT_TX_INHIBIT), + .txdiffctrl_in(GT_TX_DIFFCTRL), + .txmaincursor_in(GT_TX_MAINCURSOR), + .txprecursor_in(GT_TX_PRECURSOR), + .txpostcursor_in(GT_TX_POSTCURSOR), + + .gtwiz_userdata_tx_in(gt_txdata), + .txheader_in(gt_txheader), + .txsequence_in(gt_txsequence), + + // Receive + .gtwiz_userclk_rx_reset_in(gt_rx_reset), + .gtwiz_userclk_rx_srcclk_out(), + .gtwiz_userclk_rx_usrclk_out(), + .gtwiz_userclk_rx_usrclk2_out(rx_clk), + .gtwiz_userclk_rx_active_out(gt_userclk_rx_active), + .gtwiz_reset_rx_done_in(rx_reset_done), + .gtwiz_buffbypass_rx_reset_in(1'b0), + .gtwiz_buffbypass_rx_start_user_in(1'b0), + .gtwiz_buffbypass_rx_done_out(), + .gtwiz_buffbypass_rx_error_out(), + .rxpd_in(gt_rx_pd ? 2'b11 : 2'b00), + .gtrxreset_in(gt_rx_reset), + .rxpmareset_in(gt_rx_pma_reset), + .rxdfelpmreset_in(gt_rx_dfe_lpm_reset), + .eyescanreset_in(gt_rx_eyescan_reset), + .rxpcsreset_in(gt_rx_pcs_reset), + .rxresetdone_out(gt_rx_reset_done), + .rxpmaresetdone_out(gt_rx_pma_reset_done), + .rxprogdivreset_in(gt_rx_prgdiv_reset), + .rxprgdivresetdone_out(gt_rx_prgdiv_reset_done), + .rxpllclksel_in(gt_rx_qpll_sel ? 2'b10 : 2'b11), + .rxsysclksel_in(gt_rx_qpll_sel ? 2'b11 : 2'b10), + .rxuserrdy_in(gt_rx_userrdy), + + .rxcdrlock_out(gt_rx_cdr_lock), + .rxcdrhold_in(1'b0), + .rxcdrovrden_in(1'b0), + + .rxlpmen_in(gt_rx_lpm_en), + + .rxpolarity_in(GT_RX_POLARITY), + + .rxgearboxslip_in(gt_rxgearboxslip), + .gtwiz_userdata_rx_out(gt_rxdata), + .rxdatavalid_out(gt_rxdatavalid), + .rxheader_out(gt_rxheader), + .rxheadervalid_out(gt_rxheadervalid), + .rxstartofseq_out(gt_rxstartofseq) + ); + +end else if (!HAS_COMMON && GT_TYPE == "GTY") begin : xcvr + // UltraScale/UltraScale+ GTY (channel only) + + taxi_eth_phy_10g_us_gty_ll_ch + taxi_eth_phy_10g_us_gty_ll_ch_inst ( + // Common + .gtpowergood_out(xcvr_gtpowergood_out), + + // PLL + .qpll0clk_in(xcvr_qpll0clk_in), + .qpll0refclk_in(xcvr_qpll0refclk_in), + .qpll1clk_in(xcvr_qpll1clk_in), + .qpll1refclk_in(xcvr_qpll1refclk_in), + + // Serial data + .gtytxp_out(xcvr_txp), + .gtytxn_out(xcvr_txn), + .gtyrxp_in(xcvr_rxp), + .gtyrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_reset_in(gt_tx_reset), + .gtwiz_userclk_tx_srcclk_out(), + .gtwiz_userclk_tx_usrclk_out(), + .gtwiz_userclk_tx_usrclk2_out(tx_clk), + .gtwiz_userclk_tx_active_out(gt_userclk_tx_active), + .gtwiz_reset_tx_done_in(tx_reset_done), + .gtwiz_buffbypass_tx_reset_in(1'b0), + .gtwiz_buffbypass_tx_start_user_in(1'b0), + .gtwiz_buffbypass_tx_done_out(), + .gtwiz_buffbypass_tx_error_out(), + .txpdelecidlemode_in(1'b1), + .txpd_in(gt_tx_pd ? 2'b11 : 2'b00), + .gttxreset_in(gt_tx_reset), + .txpmareset_in(gt_tx_pma_reset), + .txpcsreset_in(gt_tx_pcs_reset), + .txresetdone_out(gt_tx_reset_done), + .txpmaresetdone_out(gt_tx_pma_reset_done), + .txprogdivreset_in(gt_tx_prgdiv_reset), + .txprgdivresetdone_out(gt_tx_prgdiv_reset_done), + .txpllclksel_in(gt_tx_qpll_sel ? 2'b10 : 2'b11), + .txsysclksel_in(gt_tx_qpll_sel ? 2'b11 : 2'b10), + .txuserrdy_in(gt_tx_userrdy), + + .txpolarity_in(GT_TX_POLARITY), + .txelecidle_in(GT_TX_ELECIDLE), + .txinhibit_in(GT_TX_INHIBIT), + .txdiffctrl_in(GT_TX_DIFFCTRL), + .txmaincursor_in(GT_TX_MAINCURSOR), + .txprecursor_in(GT_TX_PRECURSOR), + .txpostcursor_in(GT_TX_POSTCURSOR), + + .gtwiz_userdata_tx_in(gt_txdata), + .txheader_in(gt_txheader), + .txsequence_in(gt_txsequence), + + // Receive + .gtwiz_userclk_rx_reset_in(gt_rx_reset), + .gtwiz_userclk_rx_srcclk_out(), + .gtwiz_userclk_rx_usrclk_out(), + .gtwiz_userclk_rx_usrclk2_out(rx_clk), + .gtwiz_userclk_rx_active_out(gt_userclk_rx_active), + .gtwiz_reset_rx_done_in(rx_reset_done), + .gtwiz_buffbypass_rx_reset_in(1'b0), + .gtwiz_buffbypass_rx_start_user_in(1'b0), + .gtwiz_buffbypass_rx_done_out(), + .gtwiz_buffbypass_rx_error_out(), + .rxpd_in(gt_rx_pd ? 2'b11 : 2'b00), + .gtrxreset_in(gt_rx_reset), + .rxpmareset_in(gt_rx_pma_reset), + .rxdfelpmreset_in(gt_rx_dfe_lpm_reset), + .eyescanreset_in(gt_rx_eyescan_reset), + .rxpcsreset_in(gt_rx_pcs_reset), + .rxresetdone_out(gt_rx_reset_done), + .rxpmaresetdone_out(gt_rx_pma_reset_done), + .rxprogdivreset_in(gt_rx_prgdiv_reset), + .rxprgdivresetdone_out(gt_rx_prgdiv_reset_done), + .rxpllclksel_in(gt_rx_qpll_sel ? 2'b10 : 2'b11), + .rxsysclksel_in(gt_rx_qpll_sel ? 2'b11 : 2'b10), + .rxuserrdy_in(gt_rx_userrdy), + + .rxcdrlock_out(gt_rx_cdr_lock), + .rxcdrhold_in(1'b0), + .rxcdrovrden_in(1'b0), + + .rxlpmen_in(gt_rx_lpm_en), + + .rxpolarity_in(GT_RX_POLARITY), + + .rxgearboxslip_in(gt_rxgearboxslip), + .gtwiz_userdata_rx_out(gt_rxdata), + .rxdatavalid_out(gt_rxdatavalid), + .rxheader_out(gt_rxheader), + .rxheadervalid_out(gt_rxheadervalid), + .rxstartofseq_out(gt_rxstartofseq) + ); + + assign xcvr_qpll0lock_out = 1'b0; + assign xcvr_qpll0clk_out = 1'b0; + assign xcvr_qpll0refclk_out = 1'b0; + +end else if (!HAS_COMMON && GT_TYPE == "GTH") begin : xcvr + // UltraScale/UltraScale+ GTH (channel only) + + taxi_eth_phy_10g_us_gth_ll_ch + taxi_eth_phy_10g_us_gth_ll_ch_inst ( + // Common + .gtpowergood_out(xcvr_gtpowergood_out), + + // PLL + .qpll0clk_in(xcvr_qpll0clk_in), + .qpll0refclk_in(xcvr_qpll0refclk_in), + .qpll1clk_in(xcvr_qpll1clk_in), + .qpll1refclk_in(xcvr_qpll1refclk_in), + + // Serial data + .gthtxp_out(xcvr_txp), + .gthtxn_out(xcvr_txn), + .gthrxp_in(xcvr_rxp), + .gthrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_reset_in(gt_tx_reset), + .gtwiz_userclk_tx_srcclk_out(), + .gtwiz_userclk_tx_usrclk_out(), + .gtwiz_userclk_tx_usrclk2_out(tx_clk), + .gtwiz_userclk_tx_active_out(gt_userclk_tx_active), + .gtwiz_reset_tx_done_in(tx_reset_done), + .gtwiz_buffbypass_tx_reset_in(1'b0), + .gtwiz_buffbypass_tx_start_user_in(1'b0), + .gtwiz_buffbypass_tx_done_out(), + .gtwiz_buffbypass_tx_error_out(), + .txpdelecidlemode_in(1'b1), + .txpd_in(gt_tx_pd ? 2'b11 : 2'b00), + .gttxreset_in(gt_tx_reset), + .txpmareset_in(gt_tx_pma_reset), + .txpcsreset_in(gt_tx_pcs_reset), + .txresetdone_out(gt_tx_reset_done), + .txpmaresetdone_out(gt_tx_pma_reset_done), + .txprogdivreset_in(gt_tx_prgdiv_reset), + .txprgdivresetdone_out(gt_tx_prgdiv_reset_done), + .txpllclksel_in(gt_tx_qpll_sel ? 2'b10 : 2'b11), + .txsysclksel_in(gt_tx_qpll_sel ? 2'b11 : 2'b10), + .txuserrdy_in(gt_tx_userrdy), + + .txpolarity_in(GT_TX_POLARITY), + .txelecidle_in(GT_TX_ELECIDLE), + .txinhibit_in(GT_TX_INHIBIT), + .txdiffctrl_in(GT_TX_DIFFCTRL), + .txmaincursor_in(GT_TX_MAINCURSOR), + .txprecursor_in(GT_TX_PRECURSOR), + .txpostcursor_in(GT_TX_POSTCURSOR), + + .gtwiz_userdata_tx_in(gt_txdata), + .txheader_in(gt_txheader), + .txsequence_in(gt_txsequence), + + // Receive + .gtwiz_userclk_rx_reset_in(gt_rx_reset), + .gtwiz_userclk_rx_srcclk_out(), + .gtwiz_userclk_rx_usrclk_out(), + .gtwiz_userclk_rx_usrclk2_out(rx_clk), + .gtwiz_userclk_rx_active_out(gt_userclk_rx_active), + .gtwiz_reset_rx_done_in(rx_reset_done), + .gtwiz_buffbypass_rx_reset_in(1'b0), + .gtwiz_buffbypass_rx_start_user_in(1'b0), + .gtwiz_buffbypass_rx_done_out(), + .gtwiz_buffbypass_rx_error_out(), + .rxpd_in(gt_rx_pd ? 2'b11 : 2'b00), + .gtrxreset_in(gt_rx_reset), + .rxpmareset_in(gt_rx_pma_reset), + .rxdfelpmreset_in(gt_rx_dfe_lpm_reset), + .eyescanreset_in(gt_rx_eyescan_reset), + .rxpcsreset_in(gt_rx_pcs_reset), + .rxresetdone_out(gt_rx_reset_done), + .rxpmaresetdone_out(gt_rx_pma_reset_done), + .rxprogdivreset_in(gt_rx_prgdiv_reset), + .rxprgdivresetdone_out(gt_rx_prgdiv_reset_done), + .rxpllclksel_in(gt_rx_qpll_sel ? 2'b10 : 2'b11), + .rxsysclksel_in(gt_rx_qpll_sel ? 2'b11 : 2'b10), + .rxuserrdy_in(gt_rx_userrdy), + + .rxcdrlock_out(gt_rx_cdr_lock), + .rxcdrhold_in(1'b0), + .rxcdrovrden_in(1'b0), + + .rxlpmen_in(gt_rx_lpm_en), + + .rxpolarity_in(GT_RX_POLARITY), + + .rxgearboxslip_in(gt_rxgearboxslip), + .gtwiz_userdata_rx_out(gt_rxdata), + .rxdatavalid_out(gt_rxdatavalid), + .rxheader_out(gt_rxheader), + .rxheadervalid_out(gt_rxheadervalid), + .rxstartofseq_out(gt_rxstartofseq) + ); + + assign xcvr_qpll0lock_out = 1'b0; + assign xcvr_qpll0clk_out = 1'b0; + assign xcvr_qpll0refclk_out = 1'b0; + +end else begin + + $fatal(0, "Error: invalid configuration (%m)"); + +end + +endmodule + +`resetall diff --git a/src/eth/rtl/us/taxi_eth_phy_10g_us_gth_156.tcl b/src/eth/rtl/us/taxi_eth_phy_10g_us_gth_156.tcl new file mode 100644 index 0000000..9b4613a --- /dev/null +++ b/src/eth/rtl/us/taxi_eth_phy_10g_us_gth_156.tcl @@ -0,0 +1,132 @@ +# SPDX-License-Identifier: CERN-OHL-S-2.0 +# +# Copyright (c) 2025 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +set base_name {taxi_eth_phy_10g_us_gth} + +set preset {GTH-10GBASE-R} + +set freerun_freq {125} +set line_rate {10.3125} +set refclk_freq {156.25} +set sec_line_rate {0} +set sec_refclk_freq $refclk_freq +set qpll_fracn [expr {int(fmod($line_rate*1000/2 / $refclk_freq, 1)*pow(2, 24))}] +set sec_qpll_fracn [expr {int(fmod($sec_line_rate*1000/2 / $sec_refclk_freq, 1)*pow(2, 24))}] +set user_data_width {32} +set int_data_width $user_data_width +set rx_eq_mode {DFE} +set extra_ports [list] +set extra_pll_ports [list] +# PLL reset and power down +lappend extra_pll_ports qpll0reset_in qpll1reset_in +lappend extra_pll_ports qpll0pd_in qpll1pd_in +# PLL clocking +lappend extra_pll_ports gtrefclk00_in qpll0lock_out qpll0outclk_out qpll0outrefclk_out +lappend extra_pll_ports gtrefclk01_in qpll1lock_out qpll1outclk_out qpll1outrefclk_out +# PCIe +if {[string first uplus [get_property FAMILY [get_property PART [current_project]]]] != -1} { + lappend extra_pll_ports pcierateqpll0_in pcierateqpll1_in +} else { + lappend extra_pll_ports qpllrsvd2_in qpllrsvd3_in +} +# channel reset +lappend extra_ports gttxreset_in txuserrdy_in txpmareset_in txpcsreset_in txprogdivreset_in txresetdone_out txpmaresetdone_out txprgdivresetdone_out +lappend extra_ports gtrxreset_in rxuserrdy_in rxpmareset_in rxdfelpmreset_in eyescanreset_in rxpcsreset_in rxprogdivreset_in rxresetdone_out rxpmaresetdone_out rxprgdivresetdone_out +# channel power down +lappend extra_ports txpd_in txpdelecidlemode_in rxpd_in +# channel clock selection +lappend extra_ports txsysclksel_in txpllclksel_in rxsysclksel_in rxpllclksel_in +# channel polarity +lappend extra_ports txpolarity_in rxpolarity_in +# channel TX driver +lappend extra_ports txelecidle_in txinhibit_in txdiffctrl_in txmaincursor_in txprecursor_in txpostcursor_in +# channel CDR +lappend extra_ports rxcdrlock_out rxcdrhold_in rxcdrovrden_in +# channel EQ +lappend extra_ports rxlpmen_in + +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 RX_EQ_MODE $rx_eq_mode +if {$sec_line_rate != 0} { + dict set config SECONDARY_QPLL_ENABLE true + dict set config SECONDARY_QPLL_FRACN_NUMERATOR $sec_qpll_fracn + dict set config SECONDARY_QPLL_LINE_RATE $sec_line_rate + dict set config SECONDARY_QPLL_REFCLK_FREQUENCY $sec_refclk_freq +} else { + dict set config SECONDARY_QPLL_ENABLE false +} +dict set config ENABLE_OPTIONAL_PORTS $extra_ports +dict set config LOCATE_COMMON {CORE} +dict set config LOCATE_RESET_CONTROLLER {EXAMPLE_DESIGN} +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 +} + +# normal latency (async gearbox) +dict set config TX_DATA_ENCODING {64B66B_ASYNC} +dict set config TX_BUFFER_MODE {1} +dict set config TX_OUTCLK_SOURCE {TXPROGDIVCLK} +dict set config RX_DATA_DECODING {64B66B_ASYNC} +dict set config RX_BUFFER_MODE {1} +dict set config RX_OUTCLK_SOURCE {RXPROGDIVCLK} + +# 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}_ch" $preset $config + +# low latency (async gearbox with buffer bypass) +dict set config TX_DATA_ENCODING {64B66B} +dict set config TX_BUFFER_MODE {0} +dict set config TX_OUTCLK_SOURCE {TXPROGDIVCLK} +dict set config RX_DATA_DECODING {64B66B} +dict set config RX_BUFFER_MODE {0} +dict set config RX_OUTCLK_SOURCE {RXOUTCLKPMA} + +# 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}_ll_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}_ll_ch" $preset $config diff --git a/src/eth/rtl/us/taxi_eth_phy_10g_us_gth_161.tcl b/src/eth/rtl/us/taxi_eth_phy_10g_us_gth_161.tcl new file mode 100644 index 0000000..88095d1 --- /dev/null +++ b/src/eth/rtl/us/taxi_eth_phy_10g_us_gth_161.tcl @@ -0,0 +1,132 @@ +# SPDX-License-Identifier: CERN-OHL-S-2.0 +# +# Copyright (c) 2025 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +set base_name {taxi_eth_phy_10g_us_gth} + +set preset {GTH-10GBASE-R} + +set freerun_freq {125} +set line_rate {10.3125} +set refclk_freq {161.1328125} +set sec_line_rate {0} +set sec_refclk_freq $refclk_freq +set qpll_fracn [expr {int(fmod($line_rate*1000/2 / $refclk_freq, 1)*pow(2, 24))}] +set sec_qpll_fracn [expr {int(fmod($sec_line_rate*1000/2 / $sec_refclk_freq, 1)*pow(2, 24))}] +set user_data_width {32} +set int_data_width $user_data_width +set rx_eq_mode {DFE} +set extra_ports [list] +set extra_pll_ports [list] +# PLL reset and power down +lappend extra_pll_ports qpll0reset_in qpll1reset_in +lappend extra_pll_ports qpll0pd_in qpll1pd_in +# PLL clocking +lappend extra_pll_ports gtrefclk00_in qpll0lock_out qpll0outclk_out qpll0outrefclk_out +lappend extra_pll_ports gtrefclk01_in qpll1lock_out qpll1outclk_out qpll1outrefclk_out +# PCIe +if {[string first uplus [get_property FAMILY [get_property PART [current_project]]]] != -1} { + lappend extra_pll_ports pcierateqpll0_in pcierateqpll1_in +} else { + lappend extra_pll_ports qpllrsvd2_in qpllrsvd3_in +} +# channel reset +lappend extra_ports gttxreset_in txuserrdy_in txpmareset_in txpcsreset_in txprogdivreset_in txresetdone_out txpmaresetdone_out txprgdivresetdone_out +lappend extra_ports gtrxreset_in rxuserrdy_in rxpmareset_in rxdfelpmreset_in eyescanreset_in rxpcsreset_in rxprogdivreset_in rxresetdone_out rxpmaresetdone_out rxprgdivresetdone_out +# channel power down +lappend extra_ports txpd_in txpdelecidlemode_in rxpd_in +# channel clock selection +lappend extra_ports txsysclksel_in txpllclksel_in rxsysclksel_in rxpllclksel_in +# channel polarity +lappend extra_ports txpolarity_in rxpolarity_in +# channel TX driver +lappend extra_ports txelecidle_in txinhibit_in txdiffctrl_in txmaincursor_in txprecursor_in txpostcursor_in +# channel CDR +lappend extra_ports rxcdrlock_out rxcdrhold_in rxcdrovrden_in +# channel EQ +lappend extra_ports rxlpmen_in + +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 RX_EQ_MODE $rx_eq_mode +if {$sec_line_rate != 0} { + dict set config SECONDARY_QPLL_ENABLE true + dict set config SECONDARY_QPLL_FRACN_NUMERATOR $sec_qpll_fracn + dict set config SECONDARY_QPLL_LINE_RATE $sec_line_rate + dict set config SECONDARY_QPLL_REFCLK_FREQUENCY $sec_refclk_freq +} else { + dict set config SECONDARY_QPLL_ENABLE false +} +dict set config ENABLE_OPTIONAL_PORTS $extra_ports +dict set config LOCATE_COMMON {CORE} +dict set config LOCATE_RESET_CONTROLLER {EXAMPLE_DESIGN} +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 +} + +# normal latency (async gearbox) +dict set config TX_DATA_ENCODING {64B66B_ASYNC} +dict set config TX_BUFFER_MODE {1} +dict set config TX_OUTCLK_SOURCE {TXPROGDIVCLK} +dict set config RX_DATA_DECODING {64B66B_ASYNC} +dict set config RX_BUFFER_MODE {1} +dict set config RX_OUTCLK_SOURCE {RXPROGDIVCLK} + +# 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}_ch" $preset $config + +# low latency (async gearbox with buffer bypass) +dict set config TX_DATA_ENCODING {64B66B} +dict set config TX_BUFFER_MODE {0} +dict set config TX_OUTCLK_SOURCE {TXPROGDIVCLK} +dict set config RX_DATA_DECODING {64B66B} +dict set config RX_BUFFER_MODE {0} +dict set config RX_OUTCLK_SOURCE {RXOUTCLKPMA} + +# 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}_ll_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}_ll_ch" $preset $config diff --git a/src/eth/rtl/us/taxi_eth_phy_10g_us_gth_322.tcl b/src/eth/rtl/us/taxi_eth_phy_10g_us_gth_322.tcl new file mode 100644 index 0000000..9ea5a4e --- /dev/null +++ b/src/eth/rtl/us/taxi_eth_phy_10g_us_gth_322.tcl @@ -0,0 +1,132 @@ +# SPDX-License-Identifier: CERN-OHL-S-2.0 +# +# Copyright (c) 2025 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +set base_name {taxi_eth_phy_10g_us_gth} + +set preset {GTH-10GBASE-R} + +set freerun_freq {125} +set line_rate {10.3125} +set refclk_freq {322.265625} +set sec_line_rate {0} +set sec_refclk_freq $refclk_freq +set qpll_fracn [expr {int(fmod($line_rate*1000/2 / $refclk_freq, 1)*pow(2, 24))}] +set sec_qpll_fracn [expr {int(fmod($sec_line_rate*1000/2 / $sec_refclk_freq, 1)*pow(2, 24))}] +set user_data_width {32} +set int_data_width $user_data_width +set rx_eq_mode {DFE} +set extra_ports [list] +set extra_pll_ports [list] +# PLL reset and power down +lappend extra_pll_ports qpll0reset_in qpll1reset_in +lappend extra_pll_ports qpll0pd_in qpll1pd_in +# PLL clocking +lappend extra_pll_ports gtrefclk00_in qpll0lock_out qpll0outclk_out qpll0outrefclk_out +lappend extra_pll_ports gtrefclk01_in qpll1lock_out qpll1outclk_out qpll1outrefclk_out +# PCIe +if {[string first uplus [get_property FAMILY [get_property PART [current_project]]]] != -1} { + lappend extra_pll_ports pcierateqpll0_in pcierateqpll1_in +} else { + lappend extra_pll_ports qpllrsvd2_in qpllrsvd3_in +} +# channel reset +lappend extra_ports gttxreset_in txuserrdy_in txpmareset_in txpcsreset_in txprogdivreset_in txresetdone_out txpmaresetdone_out txprgdivresetdone_out +lappend extra_ports gtrxreset_in rxuserrdy_in rxpmareset_in rxdfelpmreset_in eyescanreset_in rxpcsreset_in rxprogdivreset_in rxresetdone_out rxpmaresetdone_out rxprgdivresetdone_out +# channel power down +lappend extra_ports txpd_in txpdelecidlemode_in rxpd_in +# channel clock selection +lappend extra_ports txsysclksel_in txpllclksel_in rxsysclksel_in rxpllclksel_in +# channel polarity +lappend extra_ports txpolarity_in rxpolarity_in +# channel TX driver +lappend extra_ports txelecidle_in txinhibit_in txdiffctrl_in txmaincursor_in txprecursor_in txpostcursor_in +# channel CDR +lappend extra_ports rxcdrlock_out rxcdrhold_in rxcdrovrden_in +# channel EQ +lappend extra_ports rxlpmen_in + +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 RX_EQ_MODE $rx_eq_mode +if {$sec_line_rate != 0} { + dict set config SECONDARY_QPLL_ENABLE true + dict set config SECONDARY_QPLL_FRACN_NUMERATOR $sec_qpll_fracn + dict set config SECONDARY_QPLL_LINE_RATE $sec_line_rate + dict set config SECONDARY_QPLL_REFCLK_FREQUENCY $sec_refclk_freq +} else { + dict set config SECONDARY_QPLL_ENABLE false +} +dict set config ENABLE_OPTIONAL_PORTS $extra_ports +dict set config LOCATE_COMMON {CORE} +dict set config LOCATE_RESET_CONTROLLER {EXAMPLE_DESIGN} +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 +} + +# normal latency (async gearbox) +dict set config TX_DATA_ENCODING {64B66B_ASYNC} +dict set config TX_BUFFER_MODE {1} +dict set config TX_OUTCLK_SOURCE {TXPROGDIVCLK} +dict set config RX_DATA_DECODING {64B66B_ASYNC} +dict set config RX_BUFFER_MODE {1} +dict set config RX_OUTCLK_SOURCE {RXPROGDIVCLK} + +# 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}_ch" $preset $config + +# low latency (async gearbox with buffer bypass) +dict set config TX_DATA_ENCODING {64B66B} +dict set config TX_BUFFER_MODE {0} +dict set config TX_OUTCLK_SOURCE {TXPROGDIVCLK} +dict set config RX_DATA_DECODING {64B66B} +dict set config RX_BUFFER_MODE {0} +dict set config RX_OUTCLK_SOURCE {RXOUTCLKPMA} + +# 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}_ll_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}_ll_ch" $preset $config diff --git a/src/eth/rtl/us/taxi_eth_phy_10g_us_gty_156.tcl b/src/eth/rtl/us/taxi_eth_phy_10g_us_gty_156.tcl new file mode 100644 index 0000000..8360cb1 --- /dev/null +++ b/src/eth/rtl/us/taxi_eth_phy_10g_us_gty_156.tcl @@ -0,0 +1,132 @@ +# SPDX-License-Identifier: CERN-OHL-S-2.0 +# +# Copyright (c) 2025 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +set base_name {taxi_eth_phy_10g_us_gty} + +set preset {GTY-10GBASE-R} + +set freerun_freq {125} +set line_rate {10.3125} +set refclk_freq {156.25} +set sec_line_rate {0} +set sec_refclk_freq $refclk_freq +set qpll_fracn [expr {int(fmod($line_rate*1000/2 / $refclk_freq, 1)*pow(2, 24))}] +set sec_qpll_fracn [expr {int(fmod($sec_line_rate*1000/2 / $sec_refclk_freq, 1)*pow(2, 24))}] +set user_data_width {32} +set int_data_width $user_data_width +set rx_eq_mode {DFE} +set extra_ports [list] +set extra_pll_ports [list] +# PLL reset and power down +lappend extra_pll_ports qpll0reset_in qpll1reset_in +lappend extra_pll_ports qpll0pd_in qpll1pd_in +# PLL clocking +lappend extra_pll_ports gtrefclk00_in qpll0lock_out qpll0outclk_out qpll0outrefclk_out +lappend extra_pll_ports gtrefclk01_in qpll1lock_out qpll1outclk_out qpll1outrefclk_out +# PCIe +if {[string first uplus [get_property FAMILY [get_property PART [current_project]]]] != -1} { + lappend extra_pll_ports pcierateqpll0_in pcierateqpll1_in +} else { + lappend extra_pll_ports qpllrsvd2_in qpllrsvd3_in +} +# channel reset +lappend extra_ports gttxreset_in txuserrdy_in txpmareset_in txpcsreset_in txprogdivreset_in txresetdone_out txpmaresetdone_out txprgdivresetdone_out +lappend extra_ports gtrxreset_in rxuserrdy_in rxpmareset_in rxdfelpmreset_in eyescanreset_in rxpcsreset_in rxprogdivreset_in rxresetdone_out rxpmaresetdone_out rxprgdivresetdone_out +# channel power down +lappend extra_ports txpd_in txpdelecidlemode_in rxpd_in +# channel clock selection +lappend extra_ports txsysclksel_in txpllclksel_in rxsysclksel_in rxpllclksel_in +# channel polarity +lappend extra_ports txpolarity_in rxpolarity_in +# channel TX driver +lappend extra_ports txelecidle_in txinhibit_in txdiffctrl_in txmaincursor_in txprecursor_in txpostcursor_in +# channel CDR +lappend extra_ports rxcdrlock_out rxcdrhold_in rxcdrovrden_in +# channel EQ +lappend extra_ports rxlpmen_in + +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 RX_EQ_MODE $rx_eq_mode +if {$sec_line_rate != 0} { + dict set config SECONDARY_QPLL_ENABLE true + dict set config SECONDARY_QPLL_FRACN_NUMERATOR $sec_qpll_fracn + dict set config SECONDARY_QPLL_LINE_RATE $sec_line_rate + dict set config SECONDARY_QPLL_REFCLK_FREQUENCY $sec_refclk_freq +} else { + dict set config SECONDARY_QPLL_ENABLE false +} +dict set config ENABLE_OPTIONAL_PORTS $extra_ports +dict set config LOCATE_COMMON {CORE} +dict set config LOCATE_RESET_CONTROLLER {EXAMPLE_DESIGN} +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 +} + +# normal latency (async gearbox) +dict set config TX_DATA_ENCODING {64B66B_ASYNC} +dict set config TX_BUFFER_MODE {1} +dict set config TX_OUTCLK_SOURCE {TXPROGDIVCLK} +dict set config RX_DATA_DECODING {64B66B_ASYNC} +dict set config RX_BUFFER_MODE {1} +dict set config RX_OUTCLK_SOURCE {RXPROGDIVCLK} + +# 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}_ch" $preset $config + +# low latency (async gearbox with buffer bypass) +dict set config TX_DATA_ENCODING {64B66B} +dict set config TX_BUFFER_MODE {0} +dict set config TX_OUTCLK_SOURCE {TXPROGDIVCLK} +dict set config RX_DATA_DECODING {64B66B} +dict set config RX_BUFFER_MODE {0} +dict set config RX_OUTCLK_SOURCE {RXOUTCLKPMA} + +# 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}_ll_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}_ll_ch" $preset $config diff --git a/src/eth/rtl/us/taxi_eth_phy_10g_us_gty_161.tcl b/src/eth/rtl/us/taxi_eth_phy_10g_us_gty_161.tcl new file mode 100644 index 0000000..a7061d2 --- /dev/null +++ b/src/eth/rtl/us/taxi_eth_phy_10g_us_gty_161.tcl @@ -0,0 +1,132 @@ +# SPDX-License-Identifier: CERN-OHL-S-2.0 +# +# Copyright (c) 2025 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +set base_name {taxi_eth_phy_10g_us_gty} + +set preset {GTY-10GBASE-R} + +set freerun_freq {125} +set line_rate {10.3125} +set refclk_freq {161.1328125} +set sec_line_rate {0} +set sec_refclk_freq $refclk_freq +set qpll_fracn [expr {int(fmod($line_rate*1000/2 / $refclk_freq, 1)*pow(2, 24))}] +set sec_qpll_fracn [expr {int(fmod($sec_line_rate*1000/2 / $sec_refclk_freq, 1)*pow(2, 24))}] +set user_data_width {32} +set int_data_width $user_data_width +set rx_eq_mode {DFE} +set extra_ports [list] +set extra_pll_ports [list] +# PLL reset and power down +lappend extra_pll_ports qpll0reset_in qpll1reset_in +lappend extra_pll_ports qpll0pd_in qpll1pd_in +# PLL clocking +lappend extra_pll_ports gtrefclk00_in qpll0lock_out qpll0outclk_out qpll0outrefclk_out +lappend extra_pll_ports gtrefclk01_in qpll1lock_out qpll1outclk_out qpll1outrefclk_out +# PCIe +if {[string first uplus [get_property FAMILY [get_property PART [current_project]]]] != -1} { + lappend extra_pll_ports pcierateqpll0_in pcierateqpll1_in +} else { + lappend extra_pll_ports qpllrsvd2_in qpllrsvd3_in +} +# channel reset +lappend extra_ports gttxreset_in txuserrdy_in txpmareset_in txpcsreset_in txprogdivreset_in txresetdone_out txpmaresetdone_out txprgdivresetdone_out +lappend extra_ports gtrxreset_in rxuserrdy_in rxpmareset_in rxdfelpmreset_in eyescanreset_in rxpcsreset_in rxprogdivreset_in rxresetdone_out rxpmaresetdone_out rxprgdivresetdone_out +# channel power down +lappend extra_ports txpd_in txpdelecidlemode_in rxpd_in +# channel clock selection +lappend extra_ports txsysclksel_in txpllclksel_in rxsysclksel_in rxpllclksel_in +# channel polarity +lappend extra_ports txpolarity_in rxpolarity_in +# channel TX driver +lappend extra_ports txelecidle_in txinhibit_in txdiffctrl_in txmaincursor_in txprecursor_in txpostcursor_in +# channel CDR +lappend extra_ports rxcdrlock_out rxcdrhold_in rxcdrovrden_in +# channel EQ +lappend extra_ports rxlpmen_in + +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 RX_EQ_MODE $rx_eq_mode +if {$sec_line_rate != 0} { + dict set config SECONDARY_QPLL_ENABLE true + dict set config SECONDARY_QPLL_FRACN_NUMERATOR $sec_qpll_fracn + dict set config SECONDARY_QPLL_LINE_RATE $sec_line_rate + dict set config SECONDARY_QPLL_REFCLK_FREQUENCY $sec_refclk_freq +} else { + dict set config SECONDARY_QPLL_ENABLE false +} +dict set config ENABLE_OPTIONAL_PORTS $extra_ports +dict set config LOCATE_COMMON {CORE} +dict set config LOCATE_RESET_CONTROLLER {EXAMPLE_DESIGN} +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 +} + +# normal latency (async gearbox) +dict set config TX_DATA_ENCODING {64B66B_ASYNC} +dict set config TX_BUFFER_MODE {1} +dict set config TX_OUTCLK_SOURCE {TXPROGDIVCLK} +dict set config RX_DATA_DECODING {64B66B_ASYNC} +dict set config RX_BUFFER_MODE {1} +dict set config RX_OUTCLK_SOURCE {RXPROGDIVCLK} + +# 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}_ch" $preset $config + +# low latency (async gearbox with buffer bypass) +dict set config TX_DATA_ENCODING {64B66B} +dict set config TX_BUFFER_MODE {0} +dict set config TX_OUTCLK_SOURCE {TXPROGDIVCLK} +dict set config RX_DATA_DECODING {64B66B} +dict set config RX_BUFFER_MODE {0} +dict set config RX_OUTCLK_SOURCE {RXOUTCLKPMA} + +# 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}_ll_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}_ll_ch" $preset $config diff --git a/src/eth/rtl/us/taxi_eth_phy_10g_us_gty_322.tcl b/src/eth/rtl/us/taxi_eth_phy_10g_us_gty_322.tcl new file mode 100644 index 0000000..1eb040c --- /dev/null +++ b/src/eth/rtl/us/taxi_eth_phy_10g_us_gty_322.tcl @@ -0,0 +1,132 @@ +# SPDX-License-Identifier: CERN-OHL-S-2.0 +# +# Copyright (c) 2025 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +set base_name {taxi_eth_phy_10g_us_gty} + +set preset {GTY-10GBASE-R} + +set freerun_freq {125} +set line_rate {10.3125} +set refclk_freq {322.265625} +set sec_line_rate {0} +set sec_refclk_freq $refclk_freq +set qpll_fracn [expr {int(fmod($line_rate*1000/2 / $refclk_freq, 1)*pow(2, 24))}] +set sec_qpll_fracn [expr {int(fmod($sec_line_rate*1000/2 / $sec_refclk_freq, 1)*pow(2, 24))}] +set user_data_width {32} +set int_data_width $user_data_width +set rx_eq_mode {DFE} +set extra_ports [list] +set extra_pll_ports [list] +# PLL reset and power down +lappend extra_pll_ports qpll0reset_in qpll1reset_in +lappend extra_pll_ports qpll0pd_in qpll1pd_in +# PLL clocking +lappend extra_pll_ports gtrefclk00_in qpll0lock_out qpll0outclk_out qpll0outrefclk_out +lappend extra_pll_ports gtrefclk01_in qpll1lock_out qpll1outclk_out qpll1outrefclk_out +# PCIe +if {[string first uplus [get_property FAMILY [get_property PART [current_project]]]] != -1} { + lappend extra_pll_ports pcierateqpll0_in pcierateqpll1_in +} else { + lappend extra_pll_ports qpllrsvd2_in qpllrsvd3_in +} +# channel reset +lappend extra_ports gttxreset_in txuserrdy_in txpmareset_in txpcsreset_in txprogdivreset_in txresetdone_out txpmaresetdone_out txprgdivresetdone_out +lappend extra_ports gtrxreset_in rxuserrdy_in rxpmareset_in rxdfelpmreset_in eyescanreset_in rxpcsreset_in rxprogdivreset_in rxresetdone_out rxpmaresetdone_out rxprgdivresetdone_out +# channel power down +lappend extra_ports txpd_in txpdelecidlemode_in rxpd_in +# channel clock selection +lappend extra_ports txsysclksel_in txpllclksel_in rxsysclksel_in rxpllclksel_in +# channel polarity +lappend extra_ports txpolarity_in rxpolarity_in +# channel TX driver +lappend extra_ports txelecidle_in txinhibit_in txdiffctrl_in txmaincursor_in txprecursor_in txpostcursor_in +# channel CDR +lappend extra_ports rxcdrlock_out rxcdrhold_in rxcdrovrden_in +# channel EQ +lappend extra_ports rxlpmen_in + +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 RX_EQ_MODE $rx_eq_mode +if {$sec_line_rate != 0} { + dict set config SECONDARY_QPLL_ENABLE true + dict set config SECONDARY_QPLL_FRACN_NUMERATOR $sec_qpll_fracn + dict set config SECONDARY_QPLL_LINE_RATE $sec_line_rate + dict set config SECONDARY_QPLL_REFCLK_FREQUENCY $sec_refclk_freq +} else { + dict set config SECONDARY_QPLL_ENABLE false +} +dict set config ENABLE_OPTIONAL_PORTS $extra_ports +dict set config LOCATE_COMMON {CORE} +dict set config LOCATE_RESET_CONTROLLER {EXAMPLE_DESIGN} +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 +} + +# normal latency (async gearbox) +dict set config TX_DATA_ENCODING {64B66B_ASYNC} +dict set config TX_BUFFER_MODE {1} +dict set config TX_OUTCLK_SOURCE {TXPROGDIVCLK} +dict set config RX_DATA_DECODING {64B66B_ASYNC} +dict set config RX_BUFFER_MODE {1} +dict set config RX_OUTCLK_SOURCE {RXPROGDIVCLK} + +# 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}_ch" $preset $config + +# low latency (async gearbox with buffer bypass) +dict set config TX_DATA_ENCODING {64B66B} +dict set config TX_BUFFER_MODE {0} +dict set config TX_OUTCLK_SOURCE {TXPROGDIVCLK} +dict set config RX_DATA_DECODING {64B66B} +dict set config RX_BUFFER_MODE {0} +dict set config RX_OUTCLK_SOURCE {RXOUTCLKPMA} + +# 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}_ll_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}_ll_ch" $preset $config