diff --git a/rtl/eth/us/taxi_eth_mac_25g_us.f b/rtl/eth/us/taxi_eth_mac_25g_us.f new file mode 100644 index 0000000..2dd5758 --- /dev/null +++ b/rtl/eth/us/taxi_eth_mac_25g_us.f @@ -0,0 +1,3 @@ +taxi_eth_mac_25g_us.sv +taxi_eth_mac_25g_us_ch.sv +../taxi_eth_mac_phy_10g.f diff --git a/rtl/eth/us/taxi_eth_mac_25g_us.sv b/rtl/eth/us/taxi_eth_mac_25g_us.sv new file mode 100644 index 0000000..9198ca9 --- /dev/null +++ b/rtl/eth/us/taxi_eth_mac_25g_us.sv @@ -0,0 +1,402 @@ +// 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 and MAC/PHY quad wrapper for UltraScale/UltraScale+ + */ +module taxi_eth_mac_25g_us # +( + parameter logic SIM = 1'b0, + parameter string VENDOR = "XILINX", + parameter string FAMILY = "virtexuplus", + + parameter CNT = 4, + + // GT type + parameter string GT_TYPE = "GTY", + + // MAC/PHY parameters + parameter logic PADDING_EN = 1'b1, + parameter logic DIC_EN = 1'b1, + parameter MIN_FRAME_LEN = 64, + parameter logic PTP_TS_EN = 1'b0, + parameter logic PTP_TS_FMT_TOD = 1'b1, + parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64, + parameter logic PRBS31_EN = 1'b0, + parameter TX_SERDES_PIPELINE = 1, + parameter RX_SERDES_PIPELINE = 1, + parameter BITSLIP_HIGH_CYCLES = 0, + parameter BITSLIP_LOW_CYCLES = 7, + parameter COUNT_125US = 125000/6.4 +) +( + input wire logic xcvr_ctrl_clk, + input wire logic xcvr_ctrl_rst, + + /* + * Common + */ + output wire logic xcvr_gtpowergood_out, + input wire logic xcvr_gtrefclk00_in, + output wire logic xcvr_qpll0lock_out, + output wire logic xcvr_qpll0clk_out, + output wire logic xcvr_qpll0refclk_out, + + /* + * Serial data + */ + output wire logic [CNT-1:0] xcvr_txp, + output wire logic [CNT-1:0] xcvr_txn, + input wire logic [CNT-1:0] xcvr_rxp, + input wire logic [CNT-1:0] xcvr_rxn, + + /* + * MAC clocks + */ + output wire logic [CNT-1:0] rx_clk, + input wire logic [CNT-1:0] rx_rst_in, + output wire logic [CNT-1:0] rx_rst_out, + output wire logic [CNT-1:0] tx_clk, + input wire logic [CNT-1:0] tx_rst_in, + output wire logic [CNT-1:0] tx_rst_out, + input wire logic [CNT-1:0] ptp_sample_clk, + + /* + * Transmit interface (AXI stream) + */ + taxi_axis_if.snk s_axis_tx[CNT-1:0], + taxi_axis_if.src m_axis_tx_cpl[CNT-1:0], + + /* + * Receive interface (AXI stream) + */ + taxi_axis_if.src m_axis_rx[CNT-1:0], + + /* + * PTP clock + */ + input wire logic [CNT-1:0][PTP_TS_W-1:0] tx_ptp_ts = '0, + input wire logic [CNT-1:0] tx_ptp_ts_step = '0, + input wire logic [CNT-1:0][PTP_TS_W-1:0] rx_ptp_ts = '0, + input wire logic [CNT-1:0] rx_ptp_ts_step = '0, + + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + input wire logic [CNT-1:0] tx_lfc_req = '0, + input wire logic [CNT-1:0] tx_lfc_resend = '0, + input wire logic [CNT-1:0] rx_lfc_en = '0, + output wire logic [CNT-1:0] rx_lfc_req, + input wire logic [CNT-1:0] rx_lfc_ack = '0, + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + input wire logic [CNT-1:0][7:0] tx_pfc_req = '0, + input wire logic [CNT-1:0] tx_pfc_resend = '0, + input wire logic [CNT-1:0][7:0] rx_pfc_en = '0, + output wire logic [CNT-1:0][7:0] rx_pfc_req, + input wire logic [CNT-1:0][7:0] rx_pfc_ack = '0, + + /* + * Pause interface + */ + input wire logic [CNT-1:0] tx_lfc_pause_en = '0, + input wire logic [CNT-1:0] tx_pause_req = '0, + output wire logic [CNT-1:0] tx_pause_ack, + + /* + * Status + */ + output wire logic [CNT-1:0][1:0] tx_start_packet, + output wire logic [CNT-1:0] tx_error_underflow, + output wire logic [CNT-1:0][1:0] rx_start_packet, + output wire logic [CNT-1:0][6:0] rx_error_count, + output wire logic [CNT-1:0] rx_error_bad_frame, + output wire logic [CNT-1:0] rx_error_bad_fcs, + output wire logic [CNT-1:0] rx_bad_block, + output wire logic [CNT-1:0] rx_sequence_error, + output wire logic [CNT-1:0] rx_block_lock, + output wire logic [CNT-1:0] rx_high_ber, + output wire logic [CNT-1:0] rx_status, + output wire logic [CNT-1:0] stat_tx_mcf, + output wire logic [CNT-1:0] stat_rx_mcf, + output wire logic [CNT-1:0] stat_tx_lfc_pkt, + output wire logic [CNT-1:0] stat_tx_lfc_xon, + output wire logic [CNT-1:0] stat_tx_lfc_xoff, + output wire logic [CNT-1:0] stat_tx_lfc_paused, + output wire logic [CNT-1:0] stat_tx_pfc_pkt, + output wire logic [CNT-1:0][7:0] stat_tx_pfc_xon, + output wire logic [CNT-1:0][7:0] stat_tx_pfc_xoff, + output wire logic [CNT-1:0][7:0] stat_tx_pfc_paused, + output wire logic [CNT-1:0] stat_rx_lfc_pkt, + output wire logic [CNT-1:0] stat_rx_lfc_xon, + output wire logic [CNT-1:0] stat_rx_lfc_xoff, + output wire logic [CNT-1:0] stat_rx_lfc_paused, + output wire logic [CNT-1:0] stat_rx_pfc_pkt, + output wire logic [CNT-1:0][7:0] stat_rx_pfc_xon, + output wire logic [CNT-1:0][7:0] stat_rx_pfc_xoff, + output wire logic [CNT-1:0][7:0] stat_rx_pfc_paused, + + /* + * Configuration + */ + input wire logic [CNT-1:0][7:0] cfg_ifg = '{CNT{8'd12}}, + input wire logic [CNT-1:0] cfg_tx_enable = '1, + input wire logic [CNT-1:0] cfg_rx_enable = '1, + input wire logic [CNT-1:0] cfg_tx_prbs31_enable = '0, + input wire logic [CNT-1:0] cfg_rx_prbs31_enable = '0, + input wire logic [CNT-1:0][47:0] cfg_mcf_rx_eth_dst_mcast = '{CNT{48'h01_80_C2_00_00_01}}, + input wire logic [CNT-1:0] cfg_mcf_rx_check_eth_dst_mcast = '1, + input wire logic [CNT-1:0][47:0] cfg_mcf_rx_eth_dst_ucast = '{CNT{48'd0}}, + input wire logic [CNT-1:0] cfg_mcf_rx_check_eth_dst_ucast = '0, + input wire logic [CNT-1:0][47:0] cfg_mcf_rx_eth_src = '{CNT{48'd0}}, + input wire logic [CNT-1:0] cfg_mcf_rx_check_eth_src = '0, + input wire logic [CNT-1:0][15:0] cfg_mcf_rx_eth_type = '{CNT{16'h8808}}, + input wire logic [CNT-1:0][15:0] cfg_mcf_rx_opcode_lfc = '{CNT{16'h0001}}, + input wire logic [CNT-1:0] cfg_mcf_rx_check_opcode_lfc = '1, + input wire logic [CNT-1:0][15:0] cfg_mcf_rx_opcode_pfc = '{CNT{16'h0101}}, + input wire logic [CNT-1:0] cfg_mcf_rx_check_opcode_pfc = '1, + input wire logic [CNT-1:0] cfg_mcf_rx_forward = '0, + input wire logic [CNT-1:0] cfg_mcf_rx_enable = '0, + input wire logic [CNT-1:0][47:0] cfg_tx_lfc_eth_dst = '{CNT{48'h01_80_C2_00_00_01}}, + input wire logic [CNT-1:0][47:0] cfg_tx_lfc_eth_src = '{CNT{48'h80_23_31_43_54_4C}}, + input wire logic [CNT-1:0][15:0] cfg_tx_lfc_eth_type = '{CNT{16'h8808}}, + input wire logic [CNT-1:0][15:0] cfg_tx_lfc_opcode = '{CNT{16'h0001}}, + input wire logic [CNT-1:0] cfg_tx_lfc_en = '0, + input wire logic [CNT-1:0][15:0] cfg_tx_lfc_quanta = '{CNT{16'hffff}}, + input wire logic [CNT-1:0][15:0] cfg_tx_lfc_refresh = '{CNT{16'h7fff}}, + input wire logic [CNT-1:0][47:0] cfg_tx_pfc_eth_dst = '{CNT{48'h01_80_C2_00_00_01}}, + input wire logic [CNT-1:0][47:0] cfg_tx_pfc_eth_src = '{CNT{48'h80_23_31_43_54_4C}}, + input wire logic [CNT-1:0][15:0] cfg_tx_pfc_eth_type = '{CNT{16'h8808}}, + input wire logic [CNT-1:0][15:0] cfg_tx_pfc_opcode = '{CNT{16'h0101}}, + input wire logic [CNT-1:0] cfg_tx_pfc_en = '0, + input wire logic [CNT-1:0][7:0][15:0] cfg_tx_pfc_quanta = '{CNT{'{8{16'hffff}}}}, + input wire logic [CNT-1:0][7:0][15:0] cfg_tx_pfc_refresh = '{CNT{'{8{16'h7fff}}}}, + input wire logic [CNT-1:0][15:0] cfg_rx_lfc_opcode = '{CNT{16'h0001}}, + input wire logic [CNT-1:0] cfg_rx_lfc_en = '0, + input wire logic [CNT-1:0][15:0] cfg_rx_pfc_opcode = '{CNT{16'h0101}}, + input wire logic [CNT-1:0] cfg_rx_pfc_en = '0 +); + +for (genvar n = 0; n < CNT; n = n + 1) begin : ch + + localparam HAS_COMMON = n == 0; + + wire ch_gtpowergood_out; + + wire ch_qpll0lock_out; + wire ch_qpll0clk_out; + wire ch_qpll0refclk_out; + + if (HAS_COMMON) begin + // drive outputs from common + assign xcvr_gtpowergood_out = ch_gtpowergood_out; + + assign xcvr_qpll0lock_out = ch_qpll0lock_out; + assign xcvr_qpll0clk_out = ch_qpll0clk_out; + assign xcvr_qpll0refclk_out = ch_qpll0refclk_out; + end + + taxi_eth_mac_25g_us_ch #( + .SIM(SIM), + .VENDOR(VENDOR), + .FAMILY(FAMILY), + + .HAS_COMMON(HAS_COMMON), + + // GT type + .GT_TYPE(GT_TYPE), + + // PHY parameters + .PADDING_EN(PADDING_EN), + .DIC_EN(DIC_EN), + .MIN_FRAME_LEN(MIN_FRAME_LEN), + .PTP_TS_EN(PTP_TS_EN), + .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD), + .PTP_TS_W(PTP_TS_W), + .PRBS31_EN(PRBS31_EN), + .TX_SERDES_PIPELINE(TX_SERDES_PIPELINE), + .RX_SERDES_PIPELINE(RX_SERDES_PIPELINE), + .BITSLIP_HIGH_CYCLES(BITSLIP_HIGH_CYCLES), + .BITSLIP_LOW_CYCLES(BITSLIP_LOW_CYCLES), + .COUNT_125US(COUNT_125US) + ) + ch_inst ( + .xcvr_ctrl_clk(xcvr_ctrl_clk), + .xcvr_ctrl_rst(xcvr_ctrl_rst), + + /* + * Common + */ + .xcvr_gtpowergood_out(ch_gtpowergood_out), + + /* + * PLL out + */ + .xcvr_gtrefclk00_in(xcvr_gtrefclk00_in), + .xcvr_qpll0lock_out(ch_qpll0lock_out), + .xcvr_qpll0clk_out(ch_qpll0clk_out), + .xcvr_qpll0refclk_out(ch_qpll0refclk_out), + + /* + * PLL in + */ + .xcvr_qpll0lock_in(xcvr_qpll0lock_out), + .xcvr_qpll0reset_out(), + .xcvr_qpll0clk_in(xcvr_qpll0clk_out), + .xcvr_qpll0refclk_in(xcvr_qpll0refclk_out), + + /* + * Serial data + */ + .xcvr_txp(xcvr_txp[n]), + .xcvr_txn(xcvr_txn[n]), + .xcvr_rxp(xcvr_rxp[n]), + .xcvr_rxn(xcvr_rxn[n]), + + /* + * MAC clocks + */ + .rx_clk(rx_clk[n]), + .rx_rst_in(rx_rst_in[n]), + .rx_rst_out(rx_rst_out[n]), + .tx_clk(tx_clk[n]), + .tx_rst_in(tx_rst_in[n]), + .tx_rst_out(tx_rst_out[n]), + .ptp_sample_clk(ptp_sample_clk[n]), + + /* + * Transmit interface (AXI stream) + */ + .s_axis_tx(s_axis_tx[n]), + .m_axis_tx_cpl(m_axis_tx_cpl[n]), + + /* + * Receive interface (AXI stream) + */ + .m_axis_rx(m_axis_rx[n]), + + /* + * PTP clock + */ + .tx_ptp_ts(tx_ptp_ts[n]), + .tx_ptp_ts_step(tx_ptp_ts_step[n]), + .rx_ptp_ts(rx_ptp_ts[n]), + .rx_ptp_ts_step(rx_ptp_ts_step[n]), + + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(tx_lfc_req[n]), + .tx_lfc_resend(tx_lfc_resend[n]), + .rx_lfc_en(rx_lfc_en[n]), + .rx_lfc_req(rx_lfc_req[n]), + .rx_lfc_ack(rx_lfc_ack[n]), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(tx_pfc_req[n]), + .tx_pfc_resend(tx_pfc_resend[n]), + .rx_pfc_en(rx_pfc_en[n]), + .rx_pfc_req(rx_pfc_req[n]), + .rx_pfc_ack(rx_pfc_ack[n]), + + /* + * Pause interface + */ + .tx_lfc_pause_en(tx_lfc_pause_en[n]), + .tx_pause_req(tx_pause_req[n]), + .tx_pause_ack(tx_pause_ack[n]), + + /* + * Status + */ + .tx_start_packet(tx_start_packet[n]), + .tx_error_underflow(tx_error_underflow[n]), + .rx_start_packet(rx_start_packet[n]), + .rx_error_count(rx_error_count[n]), + .rx_error_bad_frame(rx_error_bad_frame[n]), + .rx_error_bad_fcs(rx_error_bad_fcs[n]), + .rx_bad_block(rx_bad_block[n]), + .rx_sequence_error(rx_sequence_error[n]), + .rx_block_lock(rx_block_lock[n]), + .rx_high_ber(rx_high_ber[n]), + .rx_status(rx_status[n]), + .stat_tx_mcf(stat_tx_mcf[n]), + .stat_rx_mcf(stat_rx_mcf[n]), + .stat_tx_lfc_pkt(stat_tx_lfc_pkt[n]), + .stat_tx_lfc_xon(stat_tx_lfc_xon[n]), + .stat_tx_lfc_xoff(stat_tx_lfc_xoff[n]), + .stat_tx_lfc_paused(stat_tx_lfc_paused[n]), + .stat_tx_pfc_pkt(stat_tx_pfc_pkt[n]), + .stat_tx_pfc_xon(stat_tx_pfc_xon[n]), + .stat_tx_pfc_xoff(stat_tx_pfc_xoff[n]), + .stat_tx_pfc_paused(stat_tx_pfc_paused[n]), + .stat_rx_lfc_pkt(stat_rx_lfc_pkt[n]), + .stat_rx_lfc_xon(stat_rx_lfc_xon[n]), + .stat_rx_lfc_xoff(stat_rx_lfc_xoff[n]), + .stat_rx_lfc_paused(stat_rx_lfc_paused[n]), + .stat_rx_pfc_pkt(stat_rx_pfc_pkt[n]), + .stat_rx_pfc_xon(stat_rx_pfc_xon[n]), + .stat_rx_pfc_xoff(stat_rx_pfc_xoff[n]), + .stat_rx_pfc_paused(stat_rx_pfc_paused[n]), + + /* + * Configuration + */ + .cfg_ifg(cfg_ifg[n]), + .cfg_tx_enable(cfg_tx_enable[n]), + .cfg_rx_enable(cfg_rx_enable[n]), + .cfg_tx_prbs31_enable(cfg_tx_prbs31_enable[n]), + .cfg_rx_prbs31_enable(cfg_rx_prbs31_enable[n]), + .cfg_mcf_rx_eth_dst_mcast(cfg_mcf_rx_eth_dst_mcast[n]), + .cfg_mcf_rx_check_eth_dst_mcast(cfg_mcf_rx_check_eth_dst_mcast[n]), + .cfg_mcf_rx_eth_dst_ucast(cfg_mcf_rx_eth_dst_ucast[n]), + .cfg_mcf_rx_check_eth_dst_ucast(cfg_mcf_rx_check_eth_dst_ucast[n]), + .cfg_mcf_rx_eth_src(cfg_mcf_rx_eth_src[n]), + .cfg_mcf_rx_check_eth_src(cfg_mcf_rx_check_eth_src[n]), + .cfg_mcf_rx_eth_type(cfg_mcf_rx_eth_type[n]), + .cfg_mcf_rx_opcode_lfc(cfg_mcf_rx_opcode_lfc[n]), + .cfg_mcf_rx_check_opcode_lfc(cfg_mcf_rx_check_opcode_lfc[n]), + .cfg_mcf_rx_opcode_pfc(cfg_mcf_rx_opcode_pfc[n]), + .cfg_mcf_rx_check_opcode_pfc(cfg_mcf_rx_check_opcode_pfc[n]), + .cfg_mcf_rx_forward(cfg_mcf_rx_forward[n]), + .cfg_mcf_rx_enable(cfg_mcf_rx_enable[n]), + .cfg_tx_lfc_eth_dst(cfg_tx_lfc_eth_dst[n]), + .cfg_tx_lfc_eth_src(cfg_tx_lfc_eth_src[n]), + .cfg_tx_lfc_eth_type(cfg_tx_lfc_eth_type[n]), + .cfg_tx_lfc_opcode(cfg_tx_lfc_opcode[n]), + .cfg_tx_lfc_en(cfg_tx_lfc_en[n]), + .cfg_tx_lfc_quanta(cfg_tx_lfc_quanta[n]), + .cfg_tx_lfc_refresh(cfg_tx_lfc_refresh[n]), + .cfg_tx_pfc_eth_dst(cfg_tx_pfc_eth_dst[n]), + .cfg_tx_pfc_eth_src(cfg_tx_pfc_eth_src[n]), + .cfg_tx_pfc_eth_type(cfg_tx_pfc_eth_type[n]), + .cfg_tx_pfc_opcode(cfg_tx_pfc_opcode[n]), + .cfg_tx_pfc_en(cfg_tx_pfc_en[n]), + .cfg_tx_pfc_quanta(cfg_tx_pfc_quanta[n]), + .cfg_tx_pfc_refresh(cfg_tx_pfc_refresh[n]), + .cfg_rx_lfc_opcode(cfg_rx_lfc_opcode[n]), + .cfg_rx_lfc_en(cfg_rx_lfc_en[n]), + .cfg_rx_pfc_opcode(cfg_rx_pfc_opcode[n]), + .cfg_rx_pfc_en(cfg_rx_pfc_en[n]) + ); + +end + +endmodule + +`resetall diff --git a/rtl/eth/us/taxi_eth_mac_25g_us_ch.sv b/rtl/eth/us/taxi_eth_mac_25g_us_ch.sv new file mode 100644 index 0000000..b860bf0 --- /dev/null +++ b/rtl/eth/us/taxi_eth_mac_25g_us_ch.sv @@ -0,0 +1,798 @@ +// 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 and MAC/PHY wrapper for UltraScale/UltraScale+ + */ +module taxi_eth_mac_25g_us_ch # +( + 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", + + // MAC/PHY parameters + parameter logic PADDING_EN = 1'b1, + parameter logic DIC_EN = 1'b1, + parameter MIN_FRAME_LEN = 64, + parameter logic PTP_TS_EN = 1'b0, + parameter logic PTP_TS_FMT_TOD = 1'b1, + parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64, + parameter logic PRBS31_EN = 1'b0, + parameter TX_SERDES_PIPELINE = 1, + parameter RX_SERDES_PIPELINE = 1, + parameter BITSLIP_HIGH_CYCLES = 0, + parameter BITSLIP_LOW_CYCLES = 7, + parameter COUNT_125US = 125000/6.4 +) +( + 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, + output wire logic xcvr_qpll0lock_out, + output wire logic xcvr_qpll0clk_out, + output wire logic xcvr_qpll0refclk_out, + + /* + * PLL in + */ + input wire logic xcvr_qpll0lock_in, + output wire logic xcvr_qpll0reset_out, + input wire logic xcvr_qpll0clk_in, + input wire logic xcvr_qpll0refclk_in, + + /* + * Serial data + */ + output wire logic xcvr_txp, + output wire logic xcvr_txn, + input wire logic xcvr_rxp, + input wire logic xcvr_rxn, + + /* + * MAC clocks + */ + output wire logic rx_clk, + input wire logic rx_rst_in, + output wire logic rx_rst_out, + output wire logic tx_clk, + input wire logic tx_rst_in, + output wire logic tx_rst_out, + input wire logic ptp_sample_clk, + + /* + * Transmit interface (AXI stream) + */ + taxi_axis_if.snk s_axis_tx, + taxi_axis_if.src m_axis_tx_cpl, + + /* + * Receive interface (AXI stream) + */ + taxi_axis_if.src m_axis_rx, + + /* + * PTP clock + */ + input wire logic [PTP_TS_W-1:0] tx_ptp_ts = '0, + input wire logic tx_ptp_ts_step = 1'b0, + input wire logic [PTP_TS_W-1:0] rx_ptp_ts = '0, + input wire logic rx_ptp_ts_step = 1'b0, + + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + input wire logic tx_lfc_req = 1'b0, + input wire logic tx_lfc_resend = 1'b0, + input wire logic rx_lfc_en = 1'b0, + output wire logic rx_lfc_req, + input wire logic rx_lfc_ack = 1'b0, + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + input wire logic [7:0] tx_pfc_req = '0, + input wire logic tx_pfc_resend = 1'b0, + input wire logic [7:0] rx_pfc_en = '0, + output wire logic [7:0] rx_pfc_req, + input wire logic [7:0] rx_pfc_ack = '0, + + /* + * Pause interface + */ + input wire logic tx_lfc_pause_en = 1'b0, + input wire logic tx_pause_req = 1'b0, + output wire logic tx_pause_ack, + + /* + * Status + */ + output wire logic [1:0] tx_start_packet, + output wire logic tx_error_underflow, + output wire logic [1:0] rx_start_packet, + output wire logic [6:0] rx_error_count, + output wire logic rx_error_bad_frame, + output wire logic rx_error_bad_fcs, + output wire logic rx_bad_block, + output wire logic rx_sequence_error, + output wire logic rx_block_lock, + output wire logic rx_high_ber, + output wire logic rx_status, + output wire logic stat_tx_mcf, + output wire logic stat_rx_mcf, + output wire logic stat_tx_lfc_pkt, + output wire logic stat_tx_lfc_xon, + output wire logic stat_tx_lfc_xoff, + output wire logic stat_tx_lfc_paused, + output wire logic stat_tx_pfc_pkt, + output wire logic [7:0] stat_tx_pfc_xon, + output wire logic [7:0] stat_tx_pfc_xoff, + output wire logic [7:0] stat_tx_pfc_paused, + output wire logic stat_rx_lfc_pkt, + output wire logic stat_rx_lfc_xon, + output wire logic stat_rx_lfc_xoff, + output wire logic stat_rx_lfc_paused, + output wire logic stat_rx_pfc_pkt, + output wire logic [7:0] stat_rx_pfc_xon, + output wire logic [7:0] stat_rx_pfc_xoff, + output wire logic [7:0] stat_rx_pfc_paused, + + /* + * Configuration + */ + input wire logic [7:0] cfg_ifg = 8'd12, + input wire logic cfg_tx_enable = 1'b1, + input wire logic cfg_rx_enable = 1'b1, + input wire logic cfg_tx_prbs31_enable = 1'b0, + input wire logic cfg_rx_prbs31_enable = 1'b0, + input wire logic [47:0] cfg_mcf_rx_eth_dst_mcast = 48'h01_80_C2_00_00_01, + input wire logic cfg_mcf_rx_check_eth_dst_mcast = 1'b1, + input wire logic [47:0] cfg_mcf_rx_eth_dst_ucast = 48'd0, + input wire logic cfg_mcf_rx_check_eth_dst_ucast = 1'b0, + input wire logic [47:0] cfg_mcf_rx_eth_src = 48'd0, + input wire logic cfg_mcf_rx_check_eth_src = 1'b0, + input wire logic [15:0] cfg_mcf_rx_eth_type = 16'h8808, + input wire logic [15:0] cfg_mcf_rx_opcode_lfc = 16'h0001, + input wire logic cfg_mcf_rx_check_opcode_lfc = 1'b1, + input wire logic [15:0] cfg_mcf_rx_opcode_pfc = 16'h0101, + input wire logic cfg_mcf_rx_check_opcode_pfc = 1'b1, + input wire logic cfg_mcf_rx_forward = 1'b0, + input wire logic cfg_mcf_rx_enable = 1'b0, + input wire logic [47:0] cfg_tx_lfc_eth_dst = 48'h01_80_C2_00_00_01, + input wire logic [47:0] cfg_tx_lfc_eth_src = 48'h80_23_31_43_54_4C, + input wire logic [15:0] cfg_tx_lfc_eth_type = 16'h8808, + input wire logic [15:0] cfg_tx_lfc_opcode = 16'h0001, + input wire logic cfg_tx_lfc_en = 1'b0, + input wire logic [15:0] cfg_tx_lfc_quanta = 16'hffff, + input wire logic [15:0] cfg_tx_lfc_refresh = 16'h7fff, + input wire logic [47:0] cfg_tx_pfc_eth_dst = 48'h01_80_C2_00_00_01, + input wire logic [47:0] cfg_tx_pfc_eth_src = 48'h80_23_31_43_54_4C, + input wire logic [15:0] cfg_tx_pfc_eth_type = 16'h8808, + input wire logic [15:0] cfg_tx_pfc_opcode = 16'h0101, + input wire logic cfg_tx_pfc_en = 1'b0, + input wire logic [7:0][15:0] cfg_tx_pfc_quanta = '{8{16'hffff}}, + input wire logic [7:0][15:0] cfg_tx_pfc_refresh = '{8{16'h7fff}}, + input wire logic [15:0] cfg_rx_lfc_opcode = 16'h0001, + input wire logic cfg_rx_lfc_en = 1'b0, + input wire logic [15:0] cfg_rx_pfc_opcode = 16'h0101, + input wire logic cfg_rx_pfc_en = 1'b0 +); + +localparam GT_USP = FAMILY == "kintexuplus" || FAMILY == "virtexuplus" || FAMILY == "virtexuplusHBM" + || FAMILY == "virtexuplus58G" || FAMILY == "zynquplus" || FAMILY == "zynquplusRFSOC"; + +localparam DATA_W = 64; +localparam HDR_W = 2; + +wire rx_reset_req; + +wire gt_reset_tx_datapath = tx_rst_in; +wire gt_reset_rx_datapath = rx_rst_in || rx_reset_req; + +wire gt_reset_tx_done; +wire gt_reset_rx_done; + +wire [5:0] gt_txheader; +wire [63:0] gt_txdata; +wire gt_rxgearboxslip; +wire [5:0] gt_rxheader; +wire [1:0] gt_rxheadervalid; +wire [63:0] gt_rxdata; +wire [1:0] gt_rxdatavalid; + +if (SIM) begin : xcvr + // simulation (no GT core) + + assign gt_reset_tx_done = !xcvr_ctrl_rst; + assign gt_reset_rx_done = !xcvr_ctrl_rst; + +end else if (HAS_COMMON && GT_TYPE == "GTY" && GT_USP) begin : xcvr + // UltraScale+ GTY (with common) + + taxi_eth_mac_25g_us_gty_full + taxi_eth_mac_25g_us_gty_full_inst ( + // Common + .gtwiz_reset_clk_freerun_in(xcvr_ctrl_clk), + .gtwiz_reset_all_in(xcvr_ctrl_rst), + .gtpowergood_out(xcvr_gtpowergood_out), + + // PLL + .gtrefclk00_in(xcvr_gtrefclk00_in), + .qpll0lock_out(xcvr_qpll0lock_out), + .qpll0outclk_out(xcvr_qpll0clk_out), + .qpll0outrefclk_out(xcvr_qpll0refclk_out), + + // Serial data + .gtytxp_out(xcvr_txp), + .gtytxn_out(xcvr_txn), + .gtyrxp_in(xcvr_rxp), + .gtyrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_reset_in(1'b0), + .gtwiz_userclk_tx_srcclk_out(), + .gtwiz_userclk_tx_usrclk_out(), + .gtwiz_userclk_tx_usrclk2_out(tx_clk), + .gtwiz_userclk_tx_active_out(), + .gtwiz_reset_tx_pll_and_datapath_in(1'b0), + .gtwiz_reset_tx_datapath_in(gt_reset_tx_datapath), + .gtwiz_reset_tx_done_out(gt_reset_tx_done), + .txpmaresetdone_out(), + .txprgdivresetdone_out(), + + .gtwiz_userdata_tx_in(gt_txdata), + .txheader_in(gt_txheader), + .txsequence_in(7'b0), + + // Receive + .gtwiz_userclk_rx_reset_in(1'b0), + .gtwiz_userclk_rx_srcclk_out(), + .gtwiz_userclk_rx_usrclk_out(), + .gtwiz_userclk_rx_usrclk2_out(rx_clk), + .gtwiz_userclk_rx_active_out(), + .gtwiz_reset_rx_pll_and_datapath_in(1'b0), + .gtwiz_reset_rx_datapath_in(gt_reset_rx_datapath), + .gtwiz_reset_rx_cdr_stable_out(), + .gtwiz_reset_rx_done_out(gt_reset_rx_done), + .rxpmaresetdone_out(), + .rxprgdivresetdone_out(), + + .rxgearboxslip_in(gt_rxgearboxslip), + .gtwiz_userdata_rx_out(gt_rxdata), + .rxdatavalid_out(gt_rxdatavalid), + .rxheader_out(gt_rxheader), + .rxheadervalid_out(gt_rxheadervalid), + .rxstartofseq_out() + ); + + assign xcvr_qpll0reset_out = 1'b0; + +end else if (HAS_COMMON && GT_TYPE == "GTH" && GT_USP) begin : xcvr + // UltraScale+ GTH (with common) + + taxi_eth_mac_25g_us_gth_full + taxi_eth_mac_25g_us_gth_full_inst ( + // Common + .gtwiz_reset_clk_freerun_in(xcvr_ctrl_clk), + .gtwiz_reset_all_in(xcvr_ctrl_rst), + .gtpowergood_out(xcvr_gtpowergood_out), + + // PLL + .gtrefclk00_in(xcvr_gtrefclk00_in), + .qpll0lock_out(xcvr_qpll0lock_out), + .qpll0outclk_out(xcvr_qpll0clk_out), + .qpll0outrefclk_out(xcvr_qpll0refclk_out), + + // Serial data + .gthtxp_out(xcvr_txp), + .gthtxn_out(xcvr_txn), + .gthrxp_in(xcvr_rxp), + .gthrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_reset_in(1'b0), + .gtwiz_userclk_tx_srcclk_out(), + .gtwiz_userclk_tx_usrclk_out(), + .gtwiz_userclk_tx_usrclk2_out(tx_clk), + .gtwiz_userclk_tx_active_out(), + .gtwiz_reset_tx_pll_and_datapath_in(1'b0), + .gtwiz_reset_tx_datapath_in(gt_reset_tx_datapath), + .gtwiz_reset_tx_done_out(gt_reset_tx_done), + .txpmaresetdone_out(), + .txprgdivresetdone_out(), + + .gtwiz_userdata_tx_in(gt_txdata), + .txheader_in(gt_txheader), + .txsequence_in(7'b0), + + // Receive + .gtwiz_userclk_rx_reset_in(1'b0), + .gtwiz_userclk_rx_srcclk_out(), + .gtwiz_userclk_rx_usrclk_out(), + .gtwiz_userclk_rx_usrclk2_out(rx_clk), + .gtwiz_userclk_rx_active_out(), + .gtwiz_reset_rx_pll_and_datapath_in(1'b0), + .gtwiz_reset_rx_datapath_in(gt_reset_rx_datapath), + .gtwiz_reset_rx_cdr_stable_out(), + .gtwiz_reset_rx_done_out(gt_reset_rx_done), + .rxpmaresetdone_out(), + .rxprgdivresetdone_out(), + + .rxgearboxslip_in(gt_rxgearboxslip), + .gtwiz_userdata_rx_out(gt_rxdata), + .rxdatavalid_out(gt_rxdatavalid), + .rxheader_out(gt_rxheader), + .rxheadervalid_out(gt_rxheadervalid), + .rxstartofseq_out() + ); + + assign xcvr_qpll0reset_out = 1'b0; + +end else if (HAS_COMMON && GT_TYPE == "GTY" && !GT_USP) begin : xcvr + // UltraScale GTY (with common) + + taxi_eth_mac_25g_us_gty_full + taxi_eth_mac_25g_us_gty_full_inst ( + // Common + .gtwiz_reset_clk_freerun_in(xcvr_ctrl_clk), + .gtwiz_reset_all_in(xcvr_ctrl_rst), + .gtpowergood_out(xcvr_gtpowergood_out), + + // PLL + .gtrefclk00_in(xcvr_gtrefclk00_in), + .qpll0lock_out(xcvr_qpll0lock_out), + .qpll0outclk_out(xcvr_qpll0clk_out), + .qpll0outrefclk_out(xcvr_qpll0refclk_out), + + // Serial data + .gtytxp_out(xcvr_txp), + .gtytxn_out(xcvr_txn), + .gtyrxp_in(xcvr_rxp), + .gtyrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_reset_in(1'b0), + .gtwiz_userclk_tx_srcclk_out(), + .gtwiz_userclk_tx_usrclk_out(), + .gtwiz_userclk_tx_usrclk2_out(tx_clk), + .gtwiz_userclk_tx_active_out(), + .gtwiz_reset_tx_pll_and_datapath_in(1'b0), + .gtwiz_reset_tx_datapath_in(gt_reset_tx_datapath), + .gtwiz_reset_tx_done_out(gt_reset_tx_done), + .txpmaresetdone_out(), + .txprgdivresetdone_out(), + + .gtwiz_userdata_tx_in(gt_txdata), + .txheader_in(gt_txheader), + .txsequence_in(7'b0), + + // Receive + .gtwiz_userclk_rx_reset_in(1'b0), + .gtwiz_userclk_rx_srcclk_out(), + .gtwiz_userclk_rx_usrclk_out(), + .gtwiz_userclk_rx_usrclk2_out(rx_clk), + .gtwiz_userclk_rx_active_out(), + .gtwiz_reset_rx_pll_and_datapath_in(1'b0), + .gtwiz_reset_rx_datapath_in(gt_reset_rx_datapath), + .gtwiz_reset_rx_cdr_stable_out(), + .gtwiz_reset_rx_done_out(gt_reset_rx_done), + .rxpmaresetdone_out(), + .rxprgdivresetdone_out(), + + .rxgearboxslip_in(gt_rxgearboxslip), + .gtwiz_userdata_rx_out(gt_rxdata), + .rxdatavalid_out(gt_rxdatavalid), + .rxheader_out(gt_rxheader), + .rxheadervalid_out(gt_rxheadervalid), + .rxstartofseq_out() + ); + + assign xcvr_qpll0reset_out = 1'b0; + +end else if (HAS_COMMON && GT_TYPE == "GTH" && !GT_USP) begin : xcvr + // UltraScale GTH (with common) + + taxi_eth_mac_25g_us_gth_full + taxi_eth_mac_25g_us_gth_full_inst ( + // Common + .gtwiz_reset_clk_freerun_in(xcvr_ctrl_clk), + .gtwiz_reset_all_in(xcvr_ctrl_rst), + .gtpowergood_out(xcvr_gtpowergood_out), + + // PLL + .gtrefclk00_in(xcvr_gtrefclk00_in), + .qpll0lock_out(xcvr_qpll0lock_out), + .qpll0outclk_out(xcvr_qpll0clk_out), + .qpll0outrefclk_out(xcvr_qpll0refclk_out), + + // Serial data + .gthtxp_out(xcvr_txp), + .gthtxn_out(xcvr_txn), + .gthrxp_in(xcvr_rxp), + .gthrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_reset_in(1'b0), + .gtwiz_userclk_tx_srcclk_out(), + .gtwiz_userclk_tx_usrclk_out(), + .gtwiz_userclk_tx_usrclk2_out(tx_clk), + .gtwiz_userclk_tx_active_out(), + .gtwiz_reset_tx_pll_and_datapath_in(1'b0), + .gtwiz_reset_tx_datapath_in(gt_reset_tx_datapath), + .gtwiz_reset_tx_done_out(gt_reset_tx_done), + .txpmaresetdone_out(), + .txprgdivresetdone_out(), + + .gtwiz_userdata_tx_in(gt_txdata), + .txheader_in(gt_txheader), + .txsequence_in(7'b0), + + // Receive + .gtwiz_userclk_rx_reset_in(1'b0), + .gtwiz_userclk_rx_srcclk_out(), + .gtwiz_userclk_rx_usrclk_out(), + .gtwiz_userclk_rx_usrclk2_out(rx_clk), + .gtwiz_userclk_rx_active_out(), + .gtwiz_reset_rx_pll_and_datapath_in(1'b0), + .gtwiz_reset_rx_datapath_in(gt_reset_rx_datapath), + .gtwiz_reset_rx_cdr_stable_out(), + .gtwiz_reset_rx_done_out(gt_reset_rx_done), + .rxpmaresetdone_out(), + .rxprgdivresetdone_out(), + + .rxgearboxslip_in(gt_rxgearboxslip), + .gtwiz_userdata_rx_out(gt_rxdata), + .rxdatavalid_out(gt_rxdatavalid), + .rxheader_out(gt_rxheader), + .rxheadervalid_out(gt_rxheadervalid), + .rxstartofseq_out() + ); + + assign xcvr_qpll0reset_out = 1'b0; + +end else if (!HAS_COMMON && GT_TYPE == "GTY") begin : xcvr + // UltraScale/UltraScale+ GTY (channel only) + + taxi_eth_mac_25g_us_gty_channel + taxi_eth_mac_25g_us_gty_channel_inst ( + // Common + .gtwiz_reset_clk_freerun_in(xcvr_ctrl_clk), + .gtwiz_reset_all_in(xcvr_ctrl_rst), + .gtpowergood_out(xcvr_gtpowergood_out), + + // PLL + .gtwiz_reset_qpll0lock_in(xcvr_qpll0lock_in), + .gtwiz_reset_qpll0reset_out(xcvr_qpll0reset_out), + .qpll0clk_in(xcvr_qpll0clk_in), + .qpll0refclk_in(xcvr_qpll0refclk_in), + .qpll1clk_in(1'b0), + .qpll1refclk_in(1'b0), + + // Serial data + .gtytxp_out(xcvr_txp), + .gtytxn_out(xcvr_txn), + .gtyrxp_in(xcvr_rxp), + .gtyrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_reset_in(1'b0), + .gtwiz_userclk_tx_srcclk_out(), + .gtwiz_userclk_tx_usrclk_out(), + .gtwiz_userclk_tx_usrclk2_out(tx_clk), + .gtwiz_userclk_tx_active_out(), + .gtwiz_reset_tx_pll_and_datapath_in(1'b0), + .gtwiz_reset_tx_datapath_in(gt_reset_tx_datapath), + .gtwiz_reset_tx_done_out(gt_reset_tx_done), + .txpmaresetdone_out(), + .txprgdivresetdone_out(), + + .gtwiz_userdata_tx_in(gt_txdata), + .txheader_in(gt_txheader), + .txsequence_in(7'b0), + + // Receive + .gtwiz_userclk_rx_reset_in(1'b0), + .gtwiz_userclk_rx_srcclk_out(), + .gtwiz_userclk_rx_usrclk_out(), + .gtwiz_userclk_rx_usrclk2_out(rx_clk), + .gtwiz_userclk_rx_active_out(), + .gtwiz_reset_rx_pll_and_datapath_in(1'b0), + .gtwiz_reset_rx_datapath_in(gt_reset_rx_datapath), + .gtwiz_reset_rx_cdr_stable_out(), + .gtwiz_reset_rx_done_out(gt_reset_rx_done), + .rxpmaresetdone_out(), + .rxprgdivresetdone_out(), + + .rxgearboxslip_in(gt_rxgearboxslip), + .gtwiz_userdata_rx_out(gt_rxdata), + .rxdatavalid_out(gt_rxdatavalid), + .rxheader_out(gt_rxheader), + .rxheadervalid_out(gt_rxheadervalid), + .rxstartofseq_out() + ); + + 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+ GTY (channel only) + + taxi_eth_mac_25g_us_gth_channel + taxi_eth_mac_25g_us_gth_channel_inst ( + // Common + .gtwiz_reset_clk_freerun_in(xcvr_ctrl_clk), + .gtwiz_reset_all_in(xcvr_ctrl_rst), + .gtpowergood_out(xcvr_gtpowergood_out), + + // PLL + .gtwiz_reset_qpll0lock_in(xcvr_qpll0lock_in), + .gtwiz_reset_qpll0reset_out(xcvr_qpll0reset_out), + .qpll0clk_in(xcvr_qpll0clk_in), + .qpll0refclk_in(xcvr_qpll0refclk_in), + .qpll1clk_in(1'b0), + .qpll1refclk_in(1'b0), + + // Serial data + .gthtxp_out(xcvr_txp), + .gthtxn_out(xcvr_txn), + .gthrxp_in(xcvr_rxp), + .gthrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_reset_in(1'b0), + .gtwiz_userclk_tx_srcclk_out(), + .gtwiz_userclk_tx_usrclk_out(), + .gtwiz_userclk_tx_usrclk2_out(tx_clk), + .gtwiz_userclk_tx_active_out(), + .gtwiz_reset_tx_pll_and_datapath_in(1'b0), + .gtwiz_reset_tx_datapath_in(gt_reset_tx_datapath), + .gtwiz_reset_tx_done_out(gt_reset_tx_done), + .txpmaresetdone_out(), + .txprgdivresetdone_out(), + + .gtwiz_userdata_tx_in(gt_txdata), + .txheader_in(gt_txheader), + .txsequence_in(7'b0), + + // Receive + .gtwiz_userclk_rx_reset_in(1'b0), + .gtwiz_userclk_rx_srcclk_out(), + .gtwiz_userclk_rx_usrclk_out(), + .gtwiz_userclk_rx_usrclk2_out(rx_clk), + .gtwiz_userclk_rx_active_out(), + .gtwiz_reset_rx_pll_and_datapath_in(1'b0), + .gtwiz_reset_rx_datapath_in(gt_reset_rx_datapath), + .gtwiz_reset_rx_cdr_stable_out(), + .gtwiz_reset_rx_done_out(gt_reset_rx_done), + .rxpmaresetdone_out(), + .rxprgdivresetdone_out(), + + .rxgearboxslip_in(gt_rxgearboxslip), + .gtwiz_userdata_rx_out(gt_rxdata), + .rxdatavalid_out(gt_rxdatavalid), + .rxheader_out(gt_rxheader), + .rxheadervalid_out(gt_rxheadervalid), + .rxstartofseq_out() + ); + + 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 + +taxi_sync_reset #( + .N(4) +) +tx_reset_sync_inst ( + .clk(tx_clk), + .rst(!gt_reset_tx_done || tx_rst_in), + .out(tx_rst_out) +); + +taxi_sync_reset #( + .N(4) +) +rx_reset_sync_inst ( + .clk(rx_clk), + .rst(!gt_reset_rx_done || rx_rst_in), + .out(rx_rst_out) +); + +wire [DATA_W-1:0] serdes_tx_data; +wire [HDR_W-1:0] serdes_tx_hdr; +wire [DATA_W-1:0] serdes_rx_data; +wire [HDR_W-1:0] serdes_rx_hdr; +wire serdes_rx_bitslip; + +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_hdr = gt_rxheader[1:0]; +end + +taxi_eth_mac_phy_10g #( + .DATA_W(DATA_W), + .HDR_W(HDR_W), + .PADDING_EN(PADDING_EN), + .DIC_EN(DIC_EN), + .MIN_FRAME_LEN(MIN_FRAME_LEN), + .PTP_TS_EN(PTP_TS_EN), + .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD), + .PTP_TS_W(PTP_TS_W), + .BIT_REVERSE(1'b1), + .SCRAMBLER_DISABLE(1'b0), + .PRBS31_EN(PRBS31_EN), + .TX_SERDES_PIPELINE(TX_SERDES_PIPELINE), + .RX_SERDES_PIPELINE(RX_SERDES_PIPELINE), + .BITSLIP_HIGH_CYCLES(BITSLIP_HIGH_CYCLES), + .BITSLIP_LOW_CYCLES(BITSLIP_LOW_CYCLES), + .COUNT_125US(COUNT_125US) +) +eth_mac_phy_10g_inst ( + .tx_clk(tx_clk), + .tx_rst(tx_rst_out), + .rx_clk(rx_clk), + .rx_rst(rx_rst_out), + + /* + * Transmit interface (AXI stream) + */ + .s_axis_tx(s_axis_tx), + .m_axis_tx_cpl(m_axis_tx_cpl), + + /* + * Receive interface (AXI stream) + */ + .m_axis_rx(m_axis_rx), + + /* + * Serdes interface + */ + .serdes_tx_data(serdes_tx_data), + .serdes_tx_hdr(serdes_tx_hdr), + .serdes_rx_data(serdes_rx_data), + .serdes_rx_hdr(serdes_rx_hdr), + .serdes_rx_bitslip(serdes_rx_bitslip), + .serdes_rx_reset_req(rx_reset_req), + + /* + * PTP + */ + .tx_ptp_ts(tx_ptp_ts), + .rx_ptp_ts(rx_ptp_ts), + + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + .tx_lfc_req(tx_lfc_req), + .tx_lfc_resend(tx_lfc_resend), + .rx_lfc_en(rx_lfc_en), + .rx_lfc_req(rx_lfc_req), + .rx_lfc_ack(rx_lfc_ack), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + .tx_pfc_req(tx_pfc_req), + .tx_pfc_resend(tx_pfc_resend), + .rx_pfc_en(rx_pfc_en), + .rx_pfc_req(rx_pfc_req), + .rx_pfc_ack(rx_pfc_ack), + + /* + * Pause interface + */ + .tx_lfc_pause_en(tx_lfc_pause_en), + .tx_pause_req(tx_pause_req), + .tx_pause_ack(tx_pause_ack), + + /* + * Status + */ + .tx_start_packet(tx_start_packet), + .tx_error_underflow(tx_error_underflow), + .rx_start_packet(rx_start_packet), + .rx_error_count(rx_error_count), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .rx_bad_block(rx_bad_block), + .rx_sequence_error(rx_sequence_error), + .rx_block_lock(rx_block_lock), + .rx_high_ber(rx_high_ber), + .rx_status(rx_status), + .stat_tx_mcf(stat_tx_mcf), + .stat_rx_mcf(stat_rx_mcf), + .stat_tx_lfc_pkt(stat_tx_lfc_pkt), + .stat_tx_lfc_xon(stat_tx_lfc_xon), + .stat_tx_lfc_xoff(stat_tx_lfc_xoff), + .stat_tx_lfc_paused(stat_tx_lfc_paused), + .stat_tx_pfc_pkt(stat_tx_pfc_pkt), + .stat_tx_pfc_xon(stat_tx_pfc_xon), + .stat_tx_pfc_xoff(stat_tx_pfc_xoff), + .stat_tx_pfc_paused(stat_tx_pfc_paused), + .stat_rx_lfc_pkt(stat_rx_lfc_pkt), + .stat_rx_lfc_xon(stat_rx_lfc_xon), + .stat_rx_lfc_xoff(stat_rx_lfc_xoff), + .stat_rx_lfc_paused(stat_rx_lfc_paused), + .stat_rx_pfc_pkt(stat_rx_pfc_pkt), + .stat_rx_pfc_xon(stat_rx_pfc_xon), + .stat_rx_pfc_xoff(stat_rx_pfc_xoff), + .stat_rx_pfc_paused(stat_rx_pfc_paused), + + /* + * Configuration + */ + .cfg_ifg(cfg_ifg), + .cfg_tx_enable(cfg_tx_enable), + .cfg_rx_enable(cfg_rx_enable), + .cfg_tx_prbs31_enable(cfg_tx_prbs31_enable), + .cfg_rx_prbs31_enable(cfg_rx_prbs31_enable), + .cfg_mcf_rx_eth_dst_mcast(cfg_mcf_rx_eth_dst_mcast), + .cfg_mcf_rx_check_eth_dst_mcast(cfg_mcf_rx_check_eth_dst_mcast), + .cfg_mcf_rx_eth_dst_ucast(cfg_mcf_rx_eth_dst_ucast), + .cfg_mcf_rx_check_eth_dst_ucast(cfg_mcf_rx_check_eth_dst_ucast), + .cfg_mcf_rx_eth_src(cfg_mcf_rx_eth_src), + .cfg_mcf_rx_check_eth_src(cfg_mcf_rx_check_eth_src), + .cfg_mcf_rx_eth_type(cfg_mcf_rx_eth_type), + .cfg_mcf_rx_opcode_lfc(cfg_mcf_rx_opcode_lfc), + .cfg_mcf_rx_check_opcode_lfc(cfg_mcf_rx_check_opcode_lfc), + .cfg_mcf_rx_opcode_pfc(cfg_mcf_rx_opcode_pfc), + .cfg_mcf_rx_check_opcode_pfc(cfg_mcf_rx_check_opcode_pfc), + .cfg_mcf_rx_forward(cfg_mcf_rx_forward), + .cfg_mcf_rx_enable(cfg_mcf_rx_enable), + .cfg_tx_lfc_eth_dst(cfg_tx_lfc_eth_dst), + .cfg_tx_lfc_eth_src(cfg_tx_lfc_eth_src), + .cfg_tx_lfc_eth_type(cfg_tx_lfc_eth_type), + .cfg_tx_lfc_opcode(cfg_tx_lfc_opcode), + .cfg_tx_lfc_en(cfg_tx_lfc_en), + .cfg_tx_lfc_quanta(cfg_tx_lfc_quanta), + .cfg_tx_lfc_refresh(cfg_tx_lfc_refresh), + .cfg_tx_pfc_eth_dst(cfg_tx_pfc_eth_dst), + .cfg_tx_pfc_eth_src(cfg_tx_pfc_eth_src), + .cfg_tx_pfc_eth_type(cfg_tx_pfc_eth_type), + .cfg_tx_pfc_opcode(cfg_tx_pfc_opcode), + .cfg_tx_pfc_en(cfg_tx_pfc_en), + .cfg_tx_pfc_quanta(cfg_tx_pfc_quanta), + .cfg_tx_pfc_refresh(cfg_tx_pfc_refresh), + .cfg_rx_lfc_opcode(cfg_rx_lfc_opcode), + .cfg_rx_lfc_en(cfg_rx_lfc_en), + .cfg_rx_pfc_opcode(cfg_rx_pfc_opcode), + .cfg_rx_pfc_en(cfg_rx_pfc_en) +); + +endmodule + +`resetall diff --git a/rtl/eth/us/taxi_eth_mac_25g_us_gth_10g_156.tcl b/rtl/eth/us/taxi_eth_mac_25g_us_gth_10g_156.tcl new file mode 100644 index 0000000..1288ae7 --- /dev/null +++ b/rtl/eth/us/taxi_eth_mac_25g_us_gth_10g_156.tcl @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: CERN-OHL-S-2.0 +# +# Copyright (c) 2025 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +set base_name {taxi_eth_mac_25g_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 {64} +set int_data_width {32} +set rx_eq_mode {DFE} +set extra_ports [list] +set extra_pll_ports [list {qpll0lock_out}] + +set config [dict create] + +dict set config TX_LINE_RATE $line_rate +dict set config TX_REFCLK_FREQUENCY $refclk_freq +dict set config TX_QPLL_FRACN_NUMERATOR $qpll_fracn +dict set config TX_USER_DATA_WIDTH $user_data_width +dict set config TX_INT_DATA_WIDTH $int_data_width +dict set config RX_LINE_RATE $line_rate +dict set config RX_REFCLK_FREQUENCY $refclk_freq +dict set config RX_QPLL_FRACN_NUMERATOR $qpll_fracn +dict set config RX_USER_DATA_WIDTH $user_data_width +dict set config RX_INT_DATA_WIDTH $int_data_width +dict set config 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 {CORE} +dict set config LOCATE_TX_USER_CLOCKING {CORE} +dict set config LOCATE_RX_USER_CLOCKING {CORE} +dict set config LOCATE_USER_DATA_WIDTH_SIZING {CORE} +dict set config FREERUN_FREQUENCY $freerun_freq +dict set config DISABLE_LOC_XDC {1} + +proc create_gtwizard_ip {name preset config} { + create_ip -name gtwizard_ultrascale -vendor xilinx.com -library ip -module_name $name + set ip [get_ips $name] + set_property CONFIG.preset $preset $ip + set config_list {} + dict for {name value} $config { + lappend config_list "CONFIG.${name}" $value + } + set_property -dict $config_list $ip +} + +# variant with channel and common +dict set config ENABLE_OPTIONAL_PORTS [concat $extra_pll_ports $extra_ports] +dict set config LOCATE_COMMON {CORE} + +create_gtwizard_ip "${base_name}_full" $preset $config + +# variant with channel only +dict set config ENABLE_OPTIONAL_PORTS $extra_ports +dict set config LOCATE_COMMON {EXAMPLE_DESIGN} + +create_gtwizard_ip "${base_name}_channel" $preset $config diff --git a/rtl/eth/us/taxi_eth_mac_25g_us_gth_10g_161.tcl b/rtl/eth/us/taxi_eth_mac_25g_us_gth_10g_161.tcl new file mode 100644 index 0000000..411821d --- /dev/null +++ b/rtl/eth/us/taxi_eth_mac_25g_us_gth_10g_161.tcl @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: CERN-OHL-S-2.0 +# +# Copyright (c) 2025 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +set base_name {taxi_eth_mac_25g_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 {64} +set int_data_width {32} +set rx_eq_mode {DFE} +set extra_ports [list] +set extra_pll_ports [list {qpll0lock_out}] + +set config [dict create] + +dict set config TX_LINE_RATE $line_rate +dict set config TX_REFCLK_FREQUENCY $refclk_freq +dict set config TX_QPLL_FRACN_NUMERATOR $qpll_fracn +dict set config TX_USER_DATA_WIDTH $user_data_width +dict set config TX_INT_DATA_WIDTH $int_data_width +dict set config RX_LINE_RATE $line_rate +dict set config RX_REFCLK_FREQUENCY $refclk_freq +dict set config RX_QPLL_FRACN_NUMERATOR $qpll_fracn +dict set config RX_USER_DATA_WIDTH $user_data_width +dict set config RX_INT_DATA_WIDTH $int_data_width +dict set config 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 {CORE} +dict set config LOCATE_TX_USER_CLOCKING {CORE} +dict set config LOCATE_RX_USER_CLOCKING {CORE} +dict set config LOCATE_USER_DATA_WIDTH_SIZING {CORE} +dict set config FREERUN_FREQUENCY $freerun_freq +dict set config DISABLE_LOC_XDC {1} + +proc create_gtwizard_ip {name preset config} { + create_ip -name gtwizard_ultrascale -vendor xilinx.com -library ip -module_name $name + set ip [get_ips $name] + set_property CONFIG.preset $preset $ip + set config_list {} + dict for {name value} $config { + lappend config_list "CONFIG.${name}" $value + } + set_property -dict $config_list $ip +} + +# variant with channel and common +dict set config ENABLE_OPTIONAL_PORTS [concat $extra_pll_ports $extra_ports] +dict set config LOCATE_COMMON {CORE} + +create_gtwizard_ip "${base_name}_full" $preset $config + +# variant with channel only +dict set config ENABLE_OPTIONAL_PORTS $extra_ports +dict set config LOCATE_COMMON {EXAMPLE_DESIGN} + +create_gtwizard_ip "${base_name}_channel" $preset $config diff --git a/rtl/eth/us/taxi_eth_mac_25g_us_gth_10g_322.tcl b/rtl/eth/us/taxi_eth_mac_25g_us_gth_10g_322.tcl new file mode 100644 index 0000000..7c93978 --- /dev/null +++ b/rtl/eth/us/taxi_eth_mac_25g_us_gth_10g_322.tcl @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: CERN-OHL-S-2.0 +# +# Copyright (c) 2025 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +set base_name {taxi_eth_mac_25g_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 {64} +set int_data_width {32} +set rx_eq_mode {DFE} +set extra_ports [list] +set extra_pll_ports [list {qpll0lock_out}] + +set config [dict create] + +dict set config TX_LINE_RATE $line_rate +dict set config TX_REFCLK_FREQUENCY $refclk_freq +dict set config TX_QPLL_FRACN_NUMERATOR $qpll_fracn +dict set config TX_USER_DATA_WIDTH $user_data_width +dict set config TX_INT_DATA_WIDTH $int_data_width +dict set config RX_LINE_RATE $line_rate +dict set config RX_REFCLK_FREQUENCY $refclk_freq +dict set config RX_QPLL_FRACN_NUMERATOR $qpll_fracn +dict set config RX_USER_DATA_WIDTH $user_data_width +dict set config RX_INT_DATA_WIDTH $int_data_width +dict set config 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 {CORE} +dict set config LOCATE_TX_USER_CLOCKING {CORE} +dict set config LOCATE_RX_USER_CLOCKING {CORE} +dict set config LOCATE_USER_DATA_WIDTH_SIZING {CORE} +dict set config FREERUN_FREQUENCY $freerun_freq +dict set config DISABLE_LOC_XDC {1} + +proc create_gtwizard_ip {name preset config} { + create_ip -name gtwizard_ultrascale -vendor xilinx.com -library ip -module_name $name + set ip [get_ips $name] + set_property CONFIG.preset $preset $ip + set config_list {} + dict for {name value} $config { + lappend config_list "CONFIG.${name}" $value + } + set_property -dict $config_list $ip +} + +# variant with channel and common +dict set config ENABLE_OPTIONAL_PORTS [concat $extra_pll_ports $extra_ports] +dict set config LOCATE_COMMON {CORE} + +create_gtwizard_ip "${base_name}_full" $preset $config + +# variant with channel only +dict set config ENABLE_OPTIONAL_PORTS $extra_ports +dict set config LOCATE_COMMON {EXAMPLE_DESIGN} + +create_gtwizard_ip "${base_name}_channel" $preset $config diff --git a/rtl/eth/us/taxi_eth_mac_25g_us_gty_10g_156.tcl b/rtl/eth/us/taxi_eth_mac_25g_us_gty_10g_156.tcl new file mode 100644 index 0000000..9dba3d2 --- /dev/null +++ b/rtl/eth/us/taxi_eth_mac_25g_us_gty_10g_156.tcl @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: CERN-OHL-S-2.0 +# +# Copyright (c) 2025 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +set base_name {taxi_eth_mac_25g_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 {64} +set int_data_width $user_data_width +set rx_eq_mode {DFE} +set extra_ports [list] +set extra_pll_ports [list {qpll0lock_out}] + +set config [dict create] + +dict set config TX_LINE_RATE $line_rate +dict set config TX_REFCLK_FREQUENCY $refclk_freq +dict set config TX_QPLL_FRACN_NUMERATOR $qpll_fracn +dict set config TX_USER_DATA_WIDTH $user_data_width +dict set config TX_INT_DATA_WIDTH $int_data_width +dict set config RX_LINE_RATE $line_rate +dict set config RX_REFCLK_FREQUENCY $refclk_freq +dict set config RX_QPLL_FRACN_NUMERATOR $qpll_fracn +dict set config RX_USER_DATA_WIDTH $user_data_width +dict set config RX_INT_DATA_WIDTH $int_data_width +dict set config 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 {CORE} +dict set config LOCATE_TX_USER_CLOCKING {CORE} +dict set config LOCATE_RX_USER_CLOCKING {CORE} +dict set config LOCATE_USER_DATA_WIDTH_SIZING {CORE} +dict set config FREERUN_FREQUENCY $freerun_freq +dict set config DISABLE_LOC_XDC {1} + +proc create_gtwizard_ip {name preset config} { + create_ip -name gtwizard_ultrascale -vendor xilinx.com -library ip -module_name $name + set ip [get_ips $name] + set_property CONFIG.preset $preset $ip + set config_list {} + dict for {name value} $config { + lappend config_list "CONFIG.${name}" $value + } + set_property -dict $config_list $ip +} + +# variant with channel and common +dict set config ENABLE_OPTIONAL_PORTS [concat $extra_pll_ports $extra_ports] +dict set config LOCATE_COMMON {CORE} + +create_gtwizard_ip "${base_name}_full" $preset $config + +# variant with channel only +dict set config ENABLE_OPTIONAL_PORTS $extra_ports +dict set config LOCATE_COMMON {EXAMPLE_DESIGN} + +create_gtwizard_ip "${base_name}_channel" $preset $config diff --git a/rtl/eth/us/taxi_eth_mac_25g_us_gty_10g_161.tcl b/rtl/eth/us/taxi_eth_mac_25g_us_gty_10g_161.tcl new file mode 100644 index 0000000..5a54af3 --- /dev/null +++ b/rtl/eth/us/taxi_eth_mac_25g_us_gty_10g_161.tcl @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: CERN-OHL-S-2.0 +# +# Copyright (c) 2025 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +set base_name {taxi_eth_mac_25g_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 {64} +set int_data_width $user_data_width +set rx_eq_mode {DFE} +set extra_ports [list] +set extra_pll_ports [list {qpll0lock_out}] + +set config [dict create] + +dict set config TX_LINE_RATE $line_rate +dict set config TX_REFCLK_FREQUENCY $refclk_freq +dict set config TX_QPLL_FRACN_NUMERATOR $qpll_fracn +dict set config TX_USER_DATA_WIDTH $user_data_width +dict set config TX_INT_DATA_WIDTH $int_data_width +dict set config RX_LINE_RATE $line_rate +dict set config RX_REFCLK_FREQUENCY $refclk_freq +dict set config RX_QPLL_FRACN_NUMERATOR $qpll_fracn +dict set config RX_USER_DATA_WIDTH $user_data_width +dict set config RX_INT_DATA_WIDTH $int_data_width +dict set config 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 {CORE} +dict set config LOCATE_TX_USER_CLOCKING {CORE} +dict set config LOCATE_RX_USER_CLOCKING {CORE} +dict set config LOCATE_USER_DATA_WIDTH_SIZING {CORE} +dict set config FREERUN_FREQUENCY $freerun_freq +dict set config DISABLE_LOC_XDC {1} + +proc create_gtwizard_ip {name preset config} { + create_ip -name gtwizard_ultrascale -vendor xilinx.com -library ip -module_name $name + set ip [get_ips $name] + set_property CONFIG.preset $preset $ip + set config_list {} + dict for {name value} $config { + lappend config_list "CONFIG.${name}" $value + } + set_property -dict $config_list $ip +} + +# variant with channel and common +dict set config ENABLE_OPTIONAL_PORTS [concat $extra_pll_ports $extra_ports] +dict set config LOCATE_COMMON {CORE} + +create_gtwizard_ip "${base_name}_full" $preset $config + +# variant with channel only +dict set config ENABLE_OPTIONAL_PORTS $extra_ports +dict set config LOCATE_COMMON {EXAMPLE_DESIGN} + +create_gtwizard_ip "${base_name}_channel" $preset $config diff --git a/rtl/eth/us/taxi_eth_mac_25g_us_gty_10g_322.tcl b/rtl/eth/us/taxi_eth_mac_25g_us_gty_10g_322.tcl new file mode 100644 index 0000000..e21e6c8 --- /dev/null +++ b/rtl/eth/us/taxi_eth_mac_25g_us_gty_10g_322.tcl @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: CERN-OHL-S-2.0 +# +# Copyright (c) 2025 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +set base_name {taxi_eth_mac_25g_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 {64} +set int_data_width $user_data_width +set rx_eq_mode {DFE} +set extra_ports [list] +set extra_pll_ports [list {qpll0lock_out}] + +set config [dict create] + +dict set config TX_LINE_RATE $line_rate +dict set config TX_REFCLK_FREQUENCY $refclk_freq +dict set config TX_QPLL_FRACN_NUMERATOR $qpll_fracn +dict set config TX_USER_DATA_WIDTH $user_data_width +dict set config TX_INT_DATA_WIDTH $int_data_width +dict set config RX_LINE_RATE $line_rate +dict set config RX_REFCLK_FREQUENCY $refclk_freq +dict set config RX_QPLL_FRACN_NUMERATOR $qpll_fracn +dict set config RX_USER_DATA_WIDTH $user_data_width +dict set config RX_INT_DATA_WIDTH $int_data_width +dict set config 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 {CORE} +dict set config LOCATE_TX_USER_CLOCKING {CORE} +dict set config LOCATE_RX_USER_CLOCKING {CORE} +dict set config LOCATE_USER_DATA_WIDTH_SIZING {CORE} +dict set config FREERUN_FREQUENCY $freerun_freq +dict set config DISABLE_LOC_XDC {1} + +proc create_gtwizard_ip {name preset config} { + create_ip -name gtwizard_ultrascale -vendor xilinx.com -library ip -module_name $name + set ip [get_ips $name] + set_property CONFIG.preset $preset $ip + set config_list {} + dict for {name value} $config { + lappend config_list "CONFIG.${name}" $value + } + set_property -dict $config_list $ip +} + +# variant with channel and common +dict set config ENABLE_OPTIONAL_PORTS [concat $extra_pll_ports $extra_ports] +dict set config LOCATE_COMMON {CORE} + +create_gtwizard_ip "${base_name}_full" $preset $config + +# variant with channel only +dict set config ENABLE_OPTIONAL_PORTS $extra_ports +dict set config LOCATE_COMMON {EXAMPLE_DESIGN} + +create_gtwizard_ip "${base_name}_channel" $preset $config diff --git a/rtl/eth/us/taxi_eth_mac_25g_us_gty_25g_156.tcl b/rtl/eth/us/taxi_eth_mac_25g_us_gty_25g_156.tcl new file mode 100644 index 0000000..d584234 --- /dev/null +++ b/rtl/eth/us/taxi_eth_mac_25g_us_gty_25g_156.tcl @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: CERN-OHL-S-2.0 +# +# Copyright (c) 2025 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +set base_name {taxi_eth_mac_25g_us_gty} + +set preset {GTY-10GBASE-R} + +set freerun_freq {125} +set line_rate {25.78125} +set refclk_freq {156.25} +set sec_line_rate {10.3125} +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 {64} +set int_data_width $user_data_width +set rx_eq_mode {DFE} +set extra_ports [list] +set extra_pll_ports [list {qpll0lock_out}] + +set config [dict create] + +dict set config TX_LINE_RATE $line_rate +dict set config TX_REFCLK_FREQUENCY $refclk_freq +dict set config TX_QPLL_FRACN_NUMERATOR $qpll_fracn +dict set config TX_USER_DATA_WIDTH $user_data_width +dict set config TX_INT_DATA_WIDTH $int_data_width +dict set config RX_LINE_RATE $line_rate +dict set config RX_REFCLK_FREQUENCY $refclk_freq +dict set config RX_QPLL_FRACN_NUMERATOR $qpll_fracn +dict set config RX_USER_DATA_WIDTH $user_data_width +dict set config RX_INT_DATA_WIDTH $int_data_width +dict set config 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 {CORE} +dict set config LOCATE_TX_USER_CLOCKING {CORE} +dict set config LOCATE_RX_USER_CLOCKING {CORE} +dict set config LOCATE_USER_DATA_WIDTH_SIZING {CORE} +dict set config FREERUN_FREQUENCY $freerun_freq +dict set config DISABLE_LOC_XDC {1} + +proc create_gtwizard_ip {name preset config} { + create_ip -name gtwizard_ultrascale -vendor xilinx.com -library ip -module_name $name + set ip [get_ips $name] + set_property CONFIG.preset $preset $ip + set config_list {} + dict for {name value} $config { + lappend config_list "CONFIG.${name}" $value + } + set_property -dict $config_list $ip +} + +# variant with channel and common +dict set config ENABLE_OPTIONAL_PORTS [concat $extra_pll_ports $extra_ports] +dict set config LOCATE_COMMON {CORE} + +create_gtwizard_ip "${base_name}_full" $preset $config + +# variant with channel only +dict set config ENABLE_OPTIONAL_PORTS $extra_ports +dict set config LOCATE_COMMON {EXAMPLE_DESIGN} + +create_gtwizard_ip "${base_name}_channel" $preset $config diff --git a/rtl/eth/us/taxi_eth_mac_25g_us_gty_25g_161.tcl b/rtl/eth/us/taxi_eth_mac_25g_us_gty_25g_161.tcl new file mode 100644 index 0000000..faebcbd --- /dev/null +++ b/rtl/eth/us/taxi_eth_mac_25g_us_gty_25g_161.tcl @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: CERN-OHL-S-2.0 +# +# Copyright (c) 2025 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +set base_name {taxi_eth_mac_25g_us_gty} + +set preset {GTY-10GBASE-R} + +set freerun_freq {125} +set line_rate {25.78125} +set refclk_freq {161.1328125} +set sec_line_rate {10.3125} +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 {64} +set int_data_width $user_data_width +set rx_eq_mode {DFE} +set extra_ports [list] +set extra_pll_ports [list {qpll0lock_out}] + +set config [dict create] + +dict set config TX_LINE_RATE $line_rate +dict set config TX_REFCLK_FREQUENCY $refclk_freq +dict set config TX_QPLL_FRACN_NUMERATOR $qpll_fracn +dict set config TX_USER_DATA_WIDTH $user_data_width +dict set config TX_INT_DATA_WIDTH $int_data_width +dict set config RX_LINE_RATE $line_rate +dict set config RX_REFCLK_FREQUENCY $refclk_freq +dict set config RX_QPLL_FRACN_NUMERATOR $qpll_fracn +dict set config RX_USER_DATA_WIDTH $user_data_width +dict set config RX_INT_DATA_WIDTH $int_data_width +dict set config 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 {CORE} +dict set config LOCATE_TX_USER_CLOCKING {CORE} +dict set config LOCATE_RX_USER_CLOCKING {CORE} +dict set config LOCATE_USER_DATA_WIDTH_SIZING {CORE} +dict set config FREERUN_FREQUENCY $freerun_freq +dict set config DISABLE_LOC_XDC {1} + +proc create_gtwizard_ip {name preset config} { + create_ip -name gtwizard_ultrascale -vendor xilinx.com -library ip -module_name $name + set ip [get_ips $name] + set_property CONFIG.preset $preset $ip + set config_list {} + dict for {name value} $config { + lappend config_list "CONFIG.${name}" $value + } + set_property -dict $config_list $ip +} + +# variant with channel and common +dict set config ENABLE_OPTIONAL_PORTS [concat $extra_pll_ports $extra_ports] +dict set config LOCATE_COMMON {CORE} + +create_gtwizard_ip "${base_name}_full" $preset $config + +# variant with channel only +dict set config ENABLE_OPTIONAL_PORTS $extra_ports +dict set config LOCATE_COMMON {EXAMPLE_DESIGN} + +create_gtwizard_ip "${base_name}_channel" $preset $config diff --git a/rtl/eth/us/taxi_eth_mac_25g_us_gty_25g_322.tcl b/rtl/eth/us/taxi_eth_mac_25g_us_gty_25g_322.tcl new file mode 100644 index 0000000..8b6ff3c --- /dev/null +++ b/rtl/eth/us/taxi_eth_mac_25g_us_gty_25g_322.tcl @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: CERN-OHL-S-2.0 +# +# Copyright (c) 2025 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +set base_name {taxi_eth_mac_25g_us_gty} + +set preset {GTY-10GBASE-R} + +set freerun_freq {125} +set line_rate {25.78125} +set refclk_freq {322.265625} +set sec_line_rate {10.3125} +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 {64} +set int_data_width $user_data_width +set rx_eq_mode {DFE} +set extra_ports [list] +set extra_pll_ports [list {qpll0lock_out}] + +set config [dict create] + +dict set config TX_LINE_RATE $line_rate +dict set config TX_REFCLK_FREQUENCY $refclk_freq +dict set config TX_QPLL_FRACN_NUMERATOR $qpll_fracn +dict set config TX_USER_DATA_WIDTH $user_data_width +dict set config TX_INT_DATA_WIDTH $int_data_width +dict set config RX_LINE_RATE $line_rate +dict set config RX_REFCLK_FREQUENCY $refclk_freq +dict set config RX_QPLL_FRACN_NUMERATOR $qpll_fracn +dict set config RX_USER_DATA_WIDTH $user_data_width +dict set config RX_INT_DATA_WIDTH $int_data_width +dict set config 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 {CORE} +dict set config LOCATE_TX_USER_CLOCKING {CORE} +dict set config LOCATE_RX_USER_CLOCKING {CORE} +dict set config LOCATE_USER_DATA_WIDTH_SIZING {CORE} +dict set config FREERUN_FREQUENCY $freerun_freq +dict set config DISABLE_LOC_XDC {1} + +proc create_gtwizard_ip {name preset config} { + create_ip -name gtwizard_ultrascale -vendor xilinx.com -library ip -module_name $name + set ip [get_ips $name] + set_property CONFIG.preset $preset $ip + set config_list {} + dict for {name value} $config { + lappend config_list "CONFIG.${name}" $value + } + set_property -dict $config_list $ip +} + +# variant with channel and common +dict set config ENABLE_OPTIONAL_PORTS [concat $extra_pll_ports $extra_ports] +dict set config LOCATE_COMMON {CORE} + +create_gtwizard_ip "${base_name}_full" $preset $config + +# variant with channel only +dict set config ENABLE_OPTIONAL_PORTS $extra_ports +dict set config LOCATE_COMMON {EXAMPLE_DESIGN} + +create_gtwizard_ip "${base_name}_channel" $preset $config