From bf7cf3fef945b2d98a6fdb0c694a91a9f7c2c4cd Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Wed, 9 Nov 2022 20:58:30 -0800 Subject: [PATCH] Add CMAC wrapper Signed-off-by: Alex Forencich --- fpga/common/rtl/cmac_gty_ch_wrapper.v | 1201 ++++++++++++ fpga/common/rtl/cmac_gty_wrapper.v | 1695 +++++++++++++++++ .../common/syn/vivado/cmac_gty_ch_wrapper.tcl | 79 + fpga/common/syn/vivado/cmac_gty_wrapper.tcl | 117 ++ 4 files changed, 3092 insertions(+) create mode 100644 fpga/common/rtl/cmac_gty_ch_wrapper.v create mode 100644 fpga/common/rtl/cmac_gty_wrapper.v create mode 100644 fpga/common/syn/vivado/cmac_gty_ch_wrapper.tcl create mode 100644 fpga/common/syn/vivado/cmac_gty_wrapper.tcl diff --git a/fpga/common/rtl/cmac_gty_ch_wrapper.v b/fpga/common/rtl/cmac_gty_ch_wrapper.v new file mode 100644 index 000000000..85691dea3 --- /dev/null +++ b/fpga/common/rtl/cmac_gty_ch_wrapper.v @@ -0,0 +1,1201 @@ +/* + +Copyright 2022, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS +IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +*/ + +// Language: Verilog 2001 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * GTY transceiver channel wrapper for CMAC + */ +module cmac_gty_ch_wrapper # +( + parameter INDEX = 0, + parameter HAS_COMMON = (INDEX == 0), + + // PLL parameters + parameter QPLL0_PD = 1'b0, + parameter QPLL1_PD = 1'b1, + + // GT parameters + parameter GT_TX_PD = 1'b0, + parameter GT_TX_QPLL_SEL = 1'b0, + parameter GT_TX_POLARITY = 1'b0, + parameter GT_TX_ELECIDLE = 1'b0, + parameter GT_TX_INHIBIT = 1'b0, + parameter GT_TX_DIFFCTRL = 5'd24, + parameter GT_TX_MAINCURSOR = 7'd64, + parameter GT_TX_POSTCURSOR = 5'd0, + parameter GT_TX_PRECURSOR = 5'd0, + parameter GT_RX_PD = 1'b0, + parameter GT_RX_QPLL_SEL = 1'b0, + parameter GT_RX_LPM_EN = 1'b1, + parameter GT_RX_POLARITY = 1'b0 +) +( + input wire xcvr_ctrl_clk, + input wire xcvr_ctrl_rst, + + /* + * Common + */ + output wire xcvr_gtpowergood_out, + + /* + * DRP + */ + input wire drp_clk, + input wire drp_rst, + input wire [23:0] drp_addr, + input wire [15:0] drp_di, + input wire drp_en, + input wire drp_we, + output wire [15:0] drp_do, + output wire drp_rdy, + + /* + * PLL out + */ + input wire xcvr_gtrefclk00_in, + output wire xcvr_qpll0lock_out, + output wire xcvr_qpll0clk_out, + output wire xcvr_qpll0refclk_out, + input wire xcvr_gtrefclk01_in, + output wire xcvr_qpll1lock_out, + output wire xcvr_qpll1clk_out, + output wire xcvr_qpll1refclk_out, + + /* + * PLL in + */ + input wire xcvr_qpll0lock_in, + input wire xcvr_qpll0clk_in, + input wire xcvr_qpll0refclk_in, + input wire xcvr_qpll1lock_in, + input wire xcvr_qpll1clk_in, + input wire xcvr_qpll1refclk_in, + + /* + * Serial data + */ + output wire xcvr_txp, + output wire xcvr_txn, + input wire xcvr_rxp, + input wire xcvr_rxn, + + /* + * Parallel data + */ + output wire gt_txoutclk, + input wire gt_txusrclk, + input wire gt_txusrclk2, + input wire tx_reset_in, + output wire tx_reset_done, + output wire gt_tx_reset_out, + output wire gt_tx_reset_done, + input wire [127:0] gt_txdata, + input wire [15:0] gt_txctrl0, + input wire [15:0] gt_txctrl1, + output wire gt_rxoutclk, + input wire gt_rxusrclk, + input wire gt_rxusrclk2, + input wire rx_reset_in, + output wire rx_reset_done, + output wire gt_rx_reset_out, + output wire gt_rx_reset_done, + output wire [127:0] gt_rxdata, + output wire [15:0] gt_rxctrl0, + output wire [15:0] gt_rxctrl1 +); + +// DRP +reg [23:0] drp_addr_reg = 24'd0; +reg [15:0] drp_di_reg = 16'd0; +reg drp_en_reg_1 = 1'b0; +reg drp_en_reg_2 = 1'b0; +reg drp_we_reg = 1'b0; +reg [15:0] drp_do_reg = 16'd0; +reg drp_rdy_reg = 1'b0; + +wire [15:0] drp_do_1; +wire drp_rdy_1; +wire [15:0] drp_do_2; +wire drp_rdy_2; + +assign drp_do = drp_do_reg; +assign drp_rdy = drp_rdy_reg; + +// PLL +wire qpll0_lock; +wire qpll0_clk; +wire qpll0_refclk; +wire qpll1_lock; +wire qpll1_clk; +wire qpll1_refclk; + +wire tx_sel_pll_lock; +wire rx_sel_pll_lock; + +// GT +wire gt_tx_pma_reset_done; +wire gt_tx_prgdiv_reset_done; +wire gt_rx_pma_reset_done; +wire gt_rx_prgdiv_reset_done; + +wire gt_rxcdrlock; +wire gt_rxprbserr; +wire gt_rxprbslocked; + +wire [15:0] gt_dmonitorout; + +// QPLL0 reset and power down +reg qpll0_reset_drp_reg = 1'b0; +reg qpll0_reset_reg = 1'b1; +reg qpll0_pd_drp_reg = QPLL0_PD; +reg qpll0_pd_reg = QPLL0_PD; + +reg [7:0] qpll0_reset_counter_reg = 0; + +always @(posedge drp_clk) begin + qpll0_pd_reg <= qpll0_pd_drp_reg; + qpll0_reset_reg <= 1'b1; + + if (&qpll0_reset_counter_reg) begin + qpll0_reset_reg <= 1'b0; + end else begin + qpll0_reset_counter_reg <= qpll0_reset_counter_reg + 1; + end + + if (qpll0_reset_drp_reg || qpll0_pd_reg || qpll0_pd_drp_reg) begin + qpll0_reset_counter_reg <= 0; + end + + if (drp_rst) begin + qpll0_reset_reg <= 1'b1; + qpll0_pd_reg <= QPLL0_PD; + qpll0_reset_counter_reg <= 0; + end +end + +reg qpll0_lock_sync_1_reg = 1'b0, qpll0_lock_sync_2_reg = 1'b0; + +always @(posedge drp_clk) begin + qpll0_lock_sync_1_reg <= qpll0_lock; + qpll0_lock_sync_2_reg <= qpll0_lock_sync_1_reg; +end + +// QPLL1 reset and power down +reg qpll1_reset_drp_reg = 1'b0; +reg qpll1_reset_reg = 1'b1; +reg qpll1_pd_drp_reg = QPLL1_PD; +reg qpll1_pd_reg = QPLL1_PD; + +reg [7:0] qpll1_reset_counter_reg = 0; + +always @(posedge drp_clk) begin + qpll1_pd_reg <= qpll1_pd_drp_reg; + qpll1_reset_reg <= 1'b1; + + if (&qpll1_reset_counter_reg) begin + qpll1_reset_reg <= 1'b0; + end else begin + qpll1_reset_counter_reg <= qpll1_reset_counter_reg + 1; + end + + if (qpll1_reset_drp_reg || qpll1_pd_reg || qpll1_pd_drp_reg) begin + qpll1_reset_counter_reg <= 0; + end + + if (drp_rst) begin + qpll1_reset_reg <= 1'b1; + qpll1_pd_reg <= QPLL1_PD; + qpll1_reset_counter_reg <= 0; + end +end + +reg qpll1_lock_sync_1_reg = 1'b0, qpll1_lock_sync_2_reg = 1'b0; + +always @(posedge drp_clk) begin + qpll1_lock_sync_1_reg <= qpll1_lock; + qpll1_lock_sync_2_reg <= qpll1_lock_sync_1_reg; +end + +// TX reset, clock selection, and power down +reg gt_tx_reset_drp_reg = 1'b0; +reg gt_tx_reset_reg = 1'b1; +reg gt_tx_pma_reset_drp_reg = 1'b0; +reg gt_tx_pma_reset_reg = 1'b0; +reg gt_tx_pcs_reset_drp_reg = 1'b0; +reg gt_tx_pcs_reset_reg = 1'b0; + +reg gt_tx_prgdiv_reset_reg = 1'b0; +reg gt_tx_userrdy_reg = 1'b0; + +reg gt_tx_pd_drp_reg = GT_TX_PD; +reg gt_tx_pd_reg = GT_TX_PD; + +reg gt_tx_qpll_sel_drp_reg = GT_TX_QPLL_SEL; +reg gt_tx_qpll_sel_reg = GT_TX_QPLL_SEL; + +reg gt_tx_reset_done_reg = 1'b0; +reg gt_tx_reset_done_sync_1_reg = 1'b0, gt_tx_reset_done_sync_2_reg = 1'b0; +reg gt_tx_pma_reset_done_sync_1_reg = 1'b0, gt_tx_pma_reset_done_sync_2_reg = 1'b0; +reg gt_tx_prgdiv_reset_done_sync_1_reg = 1'b0, gt_tx_prgdiv_reset_done_sync_2_reg = 1'b0; +reg gt_userclk_tx_active_reg = 1'b0; +reg gt_userclk_tx_active_sync_1_reg = 1'b0, gt_userclk_tx_active_sync_2_reg = 1'b0; + +assign gt_tx_reset_out = gt_tx_reset_reg; + +always @(posedge gt_txusrclk2) begin + gt_tx_reset_done_reg <= gt_tx_reset_done; +end + +always @(posedge gt_txusrclk2, posedge gt_tx_reset_reg) begin + if (gt_tx_reset_reg) begin + gt_userclk_tx_active_reg <= 1'b0; + end else begin + gt_userclk_tx_active_reg <= 1'b1; + end +end + +always @(posedge drp_clk) begin + gt_tx_reset_done_sync_1_reg <= gt_tx_reset_done_reg; + gt_tx_reset_done_sync_2_reg <= gt_tx_reset_done_sync_1_reg; + gt_tx_pma_reset_done_sync_1_reg <= gt_tx_pma_reset_done; + gt_tx_pma_reset_done_sync_2_reg <= gt_tx_pma_reset_done_sync_1_reg; + gt_tx_prgdiv_reset_done_sync_1_reg <= gt_tx_prgdiv_reset_done; + gt_tx_prgdiv_reset_done_sync_2_reg <= gt_tx_prgdiv_reset_done_sync_1_reg; + gt_userclk_tx_active_sync_1_reg <= gt_userclk_tx_active_reg; + gt_userclk_tx_active_sync_2_reg <= gt_userclk_tx_active_sync_1_reg; +end + +wire tx_reset_in_int; + +sync_reset #( + .N(4) +) +sync_reset_tx_reset_inst ( + .clk(drp_clk), + .rst(tx_reset_in || drp_rst || xcvr_ctrl_rst), + .out(tx_reset_in_int) +); + +localparam [1:0] + TX_RESET_STATE_RESET = 2'd0, + TX_RESET_STATE_WAIT_LOCK = 2'd1, + TX_RESET_STATE_WAIT_USRCLK = 2'd2, + TX_RESET_STATE_DONE = 2'd3; + +reg [1:0] tx_reset_state_reg = TX_RESET_STATE_RESET; +reg [7:0] tx_reset_counter_reg = 0; +reg tx_reset_done_reg = 1'b0; + +assign tx_sel_pll_lock = gt_tx_qpll_sel_drp_reg ? qpll1_lock_sync_2_reg : qpll0_lock_sync_2_reg; + +assign tx_reset_done = tx_reset_done_reg; + +always @(posedge drp_clk) begin + gt_tx_reset_reg <= 1'b1; + gt_tx_pma_reset_reg <= gt_tx_pma_reset_drp_reg; + gt_tx_pcs_reset_reg <= gt_tx_pcs_reset_drp_reg; + + gt_tx_prgdiv_reset_reg <= 1'b1; + gt_tx_userrdy_reg <= 1'b0; + + gt_tx_pd_reg <= gt_tx_pd_drp_reg; + gt_tx_qpll_sel_reg <= gt_tx_qpll_sel_drp_reg; + + tx_reset_state_reg <= TX_RESET_STATE_RESET; + tx_reset_counter_reg <= 0; + tx_reset_done_reg <= 1'b0; + + case (tx_reset_state_reg) + TX_RESET_STATE_RESET: begin + gt_tx_reset_reg <= 1'b1; + gt_tx_prgdiv_reset_reg <= 1'b1; + gt_tx_userrdy_reg <= 1'b0; + + tx_reset_state_reg <= TX_RESET_STATE_WAIT_LOCK; + end + TX_RESET_STATE_WAIT_LOCK: begin + gt_tx_reset_reg <= 1'b1; + gt_tx_prgdiv_reset_reg <= 1'b1; + gt_tx_userrdy_reg <= 1'b0; + + tx_reset_state_reg <= TX_RESET_STATE_WAIT_LOCK; + if (tx_sel_pll_lock) begin + // QPLL locked + if (&tx_reset_counter_reg) begin + tx_reset_state_reg <= TX_RESET_STATE_WAIT_USRCLK; + end else begin + tx_reset_counter_reg <= tx_reset_counter_reg + 1; + end + end + end + TX_RESET_STATE_WAIT_USRCLK: begin + gt_tx_reset_reg <= 1'b0; + gt_tx_prgdiv_reset_reg <= 1'b0; + gt_tx_userrdy_reg <= 1'b0; + + tx_reset_state_reg <= TX_RESET_STATE_WAIT_USRCLK; + if (gt_userclk_tx_active_sync_2_reg) begin + // user clock running + if (&tx_reset_counter_reg) begin + tx_reset_state_reg <= TX_RESET_STATE_DONE; + end else begin + tx_reset_counter_reg <= tx_reset_counter_reg + 1; + end + end + end + TX_RESET_STATE_DONE: begin + gt_tx_reset_reg <= 1'b0; + gt_tx_prgdiv_reset_reg <= 1'b0; + gt_tx_userrdy_reg <= 1'b1; + + tx_reset_done_reg <= gt_tx_reset_done_sync_2_reg && gt_tx_prgdiv_reset_done_sync_2_reg; + + tx_reset_state_reg <= TX_RESET_STATE_DONE; + end + endcase + + if (tx_reset_in_int || gt_tx_reset_drp_reg || gt_tx_pd_drp_reg || !tx_sel_pll_lock || (gt_tx_qpll_sel_reg != gt_tx_qpll_sel_drp_reg)) begin + tx_reset_state_reg <= TX_RESET_STATE_RESET; + end + + if (drp_rst) begin + gt_tx_reset_reg <= 1'b1; + gt_tx_pma_reset_reg <= 1'b0; + gt_tx_pcs_reset_reg <= 1'b0; + + gt_tx_prgdiv_reset_reg <= 1'b1; + gt_tx_userrdy_reg <= 1'b0; + + gt_tx_pd_reg <= GT_TX_PD; + gt_tx_qpll_sel_reg <= GT_TX_QPLL_SEL; + + tx_reset_state_reg <= TX_RESET_STATE_RESET; + tx_reset_done_reg <= 1'b0; + end +end + +// RX reset, clock selection, CDR, EQ, and power down +reg gt_rx_reset_drp_reg = 1'b0; +reg gt_rx_reset_reg = 1'b1; +reg gt_rx_pma_reset_drp_reg = 1'b0; +reg gt_rx_pma_reset_reg = 1'b0; +reg gt_rx_pcs_reset_drp_reg = 1'b0; +reg gt_rx_pcs_reset_reg = 1'b0; +reg gt_rx_dfe_lpm_reset_drp_reg = 1'b0; +reg gt_rx_dfe_lpm_reset_reg = 1'b0; +reg gt_eyescan_reset_drp_reg = 1'b0; +reg gt_eyescan_reset_reg = 1'b0; + +reg gt_rx_prgdiv_reset_reg = 1'b0; +reg gt_rx_userrdy_reg = 1'b0; + +reg gt_rx_pd_drp_reg = GT_RX_PD; +reg gt_rx_pd_reg = GT_RX_PD; + +reg gt_rx_qpll_sel_drp_reg = GT_RX_QPLL_SEL; +reg gt_rx_qpll_sel_reg = GT_RX_QPLL_SEL; + +reg gt_rxcdrhold_drp_reg = 1'b0; +reg gt_rxcdrhold_reg = 1'b0; +reg gt_rxlpmen_drp_reg = GT_RX_LPM_EN; +reg gt_rxlpmen_reg = GT_RX_LPM_EN; + +reg gt_rx_reset_done_reg = 1'b0; +reg gt_rx_reset_done_sync_1_reg = 1'b0, gt_rx_reset_done_sync_2_reg = 1'b0; +reg gt_rx_pma_reset_done_sync_1_reg = 1'b0, gt_rx_pma_reset_done_sync_2_reg = 1'b0; +reg gt_rx_prgdiv_reset_done_sync_1_reg = 1'b0, gt_rx_prgdiv_reset_done_sync_2_reg = 1'b0; +reg gt_userclk_rx_active_reg = 1'b0; +reg gt_userclk_rx_active_sync_1_reg = 1'b0, gt_userclk_rx_active_sync_2_reg = 1'b0; +reg gt_rxcdrlock_sync_1_reg = 1'b0, gt_rxcdrlock_sync_2_reg = 1'b0; + +assign gt_rx_reset_out = gt_rx_reset_reg; + +always @(posedge gt_rxusrclk2) begin + gt_rx_reset_done_reg <= gt_rx_reset_done; +end + +always @(posedge gt_rxusrclk2, posedge gt_rx_reset_reg) begin + if (gt_rx_reset_reg) begin + gt_userclk_rx_active_reg <= 1'b0; + end else begin + gt_userclk_rx_active_reg <= 1'b1; + end +end + +always @(posedge drp_clk) begin + gt_rx_reset_done_sync_1_reg <= gt_rx_reset_done_reg; + gt_rx_reset_done_sync_2_reg <= gt_rx_reset_done_sync_1_reg; + gt_rx_pma_reset_done_sync_1_reg <= gt_rx_pma_reset_done; + gt_rx_pma_reset_done_sync_2_reg <= gt_rx_pma_reset_done_sync_1_reg; + gt_rx_prgdiv_reset_done_sync_1_reg <= gt_rx_prgdiv_reset_done; + gt_rx_prgdiv_reset_done_sync_2_reg <= gt_rx_prgdiv_reset_done_sync_1_reg; + gt_userclk_rx_active_sync_1_reg <= gt_userclk_rx_active_reg; + gt_userclk_rx_active_sync_2_reg <= gt_userclk_rx_active_sync_1_reg; + gt_rxcdrlock_sync_1_reg <= gt_rxcdrlock; + gt_rxcdrlock_sync_2_reg <= gt_rxcdrlock_sync_1_reg; +end + +wire rx_reset_in_int; + +sync_reset #( + .N(4) +) +sync_reset_rx_reset_inst ( + .clk(drp_clk), + .rst(rx_reset_in || drp_rst || xcvr_ctrl_rst), + .out(rx_reset_in_int) +); + +localparam [2:0] + RX_RESET_STATE_RESET = 3'd0, + RX_RESET_STATE_WAIT_LOCK = 3'd1, + RX_RESET_STATE_WAIT_CDR = 3'd2, + RX_RESET_STATE_WAIT_USRCLK = 3'd3, + RX_RESET_STATE_DONE = 3'd4; + +reg [2:0] rx_reset_state_reg = RX_RESET_STATE_RESET; +reg [7:0] rx_reset_counter_reg = 0; +reg [19:0] rx_reset_cdr_counter_reg = 0; +reg rx_reset_done_reg = 1'b0; + +assign rx_sel_pll_lock = gt_rx_qpll_sel_drp_reg ? qpll1_lock_sync_2_reg : qpll0_lock_sync_2_reg; + +assign rx_reset_done = rx_reset_done_reg; + +always @(posedge drp_clk) begin + gt_rx_reset_reg <= 1'b1; + gt_rx_pma_reset_reg <= gt_rx_pma_reset_drp_reg; + gt_rx_pcs_reset_reg <= gt_rx_pcs_reset_drp_reg; + gt_rx_dfe_lpm_reset_reg <= gt_rx_dfe_lpm_reset_drp_reg; + gt_eyescan_reset_reg <= gt_eyescan_reset_drp_reg; + + gt_rx_prgdiv_reset_reg <= 1'b1; + gt_rx_userrdy_reg <= 1'b0; + + gt_rx_pd_reg <= gt_rx_pd_drp_reg; + gt_rx_qpll_sel_reg <= gt_rx_qpll_sel_drp_reg; + + gt_rxcdrhold_reg <= gt_rxcdrhold_drp_reg; + gt_rxlpmen_reg <= gt_rxlpmen_drp_reg; + + rx_reset_state_reg <= RX_RESET_STATE_RESET; + rx_reset_counter_reg <= 0; + rx_reset_cdr_counter_reg <= 0; + rx_reset_done_reg <= 1'b0; + + case (rx_reset_state_reg) + RX_RESET_STATE_RESET: begin + gt_rx_reset_reg <= 1'b1; + gt_rx_prgdiv_reset_reg <= 1'b1; + gt_rx_userrdy_reg <= 1'b0; + + rx_reset_state_reg <= RX_RESET_STATE_WAIT_LOCK; + end + RX_RESET_STATE_WAIT_LOCK: begin + gt_rx_reset_reg <= 1'b1; + gt_rx_prgdiv_reset_reg <= 1'b1; + gt_rx_userrdy_reg <= 1'b0; + + rx_reset_state_reg <= RX_RESET_STATE_WAIT_LOCK; + if (rx_sel_pll_lock) begin + // QPLL locked + if (&rx_reset_counter_reg) begin + rx_reset_state_reg <= RX_RESET_STATE_WAIT_CDR; + end else begin + rx_reset_counter_reg <= rx_reset_counter_reg + 1; + end + end + end + RX_RESET_STATE_WAIT_CDR: begin + gt_rx_reset_reg <= 1'b0; + gt_rx_prgdiv_reset_reg <= 1'b1; + gt_rx_userrdy_reg <= 1'b0; + + rx_reset_state_reg <= RX_RESET_STATE_WAIT_CDR; + + if (&rx_reset_cdr_counter_reg) begin + rx_reset_state_reg <= RX_RESET_STATE_WAIT_USRCLK; + end else begin + rx_reset_cdr_counter_reg <= rx_reset_cdr_counter_reg + 1; + end + + if (gt_rxcdrlock_sync_2_reg) begin + // CDR locked + if (&rx_reset_counter_reg) begin + rx_reset_state_reg <= RX_RESET_STATE_WAIT_USRCLK; + end else begin + rx_reset_counter_reg <= rx_reset_counter_reg + 1; + end + end + end + RX_RESET_STATE_WAIT_USRCLK: begin + gt_rx_reset_reg <= 1'b0; + gt_rx_prgdiv_reset_reg <= 1'b0; + gt_rx_userrdy_reg <= 1'b0; + + rx_reset_state_reg <= RX_RESET_STATE_WAIT_USRCLK; + if (gt_userclk_rx_active_sync_2_reg) begin + // user clock running + if (&rx_reset_counter_reg) begin + rx_reset_state_reg <= RX_RESET_STATE_DONE; + end else begin + rx_reset_counter_reg <= rx_reset_counter_reg + 1; + end + end + end + RX_RESET_STATE_DONE: begin + gt_rx_reset_reg <= 1'b0; + gt_rx_prgdiv_reset_reg <= 1'b0; + gt_rx_userrdy_reg <= 1'b1; + + rx_reset_done_reg <= gt_rx_reset_done_sync_2_reg && gt_rx_prgdiv_reset_done_sync_2_reg; + + rx_reset_state_reg <= RX_RESET_STATE_DONE; + end + endcase + + if (rx_reset_in_int || gt_rx_reset_drp_reg || gt_rx_pd_drp_reg || !rx_sel_pll_lock || (gt_rx_qpll_sel_reg != gt_rx_qpll_sel_drp_reg) || (gt_rxlpmen_reg != gt_rxlpmen_drp_reg)) begin + rx_reset_state_reg <= RX_RESET_STATE_RESET; + end + + if (drp_rst) begin + gt_rx_reset_reg <= 1'b1; + gt_rx_pma_reset_reg <= 1'b0; + gt_rx_pcs_reset_reg <= 1'b0; + gt_rx_dfe_lpm_reset_reg <= 1'b0; + gt_eyescan_reset_reg <= 1'b0; + + gt_rx_prgdiv_reset_reg <= 1'b1; + gt_rx_userrdy_reg <= 1'b0; + + gt_rx_pd_reg <= GT_RX_PD; + gt_rx_qpll_sel_reg <= GT_RX_QPLL_SEL; + + rx_reset_state_reg <= RX_RESET_STATE_RESET; + rx_reset_done_reg <= 1'b0; + end +end + +// Loopback +reg [2:0] gt_loopback_drp_reg = 3'b000; +reg [2:0] gt_loopback_reg = 3'b000; + +always @(posedge drp_clk) begin + gt_loopback_reg <= gt_loopback_drp_reg; +end + +// Digital monitor +reg [7:0] gt_dmonitorout_drp_reg = 8'd0; +reg [7:0] gt_dmonitorout_sync_1_reg = 8'd0, gt_dmonitorout_sync_2_reg = 8'd0, gt_dmonitorout_sync_3_reg = 8'd0; + +always @(posedge drp_clk) begin + gt_dmonitorout_sync_1_reg <= gt_dmonitorout; + gt_dmonitorout_sync_2_reg <= gt_dmonitorout_sync_1_reg; + gt_dmonitorout_sync_3_reg <= gt_dmonitorout_sync_2_reg; + + if (gt_dmonitorout_sync_3_reg == gt_dmonitorout_sync_2_reg) begin + gt_dmonitorout_drp_reg <= gt_dmonitorout_sync_3_reg; + end +end + +// TX PRBS and driver control +reg [3:0] gt_txprbssel_drp_reg = 4'd0; +reg [3:0] gt_txprbssel_sync_reg = 4'd0; +reg gt_txprbsforceerr_drp_reg = 1'b0; +reg gt_txprbsforceerr_sync_1_reg = 1'b0, gt_txprbsforceerr_sync_2_reg = 1'b0, gt_txprbsforceerr_sync_3_reg = 1'b0; +reg gt_txpolarity_drp_reg = GT_TX_POLARITY; +reg gt_txpolarity_sync_reg = GT_TX_POLARITY; +reg gt_txelecidle_drp_reg = GT_TX_ELECIDLE; +reg gt_txelecidle_reg = GT_TX_ELECIDLE; +reg gt_txinhibit_drp_reg = GT_TX_INHIBIT; +reg gt_txinhibit_sync_reg = GT_TX_INHIBIT; +reg [4:0] gt_txdiffctrl_drp_reg = GT_TX_DIFFCTRL; +reg [4:0] gt_txdiffctrl_reg = GT_TX_DIFFCTRL; +reg [6:0] gt_txmaincursor_drp_reg = GT_TX_MAINCURSOR; +reg [6:0] gt_txmaincursor_reg = GT_TX_MAINCURSOR; +reg [4:0] gt_txpostcursor_drp_reg = GT_TX_POSTCURSOR; +reg [4:0] gt_txpostcursor_reg = GT_TX_POSTCURSOR; +reg [4:0] gt_txprecursor_drp_reg = GT_TX_PRECURSOR; +reg [4:0] gt_txprecursor_reg = GT_TX_PRECURSOR; + +always @(posedge gt_txusrclk2) begin + gt_txprbssel_sync_reg <= gt_txprbssel_drp_reg; + gt_txprbsforceerr_sync_1_reg <= gt_txprbsforceerr_drp_reg; + gt_txprbsforceerr_sync_2_reg <= gt_txprbsforceerr_sync_1_reg; + gt_txprbsforceerr_sync_3_reg <= gt_txprbsforceerr_sync_2_reg; + gt_txpolarity_sync_reg <= gt_txpolarity_drp_reg; + gt_txinhibit_sync_reg <= gt_txinhibit_drp_reg; +end + +always @(posedge drp_clk) begin + gt_txelecidle_reg <= gt_tx_pd_drp_reg ? 1'b1 : gt_txelecidle_drp_reg; + gt_txdiffctrl_reg <= gt_txdiffctrl_drp_reg; + gt_txmaincursor_reg <= gt_txmaincursor_drp_reg; + gt_txpostcursor_reg <= gt_txpostcursor_drp_reg; + gt_txprecursor_reg <= gt_txprecursor_drp_reg; +end + +// RX PRBS and buffer control +reg gt_rxpolarity_drp_reg = GT_RX_POLARITY; +reg gt_rxpolarity_sync_reg = GT_RX_POLARITY; +reg gt_rxprbscntreset_drp_reg = 1'b0; +reg gt_rxprbscntreset_sync_1_reg = 1'b0, gt_rxprbscntreset_sync_2_reg = 1'b0, gt_rxprbscntreset_sync_3_reg = 1'b0; +reg [3:0] gt_rxprbssel_drp_reg = 4'd0; +reg [3:0] gt_rxprbssel_sync_reg = 4'd0; +reg gt_rxprbserr_drp_reg = 1'b0; +reg gt_rxprbserr_sync_1_reg = 1'b0, gt_rxprbserr_sync_2_reg = 1'b0, gt_rxprbserr_sync_3_reg = 1'b0; +reg gt_rxprbserr_sync_4_reg = 1'b0, gt_rxprbserr_sync_5_reg = 1'b0; +reg gt_rxprbslocked_reg = 1'b0; +reg gt_rxprbslocked_sync_1_reg = 1'b0, gt_rxprbslocked_sync_2_reg = 1'b0; + +always @(posedge gt_rxusrclk2) begin + gt_rxpolarity_sync_reg <= gt_rxpolarity_drp_reg; + gt_rxprbscntreset_sync_1_reg <= gt_rxprbscntreset_drp_reg; + gt_rxprbscntreset_sync_2_reg <= gt_rxprbscntreset_sync_1_reg; + gt_rxprbscntreset_sync_3_reg <= gt_rxprbscntreset_sync_2_reg; + gt_rxprbssel_sync_reg <= gt_rxprbssel_drp_reg; + gt_rxprbserr_sync_1_reg <= (gt_rxprbserr_sync_1_reg && !gt_rxprbserr_sync_5_reg) || gt_rxprbserr; + gt_rxprbserr_sync_4_reg <= gt_rxprbserr_sync_3_reg; + gt_rxprbserr_sync_5_reg <= gt_rxprbserr_sync_4_reg; + gt_rxprbslocked_reg <= gt_rxprbslocked; +end + +always @(posedge drp_clk) begin + gt_rxprbserr_sync_2_reg <= gt_rxprbserr_sync_1_reg; + gt_rxprbserr_sync_3_reg <= gt_rxprbserr_sync_2_reg; + gt_rxprbslocked_sync_1_reg <= gt_rxprbslocked_reg; + gt_rxprbslocked_sync_2_reg <= gt_rxprbslocked_sync_1_reg; +end + +// DRP interface +always @(posedge drp_clk) begin + drp_en_reg_1 <= 1'b0; + drp_en_reg_2 <= 1'b0; + drp_we_reg <= 1'b0; + drp_rdy_reg <= 1'b0; + drp_do_reg <= 16'd0; + + gt_rxprbserr_drp_reg <= gt_rxprbserr_drp_reg || gt_rxprbserr_sync_3_reg; + + if (drp_en) begin + drp_addr_reg <= drp_addr; + drp_di_reg <= drp_di; + drp_we_reg <= drp_we; + if (HAS_COMMON && drp_addr[19] == 1'b1) begin + // common + if (drp_addr[16]) begin + // control registers + drp_rdy_reg <= 1'b1; + if (drp_we) begin + case (drp_addr[15:0]) + // QPLL0 + 16'h0000: begin + qpll0_reset_drp_reg <= drp_di[0]; + end + 16'h0001: begin + qpll0_pd_drp_reg <= drp_di[0]; + end + // QPLL1 + 16'h1000: begin + qpll1_reset_drp_reg <= drp_di[0]; + end + 16'h1001: begin + qpll1_pd_drp_reg <= drp_di[0]; + end + endcase + end + case (drp_addr[15:0]) + // QPLL0 + 16'h0000: begin + drp_do_reg[0] <= qpll0_reset_drp_reg; + drp_do_reg[8] <= qpll0_lock_sync_2_reg; + end + 16'h0001: begin + drp_do_reg[0] <= qpll0_pd_drp_reg; + end + // QPLL1 + 16'h1000: begin + drp_do_reg[0] <= qpll1_reset_drp_reg; + drp_do_reg[8] <= qpll1_lock_sync_2_reg; + end + 16'h1001: begin + drp_do_reg[0] <= qpll1_pd_drp_reg; + end + endcase + end else begin + // common DRP interface + drp_en_reg_2 <= 1'b1; + end + end else begin + // channel + if (drp_addr[16]) begin + // control registers + drp_rdy_reg <= 1'b1; + if (drp_we) begin + case (drp_addr[15:0]) + // TX + 16'h0000: begin + gt_tx_reset_drp_reg <= drp_di[0]; + gt_tx_pma_reset_drp_reg <= drp_di[1]; + gt_tx_pcs_reset_drp_reg <= drp_di[2]; + end + 16'h0001: begin + gt_tx_pd_drp_reg <= drp_di[0]; + gt_tx_qpll_sel_drp_reg <= drp_di[1]; + end + 16'h0010: begin + gt_txpolarity_drp_reg <= drp_di[0]; + gt_txelecidle_drp_reg <= drp_di[1]; + gt_txinhibit_drp_reg <= drp_di[2]; + end + 16'h0011: gt_txdiffctrl_drp_reg <= drp_di; + 16'h0012: gt_txmaincursor_drp_reg <= drp_di; + 16'h0013: gt_txprecursor_drp_reg <= drp_di; + 16'h0014: gt_txpostcursor_drp_reg <= drp_di; + 16'h0040: gt_txprbssel_drp_reg <= drp_di; + 16'h0041: gt_txprbsforceerr_drp_reg <= gt_txprbsforceerr_drp_reg ^ drp_di[0]; + // RX + 16'h1000: begin + gt_rx_reset_drp_reg <= drp_di[0]; + gt_rx_pma_reset_drp_reg <= drp_di[1]; + gt_rx_pcs_reset_drp_reg <= drp_di[2]; + gt_rx_dfe_lpm_reset_drp_reg <= drp_di[3]; + gt_eyescan_reset_drp_reg <= drp_di[4]; + end + 16'h1001: begin + gt_rx_pd_drp_reg <= drp_di[0]; + gt_rx_qpll_sel_drp_reg <= drp_di[1]; + end + 16'h1002: begin + gt_loopback_drp_reg <= drp_di[2:0]; + end + 16'h1010: begin + gt_rxpolarity_drp_reg <= drp_di[0]; + end + 16'h1020: begin + gt_rxcdrhold_drp_reg <= drp_di[0]; + end + 16'h1024: begin + gt_rxlpmen_drp_reg <= drp_di[0]; + end + 16'h1040: gt_rxprbssel_drp_reg <= drp_di; + 16'h1041: gt_rxprbscntreset_drp_reg <= gt_rxprbscntreset_drp_reg ^ drp_di[0]; + endcase + end + case (drp_addr[15:0]) + // TX + 16'h0000: begin + drp_do_reg[0] <= gt_tx_reset_drp_reg; + drp_do_reg[1] <= gt_tx_pma_reset_drp_reg; + drp_do_reg[2] <= gt_tx_pcs_reset_drp_reg; + drp_do_reg[8] <= tx_reset_done_reg; + drp_do_reg[9] <= gt_tx_reset_done_sync_2_reg; + drp_do_reg[10] <= gt_tx_pma_reset_done_sync_2_reg; + drp_do_reg[11] <= gt_tx_prgdiv_reset_done_sync_2_reg; + drp_do_reg[12] <= gt_userclk_tx_active_sync_2_reg; + end + 16'h0001: begin + drp_do_reg[0] <= gt_tx_pd_drp_reg; + drp_do_reg[1] <= gt_tx_qpll_sel_drp_reg; + end + 16'h0010: begin + drp_do_reg[0] <= gt_txpolarity_drp_reg; + drp_do_reg[1] <= gt_txelecidle_drp_reg; + drp_do_reg[2] <= gt_txinhibit_drp_reg; + end + 16'h0011: drp_do_reg <= gt_txdiffctrl_drp_reg; + 16'h0012: drp_do_reg <= gt_txmaincursor_drp_reg; + 16'h0013: drp_do_reg <= gt_txprecursor_drp_reg; + 16'h0014: drp_do_reg <= gt_txpostcursor_drp_reg; + 16'h0040: drp_do_reg <= gt_txprbssel_drp_reg; + // RX + 16'h1000: begin + drp_do_reg[0] <= gt_rx_reset_drp_reg; + drp_do_reg[1] <= gt_rx_pma_reset_drp_reg; + drp_do_reg[2] <= gt_rx_pcs_reset_drp_reg; + drp_do_reg[3] <= gt_rx_dfe_lpm_reset_drp_reg; + drp_do_reg[4] <= gt_eyescan_reset_drp_reg; + drp_do_reg[8] <= rx_reset_done_reg; + drp_do_reg[9] <= gt_rx_reset_done_sync_2_reg; + drp_do_reg[10] <= gt_rx_pma_reset_done_sync_2_reg; + drp_do_reg[11] <= gt_rx_prgdiv_reset_done_sync_2_reg; + drp_do_reg[12] <= gt_userclk_rx_active_sync_2_reg; + end + 16'h1001: begin + drp_do_reg[0] <= gt_rx_pd_drp_reg; + drp_do_reg[1] <= gt_rx_qpll_sel_drp_reg; + end + 16'h1002: begin + drp_do_reg[2:0] <= gt_loopback_drp_reg; + end + 16'h1010: begin + drp_do_reg[0] <= gt_rxpolarity_drp_reg; + end + 16'h1020: begin + drp_do_reg[0] <= gt_rxcdrhold_drp_reg; + drp_do_reg[8] <= gt_rxcdrlock_sync_2_reg; + end + 16'h1024: begin + drp_do_reg[0] <= gt_rxlpmen_drp_reg; + end + 16'h1028: drp_do_reg <= gt_dmonitorout_drp_reg; + 16'h1040: drp_do_reg <= gt_rxprbssel_drp_reg; + 16'h1041: begin + drp_do_reg[8] <= gt_rxprbslocked_sync_2_reg; + drp_do_reg[9] <= gt_rxprbserr_drp_reg; + + gt_rxprbserr_drp_reg <= gt_rxprbserr_sync_3_reg; + end + endcase + end else begin + // channel DRP interface + drp_en_reg_1 <= 1'b1; + end + end + end + + if (drp_rdy_1) begin + drp_rdy_reg <= 1'b1; + drp_do_reg <= drp_do_1; + end else if (drp_rdy_2) begin + drp_rdy_reg <= 1'b1; + drp_do_reg <= drp_do_2; + end + + if (drp_rst) begin + drp_en_reg_1 <= 1'b0; + drp_en_reg_2 <= 1'b0; + drp_we_reg <= 1'b0; + drp_rdy_reg <= 1'b0; + + qpll0_reset_drp_reg <= 1'b0; + qpll0_pd_drp_reg <= QPLL0_PD; + qpll1_reset_drp_reg <= 1'b0; + qpll1_pd_drp_reg <= QPLL1_PD; + + gt_loopback_drp_reg <= 3'b000; + + gt_tx_reset_drp_reg <= 1'b0; + gt_tx_pma_reset_drp_reg <= 1'b0; + gt_tx_pcs_reset_drp_reg <= 1'b0; + gt_rx_reset_drp_reg <= 1'b0; + gt_rx_pma_reset_drp_reg <= 1'b0; + gt_rx_pcs_reset_drp_reg <= 1'b0; + gt_rx_dfe_lpm_reset_drp_reg <= 1'b0; + gt_eyescan_reset_drp_reg <= 1'b0; + + gt_rxcdrhold_drp_reg <= 1'b0; + gt_rxlpmen_drp_reg <= GT_RX_LPM_EN; + + gt_txprbssel_drp_reg <= 4'd0; + gt_txprbsforceerr_drp_reg <= 1'b0; + gt_txpolarity_drp_reg <= GT_TX_POLARITY; + gt_txelecidle_drp_reg <= GT_TX_ELECIDLE; + gt_txinhibit_drp_reg <= GT_TX_INHIBIT; + gt_txdiffctrl_drp_reg <= GT_TX_DIFFCTRL; + gt_txmaincursor_drp_reg <= GT_TX_MAINCURSOR; + gt_txpostcursor_drp_reg <= GT_TX_POSTCURSOR; + gt_txprecursor_drp_reg <= GT_TX_PRECURSOR; + + gt_rxpolarity_drp_reg <= GT_RX_POLARITY; + gt_rxprbscntreset_drp_reg <= 1'b0; + gt_rxprbssel_drp_reg <= 4'd0; + + gt_rxprbserr_drp_reg <= 1'b0; + end +end + +generate + +if (HAS_COMMON) begin : xcvr_gty_com + + cmac_gty_full + cmac_gty_full_inst ( + // Common + .gtpowergood_out(xcvr_gtpowergood_out), + .loopback_in(gt_loopback_reg), + + // DRP + .drpclk_common_in(drp_clk), + .drpaddr_common_in(drp_addr_reg), + .drpdi_common_in(drp_di_reg), + .drpen_common_in(drp_en_reg_2), + .drpwe_common_in(drp_we_reg), + .drpdo_common_out(drp_do_2), + .drprdy_common_out(drp_rdy_2), + + .drpclk_in(drp_clk), + .drpaddr_in(drp_addr_reg), + .drpdi_in(drp_di_reg), + .drpen_in(drp_en_reg_1), + .drpwe_in(drp_we_reg), + .drpdo_out(drp_do_1), + .drprdy_out(drp_rdy_1), + + // PLL + .gtrefclk00_in(xcvr_gtrefclk00_in), + .qpll0lock_out(qpll0_lock), + .qpll0outclk_out(qpll0_clk), + .qpll0outrefclk_out(qpll0_refclk), + .gtrefclk01_in(xcvr_gtrefclk01_in), + .qpll1lock_out(qpll1_lock), + .qpll1outclk_out(qpll1_clk), + .qpll1outrefclk_out(qpll1_refclk), + + .qpll0pd_in(qpll0_pd_reg), + .qpll0reset_in(qpll0_reset_reg), + .qpll1pd_in(qpll1_pd_reg), + .qpll1reset_in(qpll1_reset_reg), + + // Serial data + .gtytxp_out(xcvr_txp), + .gtytxn_out(xcvr_txn), + .gtyrxp_in(xcvr_rxp), + .gtyrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_active_in(gt_userclk_tx_active_reg), + .gtwiz_reset_tx_done_in(tx_reset_done_reg), + .txoutclk_out(gt_txoutclk), + .txusrclk_in(gt_txusrclk), + .txusrclk2_in(gt_txusrclk2), + .txpdelecidlemode_in(1'b1), + .txpd_in(gt_tx_pd_reg ? 2'b11 : 2'b00), + .gttxreset_in(gt_tx_reset_reg), + .txpmareset_in(gt_tx_pma_reset_reg), + .txpcsreset_in(gt_tx_pcs_reset_reg), + .txresetdone_out(gt_tx_reset_done), + .txpmaresetdone_out(gt_tx_pma_reset_done), + .txprogdivreset_in(gt_tx_prgdiv_reset_reg), + .txprgdivresetdone_out(gt_tx_prgdiv_reset_done), + .txpllclksel_in(gt_tx_qpll_sel_reg ? 2'b10 : 2'b11), + .txsysclksel_in(gt_tx_qpll_sel_reg ? 2'b11 : 2'b10), + .txuserrdy_in(gt_tx_userrdy_reg), + + .txpolarity_in(gt_txpolarity_sync_reg), + .txelecidle_in(gt_txelecidle_reg), + .txinhibit_in(gt_txinhibit_sync_reg), + .txdiffctrl_in(gt_txdiffctrl_reg), + .txmaincursor_in(gt_txmaincursor_reg), + .txprecursor_in(gt_txprecursor_reg), + .txpostcursor_in(gt_txpostcursor_reg), + + .txprbsforceerr_in(gt_txprbsforceerr_sync_2_reg ^ gt_txprbsforceerr_sync_3_reg), + .txprbssel_in(gt_txprbssel_sync_reg), + + .txdata_in(gt_txdata), + .txctrl0_in(gt_txctrl0), + .txctrl1_in(gt_txctrl1), + + // Receive + .gtwiz_userclk_rx_active_in(gt_userclk_rx_active_reg), + .gtwiz_reset_rx_done_in(rx_reset_done_reg), + .rxoutclk_out(gt_rxoutclk), + .rxusrclk_in(gt_rxusrclk), + .rxusrclk2_in(gt_rxusrclk2), + .rxpd_in(gt_rx_pd_reg ? 2'b11 : 2'b00), + .gtrxreset_in(gt_rx_reset_reg), + .rxpmareset_in(gt_rx_pma_reset_reg), + .rxdfelpmreset_in(gt_rx_dfe_lpm_reset_reg), + .eyescanreset_in(gt_eyescan_reset_reg), + .rxpcsreset_in(gt_rx_pcs_reset_reg), + .rxresetdone_out(gt_rx_reset_done), + .rxpmaresetdone_out(gt_rx_pma_reset_done), + .rxprogdivreset_in(gt_rx_prgdiv_reset_reg), + .rxprgdivresetdone_out(gt_rx_prgdiv_reset_done), + .rxpllclksel_in(gt_rx_qpll_sel_reg ? 2'b10 : 2'b11), + .rxsysclksel_in(gt_rx_qpll_sel_reg ? 2'b11 : 2'b10), + .rxuserrdy_in(gt_rx_userrdy_reg), + + .rxcdrlock_out(gt_rxcdrlock), + .rxcdrhold_in(gt_rxcdrhold_reg), + + .rxlpmen_in(gt_rxlpmen_reg), + + .dmonitorout_out(gt_dmonitorout), + + .rxpolarity_in(gt_rxpolarity_sync_reg), + + .rxprbscntreset_in(gt_rxprbscntreset_sync_2_reg ^ gt_rxprbscntreset_sync_3_reg), + .rxprbssel_in(gt_rxprbssel_sync_reg), + .rxprbserr_out(gt_rxprbserr), + .rxprbslocked_out(gt_rxprbslocked), + + .eyescandataerror_out(), + + .rxdata_out(gt_rxdata), + .rxctrl0_out(gt_rxctrl0), + .rxctrl1_out(gt_rxctrl1) + ); + + assign xcvr_qpll0lock_out = qpll0_lock; + assign xcvr_qpll0clk_out = qpll0_clk; + assign xcvr_qpll0refclk_out = qpll0_refclk; + assign xcvr_qpll1lock_out = qpll1_lock; + assign xcvr_qpll1clk_out = qpll1_clk; + assign xcvr_qpll1refclk_out = qpll1_refclk; + +end else begin : xcvr_gty + + cmac_gty_channel + cmac_gty_channel_inst ( + // Common + .gtpowergood_out(xcvr_gtpowergood_out), + .loopback_in(gt_loopback_reg), + + // DRP + .drpclk_in(drp_clk), + .drpaddr_in(drp_addr_reg), + .drpdi_in(drp_di_reg), + .drpen_in(drp_en_reg_1), + .drpwe_in(drp_we_reg), + .drpdo_out(drp_do_1), + .drprdy_out(drp_rdy_1), + + // PLL + .qpll0clk_in(qpll0_clk), + .qpll0refclk_in(qpll0_refclk), + .qpll1clk_in(qpll1_clk), + .qpll1refclk_in(qpll1_refclk), + + // Serial data + .gtytxp_out(xcvr_txp), + .gtytxn_out(xcvr_txn), + .gtyrxp_in(xcvr_rxp), + .gtyrxn_in(xcvr_rxn), + + // Transmit + .gtwiz_userclk_tx_active_in(gt_userclk_tx_active_reg), + .gtwiz_reset_tx_done_in(tx_reset_done_reg), + .txoutclk_out(gt_txoutclk), + .txusrclk_in(gt_txusrclk), + .txusrclk2_in(gt_txusrclk2), + .txpdelecidlemode_in(1'b1), + .txpd_in(gt_tx_pd_reg ? 2'b11 : 2'b00), + .gttxreset_in(gt_tx_reset_reg), + .txpmareset_in(gt_tx_pma_reset_reg), + .txpcsreset_in(gt_tx_pcs_reset_reg), + .txresetdone_out(gt_tx_reset_done), + .txpmaresetdone_out(gt_tx_pma_reset_done), + .txprogdivreset_in(gt_tx_prgdiv_reset_reg), + .txprgdivresetdone_out(gt_tx_prgdiv_reset_done), + .txpllclksel_in(gt_tx_qpll_sel_reg ? 2'b10 : 2'b11), + .txsysclksel_in(gt_tx_qpll_sel_reg ? 2'b11 : 2'b10), + .txuserrdy_in(gt_tx_userrdy_reg), + + .txpolarity_in(gt_txpolarity_sync_reg), + .txelecidle_in(gt_txelecidle_reg), + .txinhibit_in(gt_txinhibit_sync_reg), + .txdiffctrl_in(gt_txdiffctrl_reg), + .txmaincursor_in(gt_txmaincursor_reg), + .txprecursor_in(gt_txprecursor_reg), + .txpostcursor_in(gt_txpostcursor_reg), + + .txprbsforceerr_in(gt_txprbsforceerr_sync_2_reg ^ gt_txprbsforceerr_sync_3_reg), + .txprbssel_in(gt_txprbssel_sync_reg), + + .txdata_in(gt_txdata), + .txctrl0_in(gt_txctrl0), + .txctrl1_in(gt_txctrl1), + + // Receive + .gtwiz_userclk_rx_active_in(gt_userclk_rx_active_reg), + .gtwiz_reset_rx_done_in(rx_reset_done_reg), + .rxoutclk_out(gt_rxoutclk), + .rxusrclk_in(gt_rxusrclk), + .rxusrclk2_in(gt_rxusrclk2), + .rxpd_in(gt_rx_pd_reg ? 2'b11 : 2'b00), + .gtrxreset_in(gt_rx_reset_reg), + .rxpmareset_in(gt_rx_pma_reset_reg), + .rxdfelpmreset_in(gt_rx_dfe_lpm_reset_reg), + .eyescanreset_in(gt_eyescan_reset_reg), + .rxpcsreset_in(gt_rx_pcs_reset_reg), + .rxresetdone_out(gt_rx_reset_done), + .rxpmaresetdone_out(gt_rx_pma_reset_done), + .rxprogdivreset_in(gt_rx_prgdiv_reset_reg), + .rxprgdivresetdone_out(gt_rx_prgdiv_reset_done), + .rxpllclksel_in(gt_rx_qpll_sel_reg ? 2'b10 : 2'b11), + .rxsysclksel_in(gt_rx_qpll_sel_reg ? 2'b11 : 2'b10), + .rxuserrdy_in(gt_rx_userrdy_reg), + + .rxcdrlock_out(gt_rxcdrlock), + .rxcdrhold_in(gt_rxcdrhold_reg), + + .rxlpmen_in(gt_rxlpmen_reg), + + .dmonitorout_out(gt_dmonitorout), + + .rxpolarity_in(gt_rxpolarity_sync_reg), + + .rxprbscntreset_in(gt_rxprbscntreset_sync_2_reg ^ gt_rxprbscntreset_sync_3_reg), + .rxprbssel_in(gt_rxprbssel_sync_reg), + .rxprbserr_out(gt_rxprbserr), + .rxprbslocked_out(gt_rxprbslocked), + + .eyescandataerror_out(), + + .rxdata_out(gt_rxdata), + .rxctrl0_out(gt_rxctrl0), + .rxctrl1_out(gt_rxctrl1) + ); + + assign xcvr_qpll0lock_out = 1'b0; + assign xcvr_qpll0clk_out = 1'b0; + assign xcvr_qpll0refclk_out = 1'b0; + assign xcvr_qpll1lock_out = 1'b0; + assign xcvr_qpll1clk_out = 1'b0; + assign xcvr_qpll1refclk_out = 1'b0; + + assign qpll0_lock = xcvr_qpll0lock_in; + assign qpll0_clk = xcvr_qpll0clk_in; + assign qpll0_refclk = xcvr_qpll0refclk_in; + assign qpll1_lock = xcvr_qpll1lock_in; + assign qpll1_clk = xcvr_qpll1clk_in; + assign qpll1_refclk = xcvr_qpll1refclk_in; + + assign drp_do_2 = 16'd0; + assign drp_rdy_2 = 1'b0; + +end + +endgenerate + +endmodule + +`resetall diff --git a/fpga/common/rtl/cmac_gty_wrapper.v b/fpga/common/rtl/cmac_gty_wrapper.v new file mode 100644 index 000000000..b4bcf6028 --- /dev/null +++ b/fpga/common/rtl/cmac_gty_wrapper.v @@ -0,0 +1,1695 @@ +/* + +Copyright 2022, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS +IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +*/ + +// Language: Verilog 2001 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * GTY transceiver and CMAC wrapper + */ +module cmac_gty_wrapper # +( + parameter COUNT = 4, + parameter DRP_CLK_FREQ_HZ = 125000000, + + // PLL parameters + parameter QPLL0_PD = 1'b0, + parameter QPLL1_PD = 1'b1, + + // GT parameters + parameter GT_1_TX_PD = 1'b0, + parameter GT_1_TX_QPLL_SEL = 1'b0, + parameter GT_1_TX_POLARITY = 1'b0, + parameter GT_1_TX_ELECIDLE = 1'b0, + parameter GT_1_TX_INHIBIT = 1'b0, + parameter GT_1_TX_DIFFCTRL = 5'd24, + parameter GT_1_TX_MAINCURSOR = 7'd64, + parameter GT_1_TX_POSTCURSOR = 5'd0, + parameter GT_1_TX_PRECURSOR = 5'd0, + parameter GT_1_RX_PD = 1'b0, + parameter GT_1_RX_QPLL_SEL = 1'b0, + parameter GT_1_RX_LPM_EN = 1'b1, + parameter GT_1_RX_POLARITY = 1'b0, + parameter GT_2_TX_PD = GT_1_TX_PD, + parameter GT_2_TX_QPLL_SEL = GT_1_TX_QPLL_SEL, + parameter GT_2_TX_POLARITY = GT_1_TX_POLARITY, + parameter GT_2_TX_ELECIDLE = GT_1_TX_ELECIDLE, + parameter GT_2_TX_INHIBIT = GT_1_TX_INHIBIT, + parameter GT_2_TX_DIFFCTRL = GT_1_TX_DIFFCTRL, + parameter GT_2_TX_MAINCURSOR = GT_1_TX_MAINCURSOR, + parameter GT_2_TX_POSTCURSOR = GT_1_TX_POSTCURSOR, + parameter GT_2_TX_PRECURSOR = GT_1_TX_PRECURSOR, + parameter GT_2_RX_PD = GT_1_RX_PD, + parameter GT_2_RX_QPLL_SEL = GT_1_RX_QPLL_SEL, + parameter GT_2_RX_LPM_EN = GT_1_RX_LPM_EN, + parameter GT_2_RX_POLARITY = GT_1_RX_POLARITY, + parameter GT_3_TX_PD = GT_1_TX_PD, + parameter GT_3_TX_QPLL_SEL = GT_1_TX_QPLL_SEL, + parameter GT_3_TX_POLARITY = GT_1_TX_POLARITY, + parameter GT_3_TX_ELECIDLE = GT_1_TX_ELECIDLE, + parameter GT_3_TX_INHIBIT = GT_1_TX_INHIBIT, + parameter GT_3_TX_DIFFCTRL = GT_1_TX_DIFFCTRL, + parameter GT_3_TX_MAINCURSOR = GT_1_TX_MAINCURSOR, + parameter GT_3_TX_POSTCURSOR = GT_1_TX_POSTCURSOR, + parameter GT_3_TX_PRECURSOR = GT_1_TX_PRECURSOR, + parameter GT_3_RX_PD = GT_1_RX_PD, + parameter GT_3_RX_QPLL_SEL = GT_1_RX_QPLL_SEL, + parameter GT_3_RX_LPM_EN = GT_1_RX_LPM_EN, + parameter GT_3_RX_POLARITY = GT_1_RX_POLARITY, + parameter GT_4_TX_PD = GT_1_TX_PD, + parameter GT_4_TX_QPLL_SEL = GT_1_TX_QPLL_SEL, + parameter GT_4_TX_POLARITY = GT_1_TX_POLARITY, + parameter GT_4_TX_ELECIDLE = GT_1_TX_ELECIDLE, + parameter GT_4_TX_INHIBIT = GT_1_TX_INHIBIT, + parameter GT_4_TX_DIFFCTRL = GT_1_TX_DIFFCTRL, + parameter GT_4_TX_MAINCURSOR = GT_1_TX_MAINCURSOR, + parameter GT_4_TX_POSTCURSOR = GT_1_TX_POSTCURSOR, + parameter GT_4_TX_PRECURSOR = GT_1_TX_PRECURSOR, + parameter GT_4_RX_PD = GT_1_RX_PD, + parameter GT_4_RX_QPLL_SEL = GT_1_RX_QPLL_SEL, + parameter GT_4_RX_LPM_EN = GT_1_RX_LPM_EN, + parameter GT_4_RX_POLARITY = GT_1_RX_POLARITY, + + // CMAC parameters + parameter AXIS_DATA_WIDTH = 512, + parameter AXIS_KEEP_WIDTH = (AXIS_DATA_WIDTH/8), + parameter TX_SERDES_PIPELINE = 1, + parameter RX_SERDES_PIPELINE = 1, + parameter RS_FEC_ENABLE = 1 +) +( + input wire xcvr_ctrl_clk, + input wire xcvr_ctrl_rst, + + /* + * Common + */ + output wire xcvr_gtpowergood_out, + input wire xcvr_ref_clk, + + /* + * DRP + */ + input wire drp_clk, + input wire drp_rst, + input wire [23:0] drp_addr, + input wire [15:0] drp_di, + input wire drp_en, + input wire drp_we, + output wire [15:0] drp_do, + output wire drp_rdy, + + /* + * Serial data + */ + output wire [COUNT-1:0] xcvr_txp, + output wire [COUNT-1:0] xcvr_txn, + input wire [COUNT-1:0] xcvr_rxp, + input wire [COUNT-1:0] xcvr_rxn, + + /* + * CMAC connections + */ + output wire tx_clk, + output wire tx_rst, + + input wire [AXIS_DATA_WIDTH-1:0] tx_axis_tdata, + input wire [AXIS_KEEP_WIDTH-1:0] tx_axis_tkeep, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire [16+1-1:0] tx_axis_tuser, + + input wire [79:0] tx_ptp_time, + output wire [79:0] tx_ptp_ts, + output wire [15:0] tx_ptp_ts_tag, + output wire tx_ptp_ts_valid, + + output wire rx_clk, + output wire rx_rst, + + output wire [AXIS_DATA_WIDTH-1:0] rx_axis_tdata, + output wire [AXIS_KEEP_WIDTH-1:0] rx_axis_tkeep, + output wire rx_axis_tvalid, + output wire rx_axis_tlast, + output wire [80+1-1:0] rx_axis_tuser, + + output wire rx_ptp_clk, + output wire rx_ptp_rst, + input wire [79:0] rx_ptp_time, + + output wire rx_status +); + +reg [23:0] drp_addr_reg = 24'd0; +reg [15:0] drp_di_reg = 16'd0; +reg drp_en_gty_reg_1 = 1'b0; +reg drp_en_gty_reg_2 = 1'b0; +reg drp_en_gty_reg_3 = 1'b0; +reg drp_en_gty_reg_4 = 1'b0; +reg drp_en_cmac_reg = 1'b0; +reg drp_en_ctrl_reg = 1'b0; +reg drp_we_reg = 1'b0; +reg [15:0] drp_do_reg = 16'd0; +reg drp_rdy_reg = 1'b0; + +wire [15:0] drp_do_gty_1; +wire drp_rdy_gty_1; +wire [15:0] drp_do_gty_2; +wire drp_rdy_gty_2; +wire [15:0] drp_do_gty_3; +wire drp_rdy_gty_3; +wire [15:0] drp_do_gty_4; +wire drp_rdy_gty_4; +wire [15:0] drp_do_cmac; +wire drp_rdy_cmac; +reg [15:0] drp_do_ctrl_reg = 0; +reg drp_rdy_ctrl_reg = 1'b0; + +assign drp_do = drp_do_reg; +assign drp_rdy = drp_rdy_reg; + +always @(posedge drp_clk) begin + drp_en_gty_reg_1 <= 1'b0; + drp_en_gty_reg_2 <= 1'b0; + drp_en_gty_reg_3 <= 1'b0; + drp_en_gty_reg_4 <= 1'b0; + drp_en_cmac_reg <= 1'b0; + drp_en_ctrl_reg <= 1'b0; + drp_we_reg <= 1'b0; + drp_rdy_reg <= 1'b0; + drp_do_reg <= 16'd0; + + if (drp_en) begin + drp_addr_reg <= drp_addr; + drp_di_reg <= drp_di; + drp_we_reg <= drp_we; + if (COUNT > 0 && (drp_addr[19:17] == 3'b000 || drp_addr[19:17] == 3'b100)) begin + drp_en_gty_reg_1 <= 1'b1; + end else if (COUNT > 1 && drp_addr[19:17] == 3'b001) begin + drp_en_gty_reg_2 <= 1'b1; + end else if (COUNT > 2 && drp_addr[19:17] == 3'b010) begin + drp_en_gty_reg_3 <= 1'b1; + end else if (COUNT > 3 && drp_addr[19:17] == 3'b011) begin + drp_en_gty_reg_4 <= 1'b1; + end else if (drp_addr[19:17] == 3'b101) begin + if (drp_addr[16]) begin + drp_en_ctrl_reg <= 1'b1; + end else begin + drp_en_cmac_reg <= 1'b1; + end + end else begin + drp_rdy_reg <= 1'b1; + end + end + + if (drp_rdy_gty_1) begin + drp_rdy_reg <= 1'b1; + drp_do_reg <= drp_do_gty_1; + end else if (drp_rdy_gty_2) begin + drp_rdy_reg <= 1'b1; + drp_do_reg <= drp_do_gty_2; + end else if (drp_rdy_gty_3) begin + drp_rdy_reg <= 1'b1; + drp_do_reg <= drp_do_gty_3; + end else if (drp_rdy_gty_4) begin + drp_rdy_reg <= 1'b1; + drp_do_reg <= drp_do_gty_4; + end else if (drp_rdy_cmac) begin + drp_rdy_reg <= 1'b1; + drp_do_reg <= drp_do_cmac; + end else if (drp_rdy_ctrl_reg) begin + drp_rdy_reg <= 1'b1; + drp_do_reg <= drp_do_ctrl_reg; + end + + if (drp_rst) begin + drp_en_gty_reg_1 <= 1'b0; + drp_en_gty_reg_2 <= 1'b0; + drp_en_gty_reg_3 <= 1'b0; + drp_en_gty_reg_4 <= 1'b0; + drp_en_cmac_reg <= 1'b0; + drp_en_ctrl_reg <= 1'b0; + drp_we_reg <= 1'b0; + drp_rdy_reg <= 1'b0; + end +end + +reg cmac_ctl_tx_rsfec_enable_reg = RS_FEC_ENABLE; +reg cmac_ctl_rx_rsfec_enable_reg = RS_FEC_ENABLE; +reg cmac_ctl_rsfec_ieee_error_indication_mode_reg = 1'b0; +reg cmac_ctl_rx_rsfec_enable_correction_reg = 1'b1; +reg cmac_ctl_rx_rsfec_enable_indication_reg = 1'b1; + +wire [3:0] cmac_stat_rx_rsfec_am_lock; +wire [4*3-1:0] cmac_stat_rx_rsfec_err_count_inc; +wire cmac_stat_rx_rsfec_hi_ser; +wire cmac_stat_rx_rsfec_lane_alignment_status; +wire [4*14-1:0] cmac_stat_rx_rsfec_lane_fill; +wire [7:0] cmac_stat_rx_rsfec_lane_mapping; +wire cmac_stat_rx_rsfec_cw_inc; +wire cmac_stat_rx_rsfec_corrected_cw_inc; +wire cmac_stat_rx_rsfec_uncorrected_cw_inc; + +wire [20*7-1:0] cmac_rx_lane_aligner_fill; + +wire cmac_stat_rx_aligned; +wire cmac_stat_rx_aligned_err; +wire [2:0] cmac_stat_rx_bad_code; +wire [2:0] cmac_stat_rx_bad_fcs; +wire cmac_stat_rx_bad_preamble; +wire cmac_stat_rx_bad_sfd; +wire [19:0] cmac_stat_rx_bip_err; +wire [19:0] cmac_stat_rx_block_lock; +wire cmac_stat_rx_broadcast; +wire [2:0] cmac_stat_rx_fragment; +wire [20*2-1:0] cmac_stat_rx_framing_err; +wire [19:0] cmac_stat_rx_framing_err_valid; +wire cmac_stat_rx_got_signal_os; +wire cmac_stat_rx_hi_ber; +wire cmac_stat_rx_inrangeerr; +wire cmac_stat_rx_internal_local_fault; +wire cmac_stat_rx_jabber; +wire cmac_stat_rx_local_fault; +wire [19:0] cmac_stat_rx_mf_err; +wire [19:0] cmac_stat_rx_mf_len_err; +wire [19:0] cmac_stat_rx_mf_repeat_err; +wire cmac_stat_rx_misaligned; +wire cmac_stat_rx_multicast; +wire cmac_stat_rx_oversize; +wire cmac_stat_rx_packet_64_bytes; +wire cmac_stat_rx_packet_65_127_bytes; +wire cmac_stat_rx_packet_128_255_bytes; +wire cmac_stat_rx_packet_256_511_bytes; +wire cmac_stat_rx_packet_512_1023_bytes; +wire cmac_stat_rx_packet_1024_1518_bytes; +wire cmac_stat_rx_packet_1519_1522_bytes; +wire cmac_stat_rx_packet_1523_1548_bytes; +wire cmac_stat_rx_packet_1549_2047_bytes; +wire cmac_stat_rx_packet_2048_4095_bytes; +wire cmac_stat_rx_packet_4096_8191_bytes; +wire cmac_stat_rx_packet_8192_9215_bytes; +wire cmac_stat_rx_packet_bad_fcs; +wire cmac_stat_rx_packet_large; +wire [2:0] cmac_stat_rx_packet_small; + +reg cmac_ctl_rx_enable_reg = 1'b1; +reg cmac_ctl_rx_force_resync_reg = 1'b0; +reg cmac_ctl_rx_test_pattern_reg = 1'b0; + +wire cmac_stat_rx_received_local_fault; +wire cmac_stat_rx_remote_fault; +wire cmac_stat_rx_status; +wire [2:0] cmac_stat_rx_stomped_fcs; +wire [19:0] cmac_stat_rx_synced; +wire [19:0] cmac_stat_rx_synced_err; +wire [2:0] cmac_stat_rx_test_pattern_mismatch; +wire cmac_stat_rx_toolong; +wire [6:0] cmac_stat_rx_total_bytes; +wire [13:0] cmac_stat_rx_total_good_bytes; +wire cmac_stat_rx_total_good_packets; +wire [2:0] cmac_stat_rx_total_packets; +wire cmac_stat_rx_truncated; +wire [2:0] cmac_stat_rx_undersize; +wire cmac_stat_rx_unicast; +wire cmac_stat_rx_vlan; +wire [19:0] cmac_stat_rx_pcsl_demuxed; +wire [20*5-1:0] cmac_stat_rx_pcsl_number; + +wire cmac_stat_tx_ptp_fifo_read_error; +wire cmac_stat_tx_ptp_fifo_write_error; + +wire cmac_stat_tx_bad_fcs; +wire cmac_stat_tx_broadcast; +wire cmac_stat_tx_frame_error; +wire cmac_stat_tx_local_fault; +wire cmac_stat_tx_multicast; +wire cmac_stat_tx_packet_64_bytes; +wire cmac_stat_tx_packet_65_127_bytes; +wire cmac_stat_tx_packet_128_255_bytes; +wire cmac_stat_tx_packet_256_511_bytes; +wire cmac_stat_tx_packet_512_1023_bytes; +wire cmac_stat_tx_packet_1024_1518_bytes; +wire cmac_stat_tx_packet_1519_1522_bytes; +wire cmac_stat_tx_packet_1523_1548_bytes; +wire cmac_stat_tx_packet_1549_2047_bytes; +wire cmac_stat_tx_packet_2048_4095_bytes; +wire cmac_stat_tx_packet_4096_8191_bytes; +wire cmac_stat_tx_packet_8192_9215_bytes; +wire cmac_stat_tx_packet_large; +wire cmac_stat_tx_packet_small; +wire [5:0] cmac_stat_tx_total_bytes; +wire [13:0] cmac_stat_tx_total_good_bytes; +wire cmac_stat_tx_total_good_packets; +wire cmac_stat_tx_total_packets; +wire cmac_stat_tx_unicast; +wire cmac_stat_tx_vlan; + +reg cmac_ctl_tx_enable_reg = 1'b1; +reg cmac_ctl_tx_send_idle_reg = 1'b0; +reg cmac_ctl_tx_send_rfi_reg = 1'b0; +reg cmac_ctl_tx_send_lfi_reg = 1'b0; +reg cmac_ctl_tx_test_pattern_reg = 1'b0; + +assign rx_status = cmac_stat_rx_status; + +reg tx_reset_drp_reg = 1'b0; +reg gt_tx_reset_drp_reg = 1'b0; +reg rx_reset_drp_reg = 1'b0; +reg gt_rx_reset_drp_reg = 1'b0; + +reg tx_rst_sync_1_reg = 1'b0, tx_rst_sync_2_reg = 1'b0; +reg rx_rst_sync_1_reg = 1'b0, rx_rst_sync_2_reg = 1'b0; + +always @(posedge drp_clk) begin + tx_rst_sync_1_reg <= tx_rst; + tx_rst_sync_2_reg <= tx_rst_sync_1_reg; + rx_rst_sync_1_reg <= rx_rst; + rx_rst_sync_2_reg <= rx_rst_sync_1_reg; +end + +reg cmac_ctl_tx_rsfec_enable_drp_reg = RS_FEC_ENABLE; +reg cmac_ctl_tx_rsfec_enable_sync_reg = RS_FEC_ENABLE; +reg cmac_ctl_rx_rsfec_enable_drp_reg = RS_FEC_ENABLE; +reg cmac_ctl_rx_rsfec_enable_sync_reg = RS_FEC_ENABLE; +reg cmac_ctl_rsfec_ieee_error_indication_mode_drp_reg = 1'b0; +reg cmac_ctl_rsfec_ieee_error_indication_mode_sync_reg = 1'b0; +reg cmac_ctl_rx_rsfec_enable_correction_drp_reg = 1'b1; +reg cmac_ctl_rx_rsfec_enable_correction_sync_reg = 1'b1; +reg cmac_ctl_rx_rsfec_enable_indication_drp_reg = 1'b1; +reg cmac_ctl_rx_rsfec_enable_indication_sync_reg = 1'b1; + +always @(posedge tx_clk) begin + cmac_ctl_tx_rsfec_enable_sync_reg <= cmac_ctl_tx_rsfec_enable_drp_reg; + cmac_ctl_tx_rsfec_enable_reg <= cmac_ctl_tx_rsfec_enable_sync_reg; +end + +always @(posedge rx_clk) begin + cmac_ctl_rx_rsfec_enable_sync_reg <= cmac_ctl_rx_rsfec_enable_drp_reg; + cmac_ctl_rx_rsfec_enable_reg <= cmac_ctl_rx_rsfec_enable_sync_reg; + cmac_ctl_rsfec_ieee_error_indication_mode_sync_reg <= cmac_ctl_rsfec_ieee_error_indication_mode_drp_reg; + cmac_ctl_rsfec_ieee_error_indication_mode_reg <= cmac_ctl_rsfec_ieee_error_indication_mode_sync_reg; + cmac_ctl_rx_rsfec_enable_correction_sync_reg <= cmac_ctl_rx_rsfec_enable_correction_drp_reg; + cmac_ctl_rx_rsfec_enable_correction_reg <= cmac_ctl_rx_rsfec_enable_correction_sync_reg; + cmac_ctl_rx_rsfec_enable_indication_sync_reg <= cmac_ctl_rx_rsfec_enable_indication_drp_reg; + cmac_ctl_rx_rsfec_enable_indication_reg <= cmac_ctl_rx_rsfec_enable_indication_sync_reg; +end + +reg [3:0] cmac_stat_rx_rsfec_am_lock_sync_1_reg = 0, cmac_stat_rx_rsfec_am_lock_sync_2_reg = 0; +reg cmac_stat_rx_rsfec_hi_ser_sync_1_reg = 1'b0, cmac_stat_rx_rsfec_hi_ser_sync_2_reg = 1'b0; +reg cmac_stat_rx_rsfec_lane_alignment_status_sync_1_reg = 1'b0, cmac_stat_rx_rsfec_lane_alignment_status_sync_2_reg = 1'b0; +reg [4*14-1:0] cmac_stat_rx_rsfec_lane_fill_sync_1_reg = 0, cmac_stat_rx_rsfec_lane_fill_sync_2_reg = 0; +reg [7:0] cmac_stat_rx_rsfec_lane_mapping_sync_1_reg = 0, cmac_stat_rx_rsfec_lane_mapping_sync_2_reg = 0; + +always @(posedge drp_clk) begin + cmac_stat_rx_rsfec_am_lock_sync_1_reg <= cmac_stat_rx_rsfec_am_lock; + cmac_stat_rx_rsfec_am_lock_sync_2_reg <= cmac_stat_rx_rsfec_am_lock_sync_1_reg; + cmac_stat_rx_rsfec_hi_ser_sync_1_reg <= cmac_stat_rx_rsfec_hi_ser; + cmac_stat_rx_rsfec_hi_ser_sync_2_reg <= cmac_stat_rx_rsfec_hi_ser_sync_1_reg; + cmac_stat_rx_rsfec_lane_alignment_status_sync_1_reg <= cmac_stat_rx_rsfec_lane_alignment_status; + cmac_stat_rx_rsfec_lane_alignment_status_sync_2_reg <= cmac_stat_rx_rsfec_lane_alignment_status_sync_1_reg; + cmac_stat_rx_rsfec_lane_fill_sync_1_reg <= cmac_stat_rx_rsfec_lane_fill; + cmac_stat_rx_rsfec_lane_fill_sync_2_reg <= cmac_stat_rx_rsfec_lane_fill_sync_1_reg; + cmac_stat_rx_rsfec_lane_mapping_sync_1_reg <= cmac_stat_rx_rsfec_lane_mapping; + cmac_stat_rx_rsfec_lane_mapping_sync_2_reg <= cmac_stat_rx_rsfec_lane_mapping_sync_1_reg; +end + +reg [20*7-1:0] cmac_rx_lane_aligner_fill_sync_1_reg = 0, cmac_rx_lane_aligner_fill_sync_2_reg = 0; + +reg cmac_stat_rx_aligned_sync_1_reg = 1'b0, cmac_stat_rx_aligned_sync_2_reg = 1'b0; +reg cmac_stat_rx_aligned_err_sync_1_reg = 1'b0, cmac_stat_rx_aligned_err_sync_2_reg = 1'b0; +reg [19:0] cmac_stat_rx_block_lock_sync_1_reg = 0, cmac_stat_rx_block_lock_sync_2_reg = 0; +reg cmac_stat_rx_hi_ber_sync_1_reg = 1'b0, cmac_stat_rx_hi_ber_sync_2_reg = 1'b0; +reg cmac_stat_rx_internal_local_fault_sync_1_reg = 1'b0, cmac_stat_rx_internal_local_fault_sync_2_reg = 1'b0; +reg cmac_stat_rx_local_fault_sync_1_reg = 1'b0, cmac_stat_rx_local_fault_sync_2_reg = 1'b0; +reg [19:0] cmac_stat_rx_mf_len_err_sync_1_reg = 20'd0, cmac_stat_rx_mf_len_err_sync_2_reg = 20'd0; +reg [19:0] cmac_stat_rx_mf_repeat_err_sync_1_reg = 20'd0, cmac_stat_rx_mf_repeat_err_sync_2_reg = 20'd0; + +always @(posedge drp_clk) begin + cmac_rx_lane_aligner_fill_sync_1_reg <= cmac_rx_lane_aligner_fill; + cmac_rx_lane_aligner_fill_sync_2_reg <= cmac_rx_lane_aligner_fill_sync_1_reg; + cmac_stat_rx_aligned_sync_1_reg <= cmac_stat_rx_aligned; + cmac_stat_rx_aligned_sync_2_reg <= cmac_stat_rx_aligned_sync_1_reg; + cmac_stat_rx_aligned_err_sync_1_reg <= cmac_stat_rx_aligned_err; + cmac_stat_rx_aligned_err_sync_2_reg <= cmac_stat_rx_aligned_err_sync_1_reg; + cmac_stat_rx_block_lock_sync_1_reg <= cmac_stat_rx_block_lock; + cmac_stat_rx_block_lock_sync_2_reg <= cmac_stat_rx_block_lock_sync_1_reg; + cmac_stat_rx_hi_ber_sync_1_reg <= cmac_stat_rx_hi_ber; + cmac_stat_rx_hi_ber_sync_2_reg <= cmac_stat_rx_hi_ber_sync_1_reg; + cmac_stat_rx_internal_local_fault_sync_1_reg <= cmac_stat_rx_internal_local_fault; + cmac_stat_rx_internal_local_fault_sync_2_reg <= cmac_stat_rx_internal_local_fault_sync_1_reg; + cmac_stat_rx_local_fault_sync_1_reg <= cmac_stat_rx_local_fault; + cmac_stat_rx_local_fault_sync_2_reg <= cmac_stat_rx_local_fault_sync_1_reg; + cmac_stat_rx_mf_len_err_sync_1_reg <= cmac_stat_rx_mf_len_err; + cmac_stat_rx_mf_len_err_sync_2_reg <= cmac_stat_rx_mf_len_err_sync_1_reg; + cmac_stat_rx_mf_repeat_err_sync_1_reg <= cmac_stat_rx_mf_repeat_err; + cmac_stat_rx_mf_repeat_err_sync_2_reg <= cmac_stat_rx_mf_repeat_err_sync_1_reg; +end + +reg cmac_ctl_rx_enable_drp_reg = 1'b1; +reg cmac_ctl_rx_enable_sync_reg = 1'b1; +reg cmac_ctl_rx_force_resync_drp_reg = 1'b0; +reg cmac_ctl_rx_force_resync_sync_reg = 1'b0; +reg cmac_ctl_rx_test_pattern_drp_reg = 1'b0; +reg cmac_ctl_rx_test_pattern_sync_reg = 1'b0; + +always @(posedge rx_clk) begin + cmac_ctl_rx_enable_sync_reg <= cmac_ctl_rx_enable_drp_reg; + cmac_ctl_rx_enable_reg <= cmac_ctl_rx_enable_sync_reg; + cmac_ctl_rx_force_resync_sync_reg <= cmac_ctl_rx_force_resync_drp_reg; + cmac_ctl_rx_force_resync_reg <= cmac_ctl_rx_force_resync_sync_reg; + cmac_ctl_rx_test_pattern_sync_reg <= cmac_ctl_rx_test_pattern_drp_reg; + cmac_ctl_rx_test_pattern_reg <= cmac_ctl_rx_test_pattern_sync_reg; +end + +reg cmac_stat_rx_received_local_fault_sync_1_reg = 1'b0, cmac_stat_rx_received_local_fault_sync_2_reg = 1'b0; +reg cmac_stat_rx_remote_fault_sync_1_reg = 1'b0, cmac_stat_rx_remote_fault_sync_2_reg = 1'b0; +reg cmac_stat_rx_status_sync_1_reg = 1'b0, cmac_stat_rx_status_sync_2_reg = 1'b0; +reg [19:0] cmac_stat_rx_synced_sync_1_reg = 20'd0, cmac_stat_rx_synced_sync_2_reg = 20'd0; +reg [19:0] cmac_stat_rx_synced_err_sync_1_reg = 20'd0, cmac_stat_rx_synced_err_sync_2_reg = 20'd0; +reg [19:0] cmac_stat_rx_pcsl_demuxed_sync_1_reg = 20'd0, cmac_stat_rx_pcsl_demuxed_sync_2_reg = 20'd0; +reg [20*5-1:0] cmac_stat_rx_pcsl_number_sync_1_reg = 0, cmac_stat_rx_pcsl_number_sync_2_reg = 0; + +always @(posedge drp_clk) begin + cmac_stat_rx_received_local_fault_sync_1_reg <= cmac_stat_rx_received_local_fault; + cmac_stat_rx_received_local_fault_sync_2_reg <= cmac_stat_rx_received_local_fault_sync_1_reg; + cmac_stat_rx_remote_fault_sync_1_reg <= cmac_stat_rx_remote_fault; + cmac_stat_rx_remote_fault_sync_2_reg <= cmac_stat_rx_remote_fault_sync_1_reg; + cmac_stat_rx_status_sync_1_reg <= cmac_stat_rx_status; + cmac_stat_rx_status_sync_2_reg <= cmac_stat_rx_status_sync_1_reg; + cmac_stat_rx_synced_sync_1_reg <= cmac_stat_rx_synced; + cmac_stat_rx_synced_sync_2_reg <= cmac_stat_rx_synced_sync_1_reg; + cmac_stat_rx_synced_err_sync_1_reg <= cmac_stat_rx_synced_err; + cmac_stat_rx_synced_err_sync_2_reg <= cmac_stat_rx_synced_err_sync_1_reg; + cmac_stat_rx_pcsl_demuxed_sync_1_reg <= cmac_stat_rx_pcsl_demuxed; + cmac_stat_rx_pcsl_demuxed_sync_2_reg <= cmac_stat_rx_pcsl_demuxed_sync_1_reg; + cmac_stat_rx_pcsl_number_sync_1_reg <= cmac_stat_rx_pcsl_number; + cmac_stat_rx_pcsl_number_sync_2_reg <= cmac_stat_rx_pcsl_number_sync_1_reg; +end + +reg cmac_stat_tx_ptp_fifo_read_error_sync_1_reg = 1'b0, cmac_stat_tx_ptp_fifo_read_error_sync_2_reg = 1'b0; +reg cmac_stat_tx_ptp_fifo_write_error_sync_1_reg = 1'b0, cmac_stat_tx_ptp_fifo_write_error_sync_2_reg = 1'b0; + +reg cmac_stat_tx_local_fault_sync_1_reg = 1'b0, cmac_stat_tx_local_fault_sync_2_reg = 1'b0; + +always @(posedge drp_clk) begin + cmac_stat_tx_ptp_fifo_read_error_sync_1_reg <= cmac_stat_tx_ptp_fifo_read_error; + cmac_stat_tx_ptp_fifo_read_error_sync_2_reg <= cmac_stat_tx_ptp_fifo_read_error_sync_1_reg; + cmac_stat_tx_ptp_fifo_write_error_sync_1_reg <= cmac_stat_tx_ptp_fifo_write_error; + cmac_stat_tx_ptp_fifo_write_error_sync_2_reg <= cmac_stat_tx_ptp_fifo_write_error_sync_1_reg; + cmac_stat_tx_local_fault_sync_1_reg <= cmac_stat_tx_local_fault; + cmac_stat_tx_local_fault_sync_2_reg <= cmac_stat_tx_local_fault_sync_1_reg; +end + +reg cmac_ctl_tx_enable_drp_reg = 1'b1; +reg cmac_ctl_tx_enable_sync_reg = 1'b1; +reg cmac_ctl_tx_send_idle_drp_reg = 1'b0; +reg cmac_ctl_tx_send_idle_sync_reg = 1'b0; +reg cmac_ctl_tx_send_rfi_drp_reg = 1'b0; +reg cmac_ctl_tx_send_rfi_sync_reg = 1'b0; +reg cmac_ctl_tx_send_lfi_drp_reg = 1'b0; +reg cmac_ctl_tx_send_lfi_sync_reg = 1'b0; +reg cmac_ctl_tx_test_pattern_drp_reg = 1'b0; +reg cmac_ctl_tx_test_pattern_sync_reg = 1'b0; + +always @(posedge tx_clk) begin + cmac_ctl_tx_enable_sync_reg <= cmac_ctl_tx_enable_drp_reg; + cmac_ctl_tx_enable_reg <= cmac_ctl_tx_enable_sync_reg; + cmac_ctl_tx_send_idle_sync_reg <= cmac_ctl_tx_send_idle_drp_reg; + cmac_ctl_tx_send_idle_reg <= cmac_ctl_tx_send_idle_sync_reg; + cmac_ctl_tx_send_rfi_sync_reg <= cmac_ctl_tx_send_rfi_drp_reg; + cmac_ctl_tx_send_rfi_reg <= cmac_ctl_tx_send_rfi_sync_reg; + cmac_ctl_tx_send_lfi_sync_reg <= cmac_ctl_tx_send_lfi_drp_reg; + cmac_ctl_tx_send_lfi_reg <= cmac_ctl_tx_send_lfi_sync_reg; + cmac_ctl_tx_test_pattern_sync_reg <= cmac_ctl_tx_test_pattern_drp_reg; + cmac_ctl_tx_test_pattern_reg <= cmac_ctl_tx_test_pattern_sync_reg; +end + +// watchdog +localparam WDT_COUNT = (DRP_CLK_FREQ_HZ * 64'd750) / 1000; +localparam WDT_WIDTH = $clog2(WDT_COUNT + 1); +reg [WDT_WIDTH-1:0] wdt_count_reg = WDT_COUNT; +reg wdt_reset_reg = 1'b0; + +always @(posedge drp_clk) begin + wdt_reset_reg <= 1'b0; + + if (wdt_count_reg == 0) begin + wdt_count_reg <= WDT_COUNT; + wdt_reset_reg <= 1'b1; + end else begin + wdt_count_reg <= wdt_count_reg - 1; + end + + if ((!tx_rst_sync_2_reg && !rx_rst_sync_2_reg && cmac_stat_rx_aligned_sync_2_reg)) begin + wdt_count_reg <= WDT_COUNT; + wdt_reset_reg <= 1'b0; + end + + if (drp_rst) begin + wdt_count_reg <= WDT_COUNT; + wdt_reset_reg <= 1'b0; + end +end + +// DRP interface +always @(posedge drp_clk) begin + drp_rdy_ctrl_reg <= 1'b0; + drp_do_ctrl_reg <= 16'd0; + + if (drp_en_ctrl_reg) begin + drp_rdy_ctrl_reg <= 1'b1; + if (drp_we_reg) begin + case (drp_addr_reg[15:0]) + // TX + 16'h0000: begin + cmac_ctl_tx_enable_drp_reg <= drp_di_reg[0]; + tx_reset_drp_reg <= drp_di_reg[8]; + gt_tx_reset_drp_reg <= drp_di_reg[9]; + end + 16'h0001: begin + cmac_ctl_tx_send_idle_drp_reg <= drp_di_reg[0]; + cmac_ctl_tx_send_rfi_drp_reg <= drp_di_reg[1]; + cmac_ctl_tx_send_lfi_drp_reg <= drp_di_reg[2]; + cmac_ctl_tx_test_pattern_drp_reg <= drp_di_reg[3]; + end + // RX + 16'h0100: begin + cmac_ctl_rx_enable_drp_reg <= drp_di_reg[0]; + rx_reset_drp_reg <= drp_di_reg[8]; + gt_rx_reset_drp_reg <= drp_di_reg[9]; + end + 16'h0101: begin + cmac_ctl_rx_force_resync_drp_reg <= drp_di_reg[0]; + cmac_ctl_rx_test_pattern_drp_reg <= drp_di_reg[1]; + end + // FEC + 16'h0200: begin + cmac_ctl_tx_rsfec_enable_drp_reg <= drp_di_reg[0]; + cmac_ctl_rx_rsfec_enable_drp_reg <= drp_di_reg[1]; + end + 16'h0201: begin + cmac_ctl_rx_rsfec_enable_correction_drp_reg <= drp_di_reg[0]; + cmac_ctl_rx_rsfec_enable_indication_drp_reg <= drp_di_reg[1]; + cmac_ctl_rsfec_ieee_error_indication_mode_drp_reg <= drp_di_reg[8]; + end + endcase + end + case (drp_addr_reg[15:0]) + // TX + 16'h0000: begin + drp_do_ctrl_reg[0] <= cmac_ctl_tx_enable_drp_reg; + drp_do_ctrl_reg[8] <= tx_reset_drp_reg; + drp_do_ctrl_reg[9] <= gt_tx_reset_drp_reg; + drp_do_ctrl_reg[15] <= tx_rst_sync_2_reg; + end + 16'h0001: begin + drp_do_ctrl_reg[0] <= cmac_ctl_tx_send_idle_drp_reg; + drp_do_ctrl_reg[1] <= cmac_ctl_tx_send_rfi_drp_reg; + drp_do_ctrl_reg[2] <= cmac_ctl_tx_send_lfi_drp_reg; + drp_do_ctrl_reg[3] <= cmac_ctl_tx_test_pattern_drp_reg; + end + 16'h0002: begin + drp_do_ctrl_reg[0] <= cmac_stat_tx_local_fault_sync_2_reg; + drp_do_ctrl_reg[8] <= cmac_stat_tx_ptp_fifo_read_error_sync_2_reg; + drp_do_ctrl_reg[9] <= cmac_stat_tx_ptp_fifo_write_error_sync_2_reg; + end + // RX + 16'h0100: begin + drp_do_ctrl_reg[0] <= cmac_ctl_rx_enable_drp_reg; + drp_do_ctrl_reg[8] <= rx_reset_drp_reg; + drp_do_ctrl_reg[9] <= gt_rx_reset_drp_reg; + drp_do_ctrl_reg[15] <= rx_rst_sync_2_reg; + end + 16'h0101: begin + drp_do_ctrl_reg[0] <= cmac_ctl_rx_force_resync_drp_reg; + drp_do_ctrl_reg[1] <= cmac_ctl_rx_test_pattern_drp_reg; + end + 16'h0102: begin + drp_do_ctrl_reg[0] <= cmac_stat_rx_status_sync_2_reg; + drp_do_ctrl_reg[1] <= cmac_stat_rx_aligned_sync_2_reg; + drp_do_ctrl_reg[8] <= cmac_stat_rx_hi_ber_sync_2_reg; + drp_do_ctrl_reg[9] <= cmac_stat_rx_aligned_err_sync_2_reg; + drp_do_ctrl_reg[12] <= cmac_stat_rx_internal_local_fault_sync_2_reg; + drp_do_ctrl_reg[13] <= cmac_stat_rx_local_fault_sync_2_reg; + drp_do_ctrl_reg[14] <= cmac_stat_rx_received_local_fault_sync_2_reg; + drp_do_ctrl_reg[15] <= cmac_stat_rx_remote_fault_sync_2_reg; + end + 16'h0110: drp_do_ctrl_reg <= cmac_stat_rx_block_lock_sync_2_reg[15:0]; + 16'h0111: drp_do_ctrl_reg <= cmac_stat_rx_block_lock_sync_2_reg[19:16]; + 16'h0112: drp_do_ctrl_reg <= cmac_stat_rx_synced_sync_2_reg[15:0]; + 16'h0113: drp_do_ctrl_reg <= cmac_stat_rx_synced_sync_2_reg[19:16]; + 16'h0114: drp_do_ctrl_reg <= cmac_stat_rx_synced_err_sync_2_reg[15:0]; + 16'h0115: drp_do_ctrl_reg <= cmac_stat_rx_synced_err_sync_2_reg[19:16]; + 16'h0116: drp_do_ctrl_reg <= cmac_stat_rx_mf_len_err_sync_2_reg[15:0]; + 16'h0117: drp_do_ctrl_reg <= cmac_stat_rx_mf_len_err_sync_2_reg[19:16]; + 16'h0118: drp_do_ctrl_reg <= cmac_stat_rx_mf_repeat_err_sync_2_reg[15:0]; + 16'h0119: drp_do_ctrl_reg <= cmac_stat_rx_mf_repeat_err_sync_2_reg[19:16]; + 16'h0120: drp_do_ctrl_reg <= cmac_stat_rx_pcsl_demuxed_sync_2_reg[15:0]; + 16'h0121: drp_do_ctrl_reg <= cmac_stat_rx_pcsl_demuxed_sync_2_reg[19:16]; + 16'h0130: begin + drp_do_ctrl_reg[7:0] <= cmac_stat_rx_pcsl_number_sync_2_reg[5*0 +: 5]; + drp_do_ctrl_reg[15:8] <= cmac_stat_rx_pcsl_number_sync_2_reg[5*1 +: 5]; + end + 16'h0131: begin + drp_do_ctrl_reg[7:0] <= cmac_stat_rx_pcsl_number_sync_2_reg[5*2 +: 5]; + drp_do_ctrl_reg[15:8] <= cmac_stat_rx_pcsl_number_sync_2_reg[5*3 +: 5]; + end + 16'h0132: begin + drp_do_ctrl_reg[7:0] <= cmac_stat_rx_pcsl_number_sync_2_reg[5*4 +: 5]; + drp_do_ctrl_reg[15:8] <= cmac_stat_rx_pcsl_number_sync_2_reg[5*5 +: 5]; + end + 16'h0133: begin + drp_do_ctrl_reg[7:0] <= cmac_stat_rx_pcsl_number_sync_2_reg[5*6 +: 5]; + drp_do_ctrl_reg[15:8] <= cmac_stat_rx_pcsl_number_sync_2_reg[5*7 +: 5]; + end + 16'h0134: begin + drp_do_ctrl_reg[7:0] <= cmac_stat_rx_pcsl_number_sync_2_reg[5*8 +: 5]; + drp_do_ctrl_reg[15:8] <= cmac_stat_rx_pcsl_number_sync_2_reg[5*9 +: 5]; + end + 16'h0135: begin + drp_do_ctrl_reg[7:0] <= cmac_stat_rx_pcsl_number_sync_2_reg[5*10 +: 5]; + drp_do_ctrl_reg[15:8] <= cmac_stat_rx_pcsl_number_sync_2_reg[5*11 +: 5]; + end + 16'h0136: begin + drp_do_ctrl_reg[7:0] <= cmac_stat_rx_pcsl_number_sync_2_reg[5*12 +: 5]; + drp_do_ctrl_reg[15:8] <= cmac_stat_rx_pcsl_number_sync_2_reg[5*13 +: 5]; + end + 16'h0137: begin + drp_do_ctrl_reg[7:0] <= cmac_stat_rx_pcsl_number_sync_2_reg[5*14 +: 5]; + drp_do_ctrl_reg[15:8] <= cmac_stat_rx_pcsl_number_sync_2_reg[5*15 +: 5]; + end + 16'h0138: begin + drp_do_ctrl_reg[7:0] <= cmac_stat_rx_pcsl_number_sync_2_reg[5*16 +: 5]; + drp_do_ctrl_reg[15:8] <= cmac_stat_rx_pcsl_number_sync_2_reg[5*17 +: 5]; + end + 16'h0139: begin + drp_do_ctrl_reg[7:0] <= cmac_stat_rx_pcsl_number_sync_2_reg[5*18 +: 5]; + drp_do_ctrl_reg[15:8] <= cmac_stat_rx_pcsl_number_sync_2_reg[5*19 +: 5]; + end + 16'h0140: begin + drp_do_ctrl_reg[7:0] <= cmac_rx_lane_aligner_fill_sync_2_reg[7*0 +: 7]; + drp_do_ctrl_reg[15:8] <= cmac_rx_lane_aligner_fill_sync_2_reg[7*1 +: 7]; + end + 16'h0141: begin + drp_do_ctrl_reg[7:0] <= cmac_rx_lane_aligner_fill_sync_2_reg[7*2 +: 7]; + drp_do_ctrl_reg[15:8] <= cmac_rx_lane_aligner_fill_sync_2_reg[7*3 +: 7]; + end + 16'h0142: begin + drp_do_ctrl_reg[7:0] <= cmac_rx_lane_aligner_fill_sync_2_reg[7*4 +: 7]; + drp_do_ctrl_reg[15:8] <= cmac_rx_lane_aligner_fill_sync_2_reg[7*5 +: 7]; + end + 16'h0143: begin + drp_do_ctrl_reg[7:0] <= cmac_rx_lane_aligner_fill_sync_2_reg[7*6 +: 7]; + drp_do_ctrl_reg[15:8] <= cmac_rx_lane_aligner_fill_sync_2_reg[7*7 +: 7]; + end + 16'h0144: begin + drp_do_ctrl_reg[7:0] <= cmac_rx_lane_aligner_fill_sync_2_reg[7*8 +: 7]; + drp_do_ctrl_reg[15:8] <= cmac_rx_lane_aligner_fill_sync_2_reg[7*9 +: 7]; + end + 16'h0145: begin + drp_do_ctrl_reg[7:0] <= cmac_rx_lane_aligner_fill_sync_2_reg[7*10 +: 7]; + drp_do_ctrl_reg[15:8] <= cmac_rx_lane_aligner_fill_sync_2_reg[7*11 +: 7]; + end + 16'h0146: begin + drp_do_ctrl_reg[7:0] <= cmac_rx_lane_aligner_fill_sync_2_reg[7*12 +: 7]; + drp_do_ctrl_reg[15:8] <= cmac_rx_lane_aligner_fill_sync_2_reg[7*13 +: 7]; + end + 16'h0147: begin + drp_do_ctrl_reg[7:0] <= cmac_rx_lane_aligner_fill_sync_2_reg[7*14 +: 7]; + drp_do_ctrl_reg[15:8] <= cmac_rx_lane_aligner_fill_sync_2_reg[7*15 +: 7]; + end + 16'h0148: begin + drp_do_ctrl_reg[7:0] <= cmac_rx_lane_aligner_fill_sync_2_reg[7*16 +: 7]; + drp_do_ctrl_reg[15:8] <= cmac_rx_lane_aligner_fill_sync_2_reg[7*17 +: 7]; + end + 16'h0149: begin + drp_do_ctrl_reg[7:0] <= cmac_rx_lane_aligner_fill_sync_2_reg[7*18 +: 7]; + drp_do_ctrl_reg[15:8] <= cmac_rx_lane_aligner_fill_sync_2_reg[7*19 +: 7]; + end + // FEC + 16'h0200: begin + drp_do_ctrl_reg[0] <= cmac_ctl_tx_rsfec_enable_drp_reg; + drp_do_ctrl_reg[1] <= cmac_ctl_rx_rsfec_enable_drp_reg; + end + 16'h0201: begin + drp_do_ctrl_reg[0] <= cmac_ctl_rx_rsfec_enable_correction_drp_reg; + drp_do_ctrl_reg[1] <= cmac_ctl_rx_rsfec_enable_indication_drp_reg; + drp_do_ctrl_reg[8] <= cmac_ctl_rsfec_ieee_error_indication_mode_drp_reg; + end + 16'h0202: begin + drp_do_ctrl_reg[0] <= cmac_stat_rx_rsfec_lane_alignment_status_sync_2_reg; + drp_do_ctrl_reg[8] <= cmac_stat_rx_rsfec_hi_ser_sync_2_reg; + end + 16'h0203: begin + drp_do_ctrl_reg[3:0] <= cmac_stat_rx_rsfec_am_lock_sync_2_reg; + end + 16'h0204: begin + drp_do_ctrl_reg[1:0] <= cmac_stat_rx_rsfec_lane_mapping_sync_2_reg[2*0 +: 2]; + drp_do_ctrl_reg[7:4] <= cmac_stat_rx_rsfec_lane_mapping_sync_2_reg[2*1 +: 2]; + drp_do_ctrl_reg[11:8] <= cmac_stat_rx_rsfec_lane_mapping_sync_2_reg[2*2 +: 2]; + drp_do_ctrl_reg[15:12] <= cmac_stat_rx_rsfec_lane_mapping_sync_2_reg[2*3 +: 2]; + end + 16'h0206: drp_do_ctrl_reg <= cmac_stat_rx_rsfec_lane_fill_sync_2_reg[14*0 +: 14]; + 16'h0207: drp_do_ctrl_reg <= cmac_stat_rx_rsfec_lane_fill_sync_2_reg[14*1 +: 14]; + 16'h0208: drp_do_ctrl_reg <= cmac_stat_rx_rsfec_lane_fill_sync_2_reg[14*2 +: 14]; + 16'h0209: drp_do_ctrl_reg <= cmac_stat_rx_rsfec_lane_fill_sync_2_reg[14*3 +: 14]; + endcase + end + + if (drp_rst) begin + drp_rdy_ctrl_reg <= 1'b0; + + tx_reset_drp_reg <= 1'b0; + gt_tx_reset_drp_reg <= 1'b0; + rx_reset_drp_reg <= 1'b0; + gt_rx_reset_drp_reg <= 1'b0; + + cmac_ctl_tx_rsfec_enable_drp_reg <= RS_FEC_ENABLE; + cmac_ctl_rx_rsfec_enable_drp_reg <= RS_FEC_ENABLE; + cmac_ctl_rsfec_ieee_error_indication_mode_drp_reg <= 1'b0; + cmac_ctl_rx_rsfec_enable_correction_drp_reg <= 1'b1; + cmac_ctl_rx_rsfec_enable_indication_drp_reg <= 1'b1; + + cmac_ctl_rx_enable_drp_reg <= 1'b1; + cmac_ctl_rx_force_resync_drp_reg <= 1'b0; + cmac_ctl_rx_test_pattern_drp_reg <= 1'b0; + + cmac_ctl_tx_enable_drp_reg <= 1'b1; + cmac_ctl_tx_send_idle_drp_reg <= 1'b0; + cmac_ctl_tx_send_rfi_drp_reg <= 1'b0; + cmac_ctl_tx_send_lfi_drp_reg <= 1'b0; + cmac_ctl_tx_test_pattern_drp_reg <= 1'b0; + end +end + +// serdes clock and reset +wire [3:0] gt_tx_reset; +wire [3:0] gt_tx_reset_out; +wire gt_txoutclk; +wire gt_txoutclk_bufg; +wire gt_txusrclk; +wire gt_txusrclk2; +wire [3:0] gt_rx_reset; +wire [3:0] gt_rx_reset_out; +wire gt_rxoutclk; +wire gt_rxoutclk_bufg; +wire [3:0] gt_rxusrclk; +wire [3:0] gt_rxusrclk2; + +assign gt_tx_reset[0] = gt_tx_reset_drp_reg; +assign gt_tx_reset[1] = gt_tx_reset_drp_reg || gt_tx_reset_out[0]; +assign gt_tx_reset[2] = gt_tx_reset_drp_reg || gt_tx_reset_out[0]; +assign gt_tx_reset[3] = gt_tx_reset_drp_reg || gt_tx_reset_out[0]; + +assign gt_rx_reset[0] = gt_rx_reset_drp_reg || wdt_reset_reg; +assign gt_rx_reset[1] = gt_rx_reset_drp_reg || wdt_reset_reg || gt_rx_reset_out[0]; +assign gt_rx_reset[2] = gt_rx_reset_drp_reg || wdt_reset_reg || gt_rx_reset_out[0]; +assign gt_rx_reset[3] = gt_rx_reset_drp_reg || wdt_reset_reg || gt_rx_reset_out[0]; + +BUFG_GT bufg_gt_txusrclk_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_tx_reset_out[0]), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_txoutclk), + .O (gt_txoutclk_bufg) +); + +assign gt_txusrclk = gt_txoutclk_bufg; +assign gt_txusrclk2 = gt_txoutclk_bufg; + +BUFG_GT bufg_gt_rxusrclk_inst ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (gt_rx_reset_out[0]), + .CLRMASK (1'b0), + .DIV (3'd0), + .I (gt_rxoutclk), + .O (gt_rxoutclk_bufg) +); + +assign gt_rxusrclk = {4{gt_rxoutclk_bufg}}; +assign gt_rxusrclk2 = {4{gt_rxoutclk_bufg}}; + +assign tx_clk = gt_txusrclk2; + +sync_reset #( + .N(4) +) +sync_reset_tx_rst_inst ( + .clk(tx_clk), + .rst(gt_tx_reset_out[0] || ~gt_tx_reset_done || tx_reset_drp_reg || drp_rst || xcvr_ctrl_rst), + .out(tx_rst) +); + +assign rx_clk = gt_txusrclk2; + +sync_reset #( + .N(4) +) +sync_reset_rx_rst_inst ( + .clk(rx_clk), + .rst(gt_tx_reset_out[0] || ~gt_rx_reset_done || rx_reset_drp_reg || drp_rst || xcvr_ctrl_rst), + .out(rx_rst) +); + +assign rx_ptp_clk = gt_rxusrclk2[0]; + +sync_reset #( + .N(4) +) +sync_reset_rx_ptp_rst_inst ( + .clk(rx_ptp_clk), + .rst(gt_rx_reset_out[0] || rx_rst), + .out(rx_ptp_rst) +); + +// serdes data +// 80 bit mode - 64 bits in data, 8 bits each in ctrl0 and ctrl1 (per serdes) +// widths match concatenated GTY ports (not all bits used) +wire [511:0] gt_txdata; +wire [63:0] gt_txctrl0; +wire [63:0] gt_txctrl1; +wire [511:0] gt_rxdata; +wire [63:0] gt_rxctrl0; +wire [63:0] gt_rxctrl1; + +wire [3:0] gt_tx_reset_done; +wire [3:0] gt_rx_reset_done; + +wire xcvr_qpll0lock; +wire xcvr_qpll0clk; +wire xcvr_qpll0refclk; + +wire xcvr_qpll1lock; +wire xcvr_qpll1clk; +wire xcvr_qpll1refclk; + +cmac_gty_ch_wrapper #( + .HAS_COMMON(1), + // PLL + .QPLL0_PD(QPLL0_PD), + .QPLL1_PD(QPLL1_PD), + // GT + .GT_TX_PD(GT_1_TX_PD), + .GT_TX_QPLL_SEL(GT_1_TX_QPLL_SEL), + .GT_TX_POLARITY(GT_1_TX_POLARITY), + .GT_TX_ELECIDLE(GT_1_TX_ELECIDLE), + .GT_TX_INHIBIT(GT_1_TX_INHIBIT), + .GT_TX_DIFFCTRL(GT_1_TX_DIFFCTRL), + .GT_TX_MAINCURSOR(GT_1_TX_MAINCURSOR), + .GT_TX_POSTCURSOR(GT_1_TX_POSTCURSOR), + .GT_TX_PRECURSOR(GT_1_TX_PRECURSOR), + .GT_RX_PD(GT_1_RX_PD), + .GT_RX_QPLL_SEL(GT_1_RX_QPLL_SEL), + .GT_RX_LPM_EN(GT_1_RX_LPM_EN), + .GT_RX_POLARITY(GT_1_RX_POLARITY) +) +gty_ch_1 ( + .xcvr_ctrl_clk(xcvr_ctrl_clk), + .xcvr_ctrl_rst(xcvr_ctrl_rst), + + // Common + .xcvr_gtpowergood_out(xcvr_gtpowergood_out), + + // DRP + .drp_clk(drp_clk), + .drp_rst(drp_rst), + .drp_addr(drp_addr_reg), + .drp_di(drp_di_reg), + .drp_en(drp_en_gty_reg_1), + .drp_we(drp_we_reg), + .drp_do(drp_do_gty_1), + .drp_rdy(drp_rdy_gty_1), + + // PLL out + .xcvr_gtrefclk00_in(xcvr_ref_clk), + .xcvr_qpll0lock_out(xcvr_qpll0lock), + .xcvr_qpll0clk_out(xcvr_qpll0clk), + .xcvr_qpll0refclk_out(xcvr_qpll0refclk), + .xcvr_gtrefclk01_in(xcvr_ref_clk), + .xcvr_qpll1lock_out(xcvr_qpll1lock), + .xcvr_qpll1clk_out(xcvr_qpll1clk), + .xcvr_qpll1refclk_out(xcvr_qpll1refclk), + + // PLL in + .xcvr_qpll0lock_in(1'b0), + .xcvr_qpll0clk_in(1'b0), + .xcvr_qpll0refclk_in(1'b0), + .xcvr_qpll1lock_in(1'b0), + .xcvr_qpll1clk_in(1'b0), + .xcvr_qpll1refclk_in(1'b0), + + // Serial data + .xcvr_txp(xcvr_txp[0]), + .xcvr_txn(xcvr_txn[0]), + .xcvr_rxp(xcvr_rxp[0]), + .xcvr_rxn(xcvr_rxn[0]), + + // Parallel data + .gt_txoutclk(gt_txoutclk), + .gt_txusrclk(gt_txusrclk), + .gt_txusrclk2(gt_txusrclk2), + .tx_reset_in(gt_tx_reset[0]), + .tx_reset_done(gt_tx_reset_done[0]), + .gt_tx_reset_out(gt_tx_reset_out[0]), + .gt_tx_reset_done(), + .gt_txdata(gt_txdata[0*128 +: 128]), + .gt_txctrl0(gt_txctrl0[0*16 +: 16]), + .gt_txctrl1(gt_txctrl1[0*16 +: 16]), + .gt_rxoutclk(gt_rxoutclk), + .gt_rxusrclk(gt_rxusrclk[0]), + .gt_rxusrclk2(gt_rxusrclk2[0]), + .rx_reset_in(gt_rx_reset[0]), + .rx_reset_done(gt_rx_reset_done[0]), + .gt_rx_reset_out(gt_rx_reset_out[0]), + .gt_rx_reset_done(), + .gt_rxdata(gt_rxdata[0*128 +: 128]), + .gt_rxctrl0(gt_rxctrl0[0*16 +: 16]), + .gt_rxctrl1(gt_rxctrl1[0*16 +: 16]) +); + +cmac_gty_ch_wrapper #( + .HAS_COMMON(0), + // GT + .GT_TX_PD(GT_2_TX_PD), + .GT_TX_QPLL_SEL(GT_2_TX_QPLL_SEL), + .GT_TX_POLARITY(GT_2_TX_POLARITY), + .GT_TX_ELECIDLE(GT_2_TX_ELECIDLE), + .GT_TX_INHIBIT(GT_2_TX_INHIBIT), + .GT_TX_DIFFCTRL(GT_2_TX_DIFFCTRL), + .GT_TX_MAINCURSOR(GT_2_TX_MAINCURSOR), + .GT_TX_POSTCURSOR(GT_2_TX_POSTCURSOR), + .GT_TX_PRECURSOR(GT_2_TX_PRECURSOR), + .GT_RX_PD(GT_2_RX_PD), + .GT_RX_QPLL_SEL(GT_2_RX_QPLL_SEL), + .GT_RX_LPM_EN(GT_2_RX_LPM_EN), + .GT_RX_POLARITY(GT_2_RX_POLARITY) +) +gty_ch_2 ( + .xcvr_ctrl_clk(xcvr_ctrl_clk), + .xcvr_ctrl_rst(xcvr_ctrl_rst), + + // Common + .xcvr_gtpowergood_out(), + + // DRP + .drp_clk(drp_clk), + .drp_rst(drp_rst), + .drp_addr(drp_addr_reg), + .drp_di(drp_di_reg), + .drp_en(drp_en_gty_reg_2), + .drp_we(drp_we_reg), + .drp_do(drp_do_gty_2), + .drp_rdy(drp_rdy_gty_2), + + // PLL out + .xcvr_gtrefclk00_in(1'b0), + .xcvr_qpll0lock_out(), + .xcvr_qpll0clk_out(), + .xcvr_qpll0refclk_out(), + .xcvr_gtrefclk01_in(1'b0), + .xcvr_qpll1lock_out(), + .xcvr_qpll1clk_out(), + .xcvr_qpll1refclk_out(), + + // PLL in + .xcvr_qpll0lock_in(xcvr_qpll0lock), + .xcvr_qpll0clk_in(xcvr_qpll0clk), + .xcvr_qpll0refclk_in(xcvr_qpll0refclk), + .xcvr_qpll1lock_in(xcvr_qpll1lock), + .xcvr_qpll1clk_in(xcvr_qpll1clk), + .xcvr_qpll1refclk_in(xcvr_qpll1refclk), + + // Serial data + .xcvr_txp(xcvr_txp[1]), + .xcvr_txn(xcvr_txn[1]), + .xcvr_rxp(xcvr_rxp[1]), + .xcvr_rxn(xcvr_rxn[1]), + + // Parallel data + .gt_txoutclk(), + .gt_txusrclk(gt_txusrclk), + .gt_txusrclk2(gt_txusrclk2), + .tx_reset_in(gt_tx_reset[1]), + .tx_reset_done(gt_tx_reset_done[1]), + .gt_tx_reset_out(gt_tx_reset_out[1]), + .gt_tx_reset_done(), + .gt_txdata(gt_txdata[1*128 +: 128]), + .gt_txctrl0(gt_txctrl0[1*16 +: 16]), + .gt_txctrl1(gt_txctrl1[1*16 +: 16]), + .gt_rxoutclk(), + .gt_rxusrclk(gt_rxusrclk[1]), + .gt_rxusrclk2(gt_rxusrclk2[1]), + .rx_reset_in(gt_rx_reset[1]), + .rx_reset_done(gt_rx_reset_done[1]), + .gt_rx_reset_out(gt_rx_reset_out[1]), + .gt_rx_reset_done(), + .gt_rxdata(gt_rxdata[1*128 +: 128]), + .gt_rxctrl0(gt_rxctrl0[1*16 +: 16]), + .gt_rxctrl1(gt_rxctrl1[1*16 +: 16]) +); + +cmac_gty_ch_wrapper #( + .HAS_COMMON(0), + // GT + .GT_TX_PD(GT_3_TX_PD), + .GT_TX_QPLL_SEL(GT_3_TX_QPLL_SEL), + .GT_TX_POLARITY(GT_3_TX_POLARITY), + .GT_TX_ELECIDLE(GT_3_TX_ELECIDLE), + .GT_TX_INHIBIT(GT_3_TX_INHIBIT), + .GT_TX_DIFFCTRL(GT_3_TX_DIFFCTRL), + .GT_TX_MAINCURSOR(GT_3_TX_MAINCURSOR), + .GT_TX_POSTCURSOR(GT_3_TX_POSTCURSOR), + .GT_TX_PRECURSOR(GT_3_TX_PRECURSOR), + .GT_RX_PD(GT_3_RX_PD), + .GT_RX_QPLL_SEL(GT_3_RX_QPLL_SEL), + .GT_RX_LPM_EN(GT_3_RX_LPM_EN), + .GT_RX_POLARITY(GT_3_RX_POLARITY) +) +gty_ch_3 ( + .xcvr_ctrl_clk(xcvr_ctrl_clk), + .xcvr_ctrl_rst(xcvr_ctrl_rst), + + // Common + .xcvr_gtpowergood_out(), + + // DRP + .drp_clk(drp_clk), + .drp_rst(drp_rst), + .drp_addr(drp_addr_reg), + .drp_di(drp_di_reg), + .drp_en(drp_en_gty_reg_3), + .drp_we(drp_we_reg), + .drp_do(drp_do_gty_3), + .drp_rdy(drp_rdy_gty_3), + + // PLL out + .xcvr_gtrefclk00_in(1'b0), + .xcvr_qpll0lock_out(), + .xcvr_qpll0clk_out(), + .xcvr_qpll0refclk_out(), + .xcvr_gtrefclk01_in(1'b0), + .xcvr_qpll1lock_out(), + .xcvr_qpll1clk_out(), + .xcvr_qpll1refclk_out(), + + // PLL in + .xcvr_qpll0lock_in(xcvr_qpll0lock), + .xcvr_qpll0clk_in(xcvr_qpll0clk), + .xcvr_qpll0refclk_in(xcvr_qpll0refclk), + .xcvr_qpll1lock_in(xcvr_qpll1lock), + .xcvr_qpll1clk_in(xcvr_qpll1clk), + .xcvr_qpll1refclk_in(xcvr_qpll1refclk), + + // Serial data + .xcvr_txp(xcvr_txp[2]), + .xcvr_txn(xcvr_txn[2]), + .xcvr_rxp(xcvr_rxp[2]), + .xcvr_rxn(xcvr_rxn[2]), + + // Parallel data + .gt_txoutclk(), + .gt_txusrclk(gt_txusrclk), + .gt_txusrclk2(gt_txusrclk2), + .tx_reset_in(gt_tx_reset[2]), + .tx_reset_done(gt_tx_reset_done[2]), + .gt_tx_reset_out(gt_tx_reset_out[2]), + .gt_tx_reset_done(), + .gt_txdata(gt_txdata[2*128 +: 128]), + .gt_txctrl0(gt_txctrl0[2*16 +: 16]), + .gt_txctrl1(gt_txctrl1[2*16 +: 16]), + .gt_rxoutclk(), + .gt_rxusrclk(gt_rxusrclk[2]), + .gt_rxusrclk2(gt_rxusrclk2[2]), + .rx_reset_in(gt_rx_reset[2]), + .rx_reset_done(gt_rx_reset_done[2]), + .gt_rx_reset_out(gt_rx_reset_out[2]), + .gt_rx_reset_done(), + .gt_rxdata(gt_rxdata[2*128 +: 128]), + .gt_rxctrl0(gt_rxctrl0[2*16 +: 16]), + .gt_rxctrl1(gt_rxctrl1[2*16 +: 16]) +); + +cmac_gty_ch_wrapper #( + .HAS_COMMON(0), + // GT + .GT_TX_PD(GT_4_TX_PD), + .GT_TX_QPLL_SEL(GT_4_TX_QPLL_SEL), + .GT_TX_POLARITY(GT_4_TX_POLARITY), + .GT_TX_ELECIDLE(GT_4_TX_ELECIDLE), + .GT_TX_INHIBIT(GT_4_TX_INHIBIT), + .GT_TX_DIFFCTRL(GT_4_TX_DIFFCTRL), + .GT_TX_MAINCURSOR(GT_4_TX_MAINCURSOR), + .GT_TX_POSTCURSOR(GT_4_TX_POSTCURSOR), + .GT_TX_PRECURSOR(GT_4_TX_PRECURSOR), + .GT_RX_PD(GT_4_RX_PD), + .GT_RX_QPLL_SEL(GT_4_RX_QPLL_SEL), + .GT_RX_LPM_EN(GT_4_RX_LPM_EN), + .GT_RX_POLARITY(GT_4_RX_POLARITY) +) +gty_ch_4 ( + .xcvr_ctrl_clk(xcvr_ctrl_clk), + .xcvr_ctrl_rst(xcvr_ctrl_rst), + + // Common + .xcvr_gtpowergood_out(), + + // DRP + .drp_clk(drp_clk), + .drp_rst(drp_rst), + .drp_addr(drp_addr_reg), + .drp_di(drp_di_reg), + .drp_en(drp_en_gty_reg_4), + .drp_we(drp_we_reg), + .drp_do(drp_do_gty_4), + .drp_rdy(drp_rdy_gty_4), + + // PLL out + .xcvr_gtrefclk00_in(1'b0), + .xcvr_qpll0lock_out(), + .xcvr_qpll0clk_out(), + .xcvr_qpll0refclk_out(), + .xcvr_gtrefclk01_in(1'b0), + .xcvr_qpll1lock_out(), + .xcvr_qpll1clk_out(), + .xcvr_qpll1refclk_out(), + + // PLL in + .xcvr_qpll0lock_in(xcvr_qpll0lock), + .xcvr_qpll0clk_in(xcvr_qpll0clk), + .xcvr_qpll0refclk_in(xcvr_qpll0refclk), + .xcvr_qpll1lock_in(xcvr_qpll1lock), + .xcvr_qpll1clk_in(xcvr_qpll1clk), + .xcvr_qpll1refclk_in(xcvr_qpll1refclk), + + // Serial data + .xcvr_txp(xcvr_txp[3]), + .xcvr_txn(xcvr_txn[3]), + .xcvr_rxp(xcvr_rxp[3]), + .xcvr_rxn(xcvr_rxn[3]), + + // Parallel data + .gt_txoutclk(), + .gt_txusrclk(gt_txusrclk), + .gt_txusrclk2(gt_txusrclk2), + .tx_reset_in(gt_tx_reset[3]), + .tx_reset_done(gt_tx_reset_done[3]), + .gt_tx_reset_out(gt_tx_reset_out[3]), + .gt_tx_reset_done(), + .gt_txdata(gt_txdata[3*128 +: 128]), + .gt_txctrl0(gt_txctrl0[3*16 +: 16]), + .gt_txctrl1(gt_txctrl1[3*16 +: 16]), + .gt_rxoutclk(), + .gt_rxusrclk(gt_rxusrclk[3]), + .gt_rxusrclk2(gt_rxusrclk2[3]), + .rx_reset_in(gt_rx_reset[3]), + .rx_reset_done(gt_rx_reset_done[3]), + .gt_rx_reset_out(gt_rx_reset_out[3]), + .gt_rx_reset_done(), + .gt_rxdata(gt_rxdata[3*128 +: 128]), + .gt_rxctrl0(gt_rxctrl0[3*16 +: 16]), + .gt_rxctrl1(gt_rxctrl1[3*16 +: 16]) +); + +wire [511:0] cmac_txdata; +wire [63:0] cmac_txctrl0; +wire [63:0] cmac_txctrl1; +wire [511:0] cmac_rxdata; +wire [63:0] cmac_rxctrl0; +wire [63:0] cmac_rxctrl1; + +generate + +genvar n; + +if (TX_SERDES_PIPELINE) begin + + (* shreg_extract = "no" *) + reg [511:0] cmac_txdata_pipe_reg[TX_SERDES_PIPELINE-1:0]; + (* shreg_extract = "no" *) + reg [63:0] cmac_txctrl0_pipe_reg[TX_SERDES_PIPELINE-1:0]; + (* shreg_extract = "no" *) + reg [63:0] cmac_txctrl1_pipe_reg[TX_SERDES_PIPELINE-1:0]; + + integer i; + + for (n = 0; n < 4; n = n + 1) begin + always @(posedge gt_txusrclk2) begin + cmac_txdata_pipe_reg[0][128*n +: 64] <= cmac_txdata[128*n +: 64]; + cmac_txctrl0_pipe_reg[0][16*n +: 8] <= cmac_txctrl0[16*n +: 8]; + cmac_txctrl1_pipe_reg[0][16*n +: 8] <= cmac_txctrl1[16*n +: 8]; + + for (i = 1; i < TX_SERDES_PIPELINE; i = i + 1) begin + cmac_txdata_pipe_reg[i][128*n +: 64] <= cmac_txdata_pipe_reg[i-1][128*n +: 64]; + cmac_txctrl0_pipe_reg[i][16*n +: 8] <= cmac_txctrl0_pipe_reg[i-1][16*n +: 8]; + cmac_txctrl1_pipe_reg[i][16*n +: 8] <= cmac_txctrl1_pipe_reg[i-1][16*n +: 8]; + end + end + end + + assign gt_txdata = cmac_txdata_pipe_reg[TX_SERDES_PIPELINE-1]; + assign gt_txctrl0 = cmac_txctrl0_pipe_reg[TX_SERDES_PIPELINE-1]; + assign gt_txctrl1 = cmac_txctrl1_pipe_reg[TX_SERDES_PIPELINE-1]; + +end else begin + + assign gt_txdata = cmac_txdata; + assign gt_txctrl0 = cmac_txctrl0; + assign gt_txctrl1 = cmac_txctrl1; + +end + +if (RX_SERDES_PIPELINE) begin + + (* shreg_extract = "no" *) + reg [511:0] cmac_rxdata_pipe_reg[RX_SERDES_PIPELINE-1:0]; + (* shreg_extract = "no" *) + reg [63:0] cmac_rxctrl0_pipe_reg[RX_SERDES_PIPELINE-1:0]; + (* shreg_extract = "no" *) + reg [63:0] cmac_rxctrl1_pipe_reg[RX_SERDES_PIPELINE-1:0]; + + integer i; + + for (n = 0; n < 4; n = n + 1) begin + always @(posedge gt_rxusrclk2[n]) begin + cmac_rxdata_pipe_reg[0][128*n +: 64] <= gt_rxdata[128*n +: 64]; + cmac_rxctrl0_pipe_reg[0][16*n +: 8] <= gt_rxctrl0[16*n +: 8]; + cmac_rxctrl1_pipe_reg[0][16*n +: 8] <= gt_rxctrl1[16*n +: 8]; + + for (i = 1; i < RX_SERDES_PIPELINE; i = i + 1) begin + cmac_rxdata_pipe_reg[i][128*n +: 64] <= cmac_rxdata_pipe_reg[i-1][128*n +: 64]; + cmac_rxctrl0_pipe_reg[i][16*n +: 8] <= cmac_rxctrl0_pipe_reg[i-1][16*n +: 8]; + cmac_rxctrl1_pipe_reg[i][16*n +: 8] <= cmac_rxctrl1_pipe_reg[i-1][16*n +: 8]; + end + end + end + + assign cmac_rxdata = cmac_rxdata_pipe_reg[RX_SERDES_PIPELINE-1]; + assign cmac_rxctrl0 = cmac_rxctrl0_pipe_reg[RX_SERDES_PIPELINE-1]; + assign cmac_rxctrl1 = cmac_rxctrl1_pipe_reg[RX_SERDES_PIPELINE-1]; + +end else begin + + assign cmac_rxdata = gt_rxdata; + assign cmac_rxctrl0 = gt_rxctrl0; + assign cmac_rxctrl1 = gt_rxctrl1; + +end + +endgenerate + +wire [AXIS_DATA_WIDTH-1:0] cmac_tx_axis_tdata; +wire [AXIS_KEEP_WIDTH-1:0] cmac_tx_axis_tkeep; +wire cmac_tx_axis_tvalid; +wire cmac_tx_axis_tready; +wire cmac_tx_axis_tlast; +wire [16+1-1:0] cmac_tx_axis_tuser; + +wire [AXIS_DATA_WIDTH-1:0] cmac_rx_axis_tdata; +wire [AXIS_KEEP_WIDTH-1:0] cmac_rx_axis_tkeep; +wire cmac_rx_axis_tvalid; +wire cmac_rx_axis_tlast; +wire cmac_rx_axis_tuser; +wire [79:0] cmac_rx_ptp_ts; + +cmac_pad #( + .DATA_WIDTH(AXIS_DATA_WIDTH), + .KEEP_WIDTH(AXIS_KEEP_WIDTH), + .USER_WIDTH(16+1) +) +cmac_pad_inst ( + .clk(tx_clk), + .rst(tx_rst), + + .s_axis_tdata(tx_axis_tdata), + .s_axis_tkeep(tx_axis_tkeep), + .s_axis_tvalid(tx_axis_tvalid), + .s_axis_tready(tx_axis_tready), + .s_axis_tlast(tx_axis_tlast), + .s_axis_tuser(tx_axis_tuser), + + .m_axis_tdata(cmac_tx_axis_tdata), + .m_axis_tkeep(cmac_tx_axis_tkeep), + .m_axis_tvalid(cmac_tx_axis_tvalid), + .m_axis_tready(cmac_tx_axis_tready), + .m_axis_tlast(cmac_tx_axis_tlast), + .m_axis_tuser(cmac_tx_axis_tuser) +); + +mac_ts_insert #( + .PTP_TS_WIDTH(80), + .DATA_WIDTH(AXIS_DATA_WIDTH), + .KEEP_WIDTH(AXIS_KEEP_WIDTH), + .S_USER_WIDTH(1), + .M_USER_WIDTH(80+1) +) +mac_ts_insert_inst ( + .clk(rx_clk), + .rst(rx_rst), + + .ptp_ts(cmac_rx_ptp_ts), + + .s_axis_tdata(cmac_rx_axis_tdata), + .s_axis_tkeep(cmac_rx_axis_tkeep), + .s_axis_tvalid(cmac_rx_axis_tvalid), + .s_axis_tready(), + .s_axis_tlast(cmac_rx_axis_tlast), + .s_axis_tuser(cmac_rx_axis_tuser), + + .m_axis_tdata(rx_axis_tdata), + .m_axis_tkeep(rx_axis_tkeep), + .m_axis_tvalid(rx_axis_tvalid), + .m_axis_tready(1'b1), + .m_axis_tlast(rx_axis_tlast), + .m_axis_tuser(rx_axis_tuser) +); + +cmac_usplus cmac_inst ( + .txdata_in(cmac_txdata), + .txctrl0_in(cmac_txctrl0), + .txctrl1_in(cmac_txctrl1), + .rxdata_out(cmac_rxdata), + .rxctrl0_out(cmac_rxctrl0), + .rxctrl1_out(cmac_rxctrl1), + + .ctl_tx_rsfec_enable(cmac_ctl_tx_rsfec_enable_reg), + .ctl_rx_rsfec_enable(cmac_ctl_rx_rsfec_enable_reg), + .ctl_rsfec_ieee_error_indication_mode(cmac_ctl_rsfec_ieee_error_indication_mode_reg), + .ctl_rx_rsfec_enable_correction(cmac_ctl_rx_rsfec_enable_correction_reg), + .ctl_rx_rsfec_enable_indication(cmac_ctl_rx_rsfec_enable_indication_reg), + .stat_rx_rsfec_am_lock0(cmac_stat_rx_rsfec_am_lock[0]), + .stat_rx_rsfec_am_lock1(cmac_stat_rx_rsfec_am_lock[1]), + .stat_rx_rsfec_am_lock2(cmac_stat_rx_rsfec_am_lock[2]), + .stat_rx_rsfec_am_lock3(cmac_stat_rx_rsfec_am_lock[3]), + .stat_rx_rsfec_err_count0_inc(cmac_stat_rx_rsfec_err_count_inc[3*0 +: 3]), + .stat_rx_rsfec_err_count1_inc(cmac_stat_rx_rsfec_err_count_inc[3*1 +: 3]), + .stat_rx_rsfec_err_count2_inc(cmac_stat_rx_rsfec_err_count_inc[3*2 +: 3]), + .stat_rx_rsfec_err_count3_inc(cmac_stat_rx_rsfec_err_count_inc[3*3 +: 3]), + .stat_rx_rsfec_hi_ser(cmac_stat_rx_rsfec_hi_ser), + .stat_rx_rsfec_lane_alignment_status(cmac_stat_rx_rsfec_lane_alignment_status), + .stat_rx_rsfec_lane_fill_0(cmac_stat_rx_rsfec_lane_fill[14*0 +: 14]), + .stat_rx_rsfec_lane_fill_1(cmac_stat_rx_rsfec_lane_fill[14*1 +: 14]), + .stat_rx_rsfec_lane_fill_2(cmac_stat_rx_rsfec_lane_fill[14*2 +: 14]), + .stat_rx_rsfec_lane_fill_3(cmac_stat_rx_rsfec_lane_fill[14*3 +: 14]), + .stat_rx_rsfec_lane_mapping(cmac_stat_rx_rsfec_lane_mapping), + .stat_rx_rsfec_cw_inc(cmac_stat_rx_rsfec_cw_inc), + .stat_rx_rsfec_corrected_cw_inc(cmac_stat_rx_rsfec_corrected_cw_inc), + .stat_rx_rsfec_uncorrected_cw_inc(cmac_stat_rx_rsfec_uncorrected_cw_inc), + + .rx_axis_tvalid(cmac_rx_axis_tvalid), + .rx_axis_tdata(cmac_rx_axis_tdata), + .rx_axis_tlast(cmac_rx_axis_tlast), + .rx_axis_tkeep(cmac_rx_axis_tkeep), + .rx_axis_tuser(cmac_rx_axis_tuser), + + .rx_otn_bip8_0(), + .rx_otn_bip8_1(), + .rx_otn_bip8_2(), + .rx_otn_bip8_3(), + .rx_otn_bip8_4(), + .rx_otn_data_0(), + .rx_otn_data_1(), + .rx_otn_data_2(), + .rx_otn_data_3(), + .rx_otn_data_4(), + .rx_otn_ena(), + .rx_otn_lane0(), + .rx_otn_vlmarker(), + + .rx_preambleout(), + + .rx_lane_aligner_fill_0(cmac_rx_lane_aligner_fill[7*0 +: 7]), + .rx_lane_aligner_fill_1(cmac_rx_lane_aligner_fill[7*1 +: 7]), + .rx_lane_aligner_fill_2(cmac_rx_lane_aligner_fill[7*2 +: 7]), + .rx_lane_aligner_fill_3(cmac_rx_lane_aligner_fill[7*3 +: 7]), + .rx_lane_aligner_fill_4(cmac_rx_lane_aligner_fill[7*4 +: 7]), + .rx_lane_aligner_fill_5(cmac_rx_lane_aligner_fill[7*5 +: 7]), + .rx_lane_aligner_fill_6(cmac_rx_lane_aligner_fill[7*6 +: 7]), + .rx_lane_aligner_fill_7(cmac_rx_lane_aligner_fill[7*7 +: 7]), + .rx_lane_aligner_fill_8(cmac_rx_lane_aligner_fill[7*8 +: 7]), + .rx_lane_aligner_fill_9(cmac_rx_lane_aligner_fill[7*9 +: 7]), + .rx_lane_aligner_fill_10(cmac_rx_lane_aligner_fill[7*10 +: 7]), + .rx_lane_aligner_fill_11(cmac_rx_lane_aligner_fill[7*11 +: 7]), + .rx_lane_aligner_fill_12(cmac_rx_lane_aligner_fill[7*12 +: 7]), + .rx_lane_aligner_fill_13(cmac_rx_lane_aligner_fill[7*13 +: 7]), + .rx_lane_aligner_fill_14(cmac_rx_lane_aligner_fill[7*14 +: 7]), + .rx_lane_aligner_fill_15(cmac_rx_lane_aligner_fill[7*15 +: 7]), + .rx_lane_aligner_fill_16(cmac_rx_lane_aligner_fill[7*16 +: 7]), + .rx_lane_aligner_fill_17(cmac_rx_lane_aligner_fill[7*17 +: 7]), + .rx_lane_aligner_fill_18(cmac_rx_lane_aligner_fill[7*18 +: 7]), + .rx_lane_aligner_fill_19(cmac_rx_lane_aligner_fill[7*19 +: 7]), + + .rx_ptp_tstamp_out(cmac_rx_ptp_ts), + .rx_ptp_pcslane_out(), + .ctl_rx_systemtimerin(rx_ptp_time), + + .stat_rx_aligned(cmac_stat_rx_aligned), + .stat_rx_aligned_err(cmac_stat_rx_aligned_err), + .stat_rx_bad_code(cmac_stat_rx_bad_code), + .stat_rx_bad_fcs(cmac_stat_rx_bad_fcs), + .stat_rx_bad_preamble(cmac_stat_rx_bad_preamble), + .stat_rx_bad_sfd(cmac_stat_rx_bad_sfd), + .stat_rx_bip_err_0(cmac_stat_rx_bip_err[0]), + .stat_rx_bip_err_1(cmac_stat_rx_bip_err[1]), + .stat_rx_bip_err_2(cmac_stat_rx_bip_err[2]), + .stat_rx_bip_err_3(cmac_stat_rx_bip_err[3]), + .stat_rx_bip_err_4(cmac_stat_rx_bip_err[4]), + .stat_rx_bip_err_5(cmac_stat_rx_bip_err[5]), + .stat_rx_bip_err_6(cmac_stat_rx_bip_err[6]), + .stat_rx_bip_err_7(cmac_stat_rx_bip_err[7]), + .stat_rx_bip_err_8(cmac_stat_rx_bip_err[8]), + .stat_rx_bip_err_9(cmac_stat_rx_bip_err[9]), + .stat_rx_bip_err_10(cmac_stat_rx_bip_err[10]), + .stat_rx_bip_err_11(cmac_stat_rx_bip_err[11]), + .stat_rx_bip_err_12(cmac_stat_rx_bip_err[12]), + .stat_rx_bip_err_13(cmac_stat_rx_bip_err[13]), + .stat_rx_bip_err_14(cmac_stat_rx_bip_err[14]), + .stat_rx_bip_err_15(cmac_stat_rx_bip_err[15]), + .stat_rx_bip_err_16(cmac_stat_rx_bip_err[16]), + .stat_rx_bip_err_17(cmac_stat_rx_bip_err[17]), + .stat_rx_bip_err_18(cmac_stat_rx_bip_err[18]), + .stat_rx_bip_err_19(cmac_stat_rx_bip_err[19]), + .stat_rx_block_lock(cmac_stat_rx_block_lock), + .stat_rx_broadcast(cmac_stat_rx_broadcast), + .stat_rx_fragment(cmac_stat_rx_fragment), + .stat_rx_framing_err_0(cmac_stat_rx_framing_err[2*0 +: 2]), + .stat_rx_framing_err_1(cmac_stat_rx_framing_err[2*1 +: 2]), + .stat_rx_framing_err_2(cmac_stat_rx_framing_err[2*2 +: 2]), + .stat_rx_framing_err_3(cmac_stat_rx_framing_err[2*3 +: 2]), + .stat_rx_framing_err_4(cmac_stat_rx_framing_err[2*4 +: 2]), + .stat_rx_framing_err_5(cmac_stat_rx_framing_err[2*5 +: 2]), + .stat_rx_framing_err_6(cmac_stat_rx_framing_err[2*6 +: 2]), + .stat_rx_framing_err_7(cmac_stat_rx_framing_err[2*7 +: 2]), + .stat_rx_framing_err_8(cmac_stat_rx_framing_err[2*8 +: 2]), + .stat_rx_framing_err_9(cmac_stat_rx_framing_err[2*9 +: 2]), + .stat_rx_framing_err_10(cmac_stat_rx_framing_err[2*10 +: 2]), + .stat_rx_framing_err_11(cmac_stat_rx_framing_err[2*11 +: 2]), + .stat_rx_framing_err_12(cmac_stat_rx_framing_err[2*12 +: 2]), + .stat_rx_framing_err_13(cmac_stat_rx_framing_err[2*13 +: 2]), + .stat_rx_framing_err_14(cmac_stat_rx_framing_err[2*14 +: 2]), + .stat_rx_framing_err_15(cmac_stat_rx_framing_err[2*15 +: 2]), + .stat_rx_framing_err_16(cmac_stat_rx_framing_err[2*16 +: 2]), + .stat_rx_framing_err_17(cmac_stat_rx_framing_err[2*17 +: 2]), + .stat_rx_framing_err_18(cmac_stat_rx_framing_err[2*18 +: 2]), + .stat_rx_framing_err_19(cmac_stat_rx_framing_err[2*19 +: 2]), + .stat_rx_framing_err_valid_0(cmac_stat_rx_framing_err_valid[0]), + .stat_rx_framing_err_valid_1(cmac_stat_rx_framing_err_valid[1]), + .stat_rx_framing_err_valid_2(cmac_stat_rx_framing_err_valid[2]), + .stat_rx_framing_err_valid_3(cmac_stat_rx_framing_err_valid[3]), + .stat_rx_framing_err_valid_4(cmac_stat_rx_framing_err_valid[4]), + .stat_rx_framing_err_valid_5(cmac_stat_rx_framing_err_valid[5]), + .stat_rx_framing_err_valid_6(cmac_stat_rx_framing_err_valid[6]), + .stat_rx_framing_err_valid_7(cmac_stat_rx_framing_err_valid[7]), + .stat_rx_framing_err_valid_8(cmac_stat_rx_framing_err_valid[8]), + .stat_rx_framing_err_valid_9(cmac_stat_rx_framing_err_valid[9]), + .stat_rx_framing_err_valid_10(cmac_stat_rx_framing_err_valid[10]), + .stat_rx_framing_err_valid_11(cmac_stat_rx_framing_err_valid[11]), + .stat_rx_framing_err_valid_12(cmac_stat_rx_framing_err_valid[12]), + .stat_rx_framing_err_valid_13(cmac_stat_rx_framing_err_valid[13]), + .stat_rx_framing_err_valid_14(cmac_stat_rx_framing_err_valid[14]), + .stat_rx_framing_err_valid_15(cmac_stat_rx_framing_err_valid[15]), + .stat_rx_framing_err_valid_16(cmac_stat_rx_framing_err_valid[16]), + .stat_rx_framing_err_valid_17(cmac_stat_rx_framing_err_valid[17]), + .stat_rx_framing_err_valid_18(cmac_stat_rx_framing_err_valid[18]), + .stat_rx_framing_err_valid_19(cmac_stat_rx_framing_err_valid[19]), + .stat_rx_got_signal_os(cmac_stat_rx_got_signal_os), + .stat_rx_hi_ber(cmac_stat_rx_hi_ber), + .stat_rx_inrangeerr(cmac_stat_rx_inrangeerr), + .stat_rx_internal_local_fault(cmac_stat_rx_internal_local_fault), + .stat_rx_jabber(cmac_stat_rx_jabber), + .stat_rx_local_fault(cmac_stat_rx_local_fault), + .stat_rx_mf_err(cmac_stat_rx_mf_err), + .stat_rx_mf_len_err(cmac_stat_rx_mf_len_err), + .stat_rx_mf_repeat_err(cmac_stat_rx_mf_repeat_err), + .stat_rx_misaligned(cmac_stat_rx_misaligned), + .stat_rx_multicast(cmac_stat_rx_multicast), + .stat_rx_oversize(cmac_stat_rx_oversize), + .stat_rx_packet_64_bytes(cmac_stat_rx_packet_64_bytes), + .stat_rx_packet_65_127_bytes(cmac_stat_rx_packet_65_127_bytes), + .stat_rx_packet_128_255_bytes(cmac_stat_rx_packet_128_255_bytes), + .stat_rx_packet_256_511_bytes(cmac_stat_rx_packet_256_511_bytes), + .stat_rx_packet_512_1023_bytes(cmac_stat_rx_packet_512_1023_bytes), + .stat_rx_packet_1024_1518_bytes(cmac_stat_rx_packet_1024_1518_bytes), + .stat_rx_packet_1519_1522_bytes(cmac_stat_rx_packet_1519_1522_bytes), + .stat_rx_packet_1523_1548_bytes(cmac_stat_rx_packet_1523_1548_bytes), + .stat_rx_packet_1549_2047_bytes(cmac_stat_rx_packet_1549_2047_bytes), + .stat_rx_packet_2048_4095_bytes(cmac_stat_rx_packet_2048_4095_bytes), + .stat_rx_packet_4096_8191_bytes(cmac_stat_rx_packet_4096_8191_bytes), + .stat_rx_packet_8192_9215_bytes(cmac_stat_rx_packet_8192_9215_bytes), + .stat_rx_packet_bad_fcs(cmac_stat_rx_packet_bad_fcs), + .stat_rx_packet_large(cmac_stat_rx_packet_large), + .stat_rx_packet_small(cmac_stat_rx_packet_small), + + .ctl_rx_enable(cmac_ctl_rx_enable_reg), + .ctl_rx_force_resync(cmac_ctl_rx_force_resync_reg), + .ctl_rx_test_pattern(cmac_ctl_rx_test_pattern_reg), + + .rx_clk(rx_clk), + + .stat_rx_received_local_fault(cmac_stat_rx_received_local_fault), + .stat_rx_remote_fault(cmac_stat_rx_remote_fault), + .stat_rx_status(cmac_stat_rx_status), + .stat_rx_stomped_fcs(cmac_stat_rx_stomped_fcs), + .stat_rx_synced(cmac_stat_rx_synced), + .stat_rx_synced_err(cmac_stat_rx_synced_err), + .stat_rx_test_pattern_mismatch(cmac_stat_rx_test_pattern_mismatch), + .stat_rx_toolong(cmac_stat_rx_toolong), + .stat_rx_total_bytes(cmac_stat_rx_total_bytes), + .stat_rx_total_good_bytes(cmac_stat_rx_total_good_bytes), + .stat_rx_total_good_packets(cmac_stat_rx_total_good_packets), + .stat_rx_total_packets(cmac_stat_rx_total_packets), + .stat_rx_truncated(cmac_stat_rx_truncated), + .stat_rx_undersize(cmac_stat_rx_undersize), + .stat_rx_unicast(cmac_stat_rx_unicast), + .stat_rx_vlan(cmac_stat_rx_vlan), + .stat_rx_pcsl_demuxed(cmac_stat_rx_pcsl_demuxed), + .stat_rx_pcsl_number_0(cmac_stat_rx_pcsl_number[5*0 +: 5]), + .stat_rx_pcsl_number_1(cmac_stat_rx_pcsl_number[5*1 +: 5]), + .stat_rx_pcsl_number_2(cmac_stat_rx_pcsl_number[5*2 +: 5]), + .stat_rx_pcsl_number_3(cmac_stat_rx_pcsl_number[5*3 +: 5]), + .stat_rx_pcsl_number_4(cmac_stat_rx_pcsl_number[5*4 +: 5]), + .stat_rx_pcsl_number_5(cmac_stat_rx_pcsl_number[5*5 +: 5]), + .stat_rx_pcsl_number_6(cmac_stat_rx_pcsl_number[5*6 +: 5]), + .stat_rx_pcsl_number_7(cmac_stat_rx_pcsl_number[5*7 +: 5]), + .stat_rx_pcsl_number_8(cmac_stat_rx_pcsl_number[5*8 +: 5]), + .stat_rx_pcsl_number_9(cmac_stat_rx_pcsl_number[5*9 +: 5]), + .stat_rx_pcsl_number_10(cmac_stat_rx_pcsl_number[5*10 +: 5]), + .stat_rx_pcsl_number_11(cmac_stat_rx_pcsl_number[5*11 +: 5]), + .stat_rx_pcsl_number_12(cmac_stat_rx_pcsl_number[5*12 +: 5]), + .stat_rx_pcsl_number_13(cmac_stat_rx_pcsl_number[5*13 +: 5]), + .stat_rx_pcsl_number_14(cmac_stat_rx_pcsl_number[5*14 +: 5]), + .stat_rx_pcsl_number_15(cmac_stat_rx_pcsl_number[5*15 +: 5]), + .stat_rx_pcsl_number_16(cmac_stat_rx_pcsl_number[5*16 +: 5]), + .stat_rx_pcsl_number_17(cmac_stat_rx_pcsl_number[5*17 +: 5]), + .stat_rx_pcsl_number_18(cmac_stat_rx_pcsl_number[5*18 +: 5]), + .stat_rx_pcsl_number_19(cmac_stat_rx_pcsl_number[5*19 +: 5]), + + .ctl_tx_systemtimerin(tx_ptp_time), + .stat_tx_ptp_fifo_read_error(cmac_stat_tx_ptp_fifo_read_error), + .stat_tx_ptp_fifo_write_error(cmac_stat_tx_ptp_fifo_write_error), + .tx_ptp_tstamp_valid_out(tx_ptp_ts_valid), + .tx_ptp_pcslane_out(), + .tx_ptp_tstamp_tag_out(tx_ptp_ts_tag), + .tx_ptp_tstamp_out(tx_ptp_ts), + .tx_ptp_1588op_in(2'b10), + .tx_ptp_tag_field_in(cmac_tx_axis_tuser[16:1]), + + .stat_tx_bad_fcs(cmac_stat_tx_bad_fcs), + .stat_tx_broadcast(cmac_stat_tx_broadcast), + .stat_tx_frame_error(cmac_stat_tx_frame_error), + .stat_tx_local_fault(cmac_stat_tx_local_fault), + .stat_tx_multicast(cmac_stat_tx_multicast), + .stat_tx_packet_64_bytes(cmac_stat_tx_packet_64_bytes), + .stat_tx_packet_65_127_bytes(cmac_stat_tx_packet_65_127_bytes), + .stat_tx_packet_128_255_bytes(cmac_stat_tx_packet_128_255_bytes), + .stat_tx_packet_256_511_bytes(cmac_stat_tx_packet_256_511_bytes), + .stat_tx_packet_512_1023_bytes(cmac_stat_tx_packet_512_1023_bytes), + .stat_tx_packet_1024_1518_bytes(cmac_stat_tx_packet_1024_1518_bytes), + .stat_tx_packet_1519_1522_bytes(cmac_stat_tx_packet_1519_1522_bytes), + .stat_tx_packet_1523_1548_bytes(cmac_stat_tx_packet_1523_1548_bytes), + .stat_tx_packet_1549_2047_bytes(cmac_stat_tx_packet_1549_2047_bytes), + .stat_tx_packet_2048_4095_bytes(cmac_stat_tx_packet_2048_4095_bytes), + .stat_tx_packet_4096_8191_bytes(cmac_stat_tx_packet_4096_8191_bytes), + .stat_tx_packet_8192_9215_bytes(cmac_stat_tx_packet_8192_9215_bytes), + .stat_tx_packet_large(cmac_stat_tx_packet_large), + .stat_tx_packet_small(cmac_stat_tx_packet_small), + .stat_tx_total_bytes(cmac_stat_tx_total_bytes), + .stat_tx_total_good_bytes(cmac_stat_tx_total_good_bytes), + .stat_tx_total_good_packets(cmac_stat_tx_total_good_packets), + .stat_tx_total_packets(cmac_stat_tx_total_packets), + .stat_tx_unicast(cmac_stat_tx_unicast), + .stat_tx_vlan(cmac_stat_tx_vlan), + + .ctl_tx_enable(cmac_ctl_tx_enable_reg), + .ctl_tx_send_idle(cmac_ctl_tx_send_idle_reg), + .ctl_tx_send_rfi(cmac_ctl_tx_send_rfi_reg), + .ctl_tx_send_lfi(cmac_ctl_tx_send_lfi_reg), + .ctl_tx_test_pattern(cmac_ctl_tx_test_pattern_reg), + + .tx_clk(tx_clk), + + .tx_axis_tready(cmac_tx_axis_tready), + .tx_axis_tvalid(cmac_tx_axis_tvalid), + .tx_axis_tdata(cmac_tx_axis_tdata), + .tx_axis_tlast(cmac_tx_axis_tlast), + .tx_axis_tkeep(cmac_tx_axis_tkeep), + .tx_axis_tuser(cmac_tx_axis_tuser[0]), + + .tx_ovfout(), + .tx_unfout(), + .tx_preamblein(56'd0), + + .tx_reset_done(tx_rst), + .rx_reset_done(rx_rst), + + .rx_serdes_reset_done({6'h3f, ~gt_rx_reset_done}), + .rx_serdes_clk_in({6'd0, gt_rxusrclk2}), + + .drp_clk(drp_clk), + .drp_addr(drp_addr_reg), + .drp_di(drp_di_reg), + .drp_en(drp_en_cmac_reg), + .drp_we(drp_we_reg), + .drp_do(drp_do_cmac), + .drp_rdy(drp_rdy_cmac) +); + +endmodule + +`resetall diff --git a/fpga/common/syn/vivado/cmac_gty_ch_wrapper.tcl b/fpga/common/syn/vivado/cmac_gty_ch_wrapper.tcl new file mode 100644 index 000000000..739e08659 --- /dev/null +++ b/fpga/common/syn/vivado/cmac_gty_ch_wrapper.tcl @@ -0,0 +1,79 @@ +# Copyright 2022, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS +# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +# OF SUCH DAMAGE. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +# GTY transceiver and PHY wrapper timing constraints + +foreach inst [get_cells -hier -filter {(ORIG_REF_NAME == cmac_gty_ch_wrapper || REF_NAME == cmac_gty_ch_wrapper)}] { + puts "Inserting timing constraints for cmac_gty_ch_wrapper instance $inst" + + proc constrain_sync_chain {inst driver args} { + set sync_ffs [get_cells -hier [concat $driver $args] -filter "PARENT == $inst"] + + if {[llength $sync_ffs]} { + set_property ASYNC_REG TRUE $sync_ffs + + set src_clk [get_clocks -of_objects [get_pins "$inst/$driver/C"]] + + set_max_delay -from [get_cells "$inst/$driver"] -to [get_cells "$inst/[lindex $args 0]"] -datapath_only [get_property -min PERIOD $src_clk] + } + } + + # PLL lock + set_property -quiet ASYNC_REG TRUE [get_cells -quiet -hier -regexp ".*/qpll\[01\]_lock_sync_\[12\]_reg_reg" -filter "PARENT == $inst"] + + # reset synchronization + constrain_sync_chain $inst "gt_tx_reset_done_reg_reg" "gt_tx_reset_done_sync_1_reg_reg" "gt_tx_reset_done_sync_2_reg_reg" + set_property -quiet ASYNC_REG TRUE [get_cells -quiet -hier -regexp ".*/gt_rx_pma_reset_done_sync_\[12\]_reg_reg" -filter "PARENT == $inst"] + set_property -quiet ASYNC_REG TRUE [get_cells -quiet -hier -regexp ".*/gt_rx_prgdiv_reset_done_sync_\[12\]_reg_reg" -filter "PARENT == $inst"] + constrain_sync_chain $inst "gt_userclk_tx_active_reg_reg" "gt_userclk_tx_active_sync_1_reg_reg" "gt_userclk_tx_active_sync_2_reg_reg" + constrain_sync_chain $inst "gt_rx_reset_done_reg_reg" "gt_rx_reset_done_sync_1_reg_reg" "gt_rx_reset_done_sync_2_reg_reg" + set_property -quiet ASYNC_REG TRUE [get_cells -quiet -hier -regexp ".*/gt_rx_pma_reset_done_sync_\[12\]_reg_reg" -filter "PARENT == $inst"] + set_property -quiet ASYNC_REG TRUE [get_cells -quiet -hier -regexp ".*/gt_rx_prgdiv_reset_done_sync_\[12\]_reg_reg" -filter "PARENT == $inst"] + constrain_sync_chain $inst "gt_userclk_rx_active_reg_reg" "gt_userclk_rx_active_sync_1_reg_reg" "gt_userclk_rx_active_sync_2_reg_reg" + set_property -quiet ASYNC_REG TRUE [get_cells -quiet -hier -regexp ".*/gt_rxcdrlock_sync_\[12\]_reg_reg" -filter "PARENT == $inst"] + + set_false_path -to [get_pins "$inst/gt_userclk_tx_active_reg_reg/CLR"] + set_false_path -to [get_pins "$inst/gt_userclk_rx_active_reg_reg/CLR"] + + # TX + constrain_sync_chain $inst "gt_txprbssel_drp_reg_reg[*]" "gt_txprbssel_sync_reg_reg[*]" + constrain_sync_chain $inst "gt_txprbsforceerr_drp_reg_reg" "gt_txprbsforceerr_sync_1_reg_reg" "gt_txprbsforceerr_sync_2_reg_reg" + constrain_sync_chain $inst "gt_txpolarity_drp_reg_reg" "gt_txpolarity_sync_reg_reg" + constrain_sync_chain $inst "gt_txinhibit_drp_reg_reg" "gt_txinhibit_sync_reg_reg" + set_false_path -from [get_cells "$inst/gt_tx_pd_reg_reg"] + set_false_path -from [get_cells "$inst/gt_txelecidle_reg_reg"] + + # RX + constrain_sync_chain $inst "gt_rxpolarity_drp_reg_reg" "gt_rxpolarity_sync_reg_reg" + constrain_sync_chain $inst "gt_rxprbssel_drp_reg_reg[*]" "gt_rxprbssel_sync_reg_reg[*]" + constrain_sync_chain $inst "gt_rxprbscntreset_drp_reg_reg" "gt_rxprbscntreset_sync_1_reg_reg" "gt_rxprbscntreset_sync_2_reg_reg" + constrain_sync_chain $inst "gt_rxprbserr_sync_1_reg_reg" "gt_rxprbserr_sync_2_reg_reg" "gt_rxprbserr_sync_3_reg_reg" + constrain_sync_chain $inst "gt_rxprbserr_sync_3_reg_reg" "gt_rxprbserr_sync_4_reg_reg" "gt_rxprbserr_sync_5_reg_reg" + constrain_sync_chain $inst "gt_rxprbslocked_reg_reg" "gt_rxprbslocked_sync_1_reg_reg" "gt_rxprbslocked_sync_2_reg_reg" +} diff --git a/fpga/common/syn/vivado/cmac_gty_wrapper.tcl b/fpga/common/syn/vivado/cmac_gty_wrapper.tcl new file mode 100644 index 000000000..8ded06082 --- /dev/null +++ b/fpga/common/syn/vivado/cmac_gty_wrapper.tcl @@ -0,0 +1,117 @@ +# Copyright 2022, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS +# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +# OF SUCH DAMAGE. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +# GTY transceiver and PHY wrapper timing constraints + +foreach inst [get_cells -hier -filter {(ORIG_REF_NAME == cmac_gty_wrapper || REF_NAME == cmac_gty_wrapper)}] { + puts "Inserting timing constraints for cmac_gty_wrapper instance $inst" + + proc constrain_sync_chain {inst driver args} { + set sync_ffs [get_cells -hier [concat $driver $args] -filter "PARENT == $inst"] + + if {[llength $sync_ffs]} { + set_property ASYNC_REG TRUE $sync_ffs + + set src_clk [get_clocks -of_objects [get_pins "$inst/$driver/C"]] + + set_max_delay -from [get_cells "$inst/$driver"] -to [get_cells "$inst/[lindex $args 0]"] -datapath_only [get_property -min PERIOD $src_clk] + } + } + + proc constrain_sync_chain_async {inst driver args} { + set sync_ffs [get_cells -hier [concat $driver $args] -filter "PARENT == $inst"] + + if {[llength $sync_ffs]} { + set_property ASYNC_REG TRUE $sync_ffs + + set_false_path -to [get_pins "$inst/$driver/D"] + } + } + + # False paths to async input pins on CMAC + set cmac_cells [get_cells -hierarchical -filter "PARENT == $inst/cmac_inst/inst/i_cmac_usplus_top"] + set_false_path -to [get_pins -of $cmac_cells -filter "REF_PIN_NAME =~ RX_RESET"] + set_false_path -to [get_pins -of $cmac_cells -filter "REF_PIN_NAME =~ TX_RESET"] + set_false_path -to [get_pins -of $cmac_cells -filter "REF_PIN_NAME =~ RX_SERDES_RESET*"] + set_false_path -to [get_pins -of $cmac_cells -filter "REF_PIN_NAME =~ CTL_RX_ENABLE_PPP"] + set_false_path -to [get_pins -of $cmac_cells -filter "REF_PIN_NAME =~ CTL_RX_CHECK_SA_PPP"] + set_false_path -to [get_pins -of $cmac_cells -filter "REF_PIN_NAME =~ CTL_RX_CHECK_OPCODE_PPP"] + set_false_path -to [get_pins -of $cmac_cells -filter "REF_PIN_NAME =~ CTL_RX_RSFEC_ENABLE"] + set_false_path -to [get_pins -of $cmac_cells -filter "REF_PIN_NAME =~ CTL_RX_FORCE_RESYNC"] + + # Control and status connections to DRP registers + constrain_sync_chain_async $inst "tx_rst_sync_1_reg_reg" "tx_rst_sync_2_reg_reg" + constrain_sync_chain_async $inst "rx_rst_sync_1_reg_reg" "rx_rst_sync_2_reg_reg" + + constrain_sync_chain $inst "cmac_ctl_tx_rsfec_enable_drp_reg_reg" "cmac_ctl_tx_rsfec_enable_sync_reg_reg" "cmac_ctl_tx_rsfec_enable_reg_reg" + constrain_sync_chain $inst "cmac_ctl_rx_rsfec_enable_drp_reg_reg" "cmac_ctl_rx_rsfec_enable_sync_reg_reg" "cmac_ctl_rx_rsfec_enable_reg_reg" + constrain_sync_chain $inst "cmac_ctl_rsfec_ieee_error_indication_mode_drp_reg_reg" "cmac_ctl_rsfec_ieee_error_indication_mode_sync_reg_reg" "cmac_ctl_rsfec_ieee_error_indication_mode_reg_reg" + constrain_sync_chain $inst "cmac_ctl_rx_rsfec_enable_correction_drp_reg_reg" "cmac_ctl_rx_rsfec_enable_correction_sync_reg_reg" "cmac_ctl_rx_rsfec_enable_correction_reg_reg" + constrain_sync_chain $inst "cmac_ctl_rx_rsfec_enable_indication_drp_reg_reg" "cmac_ctl_rx_rsfec_enable_indication_sync_reg_reg" "cmac_ctl_rx_rsfec_enable_indication_reg_reg" + + constrain_sync_chain_async $inst "cmac_stat_rx_rsfec_am_lock_sync_1_reg_reg[*]" "cmac_stat_rx_rsfec_am_lock_sync_2_reg_reg[*]" + constrain_sync_chain_async $inst "cmac_stat_rx_rsfec_hi_ser_sync_1_reg_reg" "cmac_stat_rx_rsfec_hi_ser_sync_2_reg_reg" + constrain_sync_chain_async $inst "cmac_stat_rx_rsfec_lane_alignment_status_sync_1_reg_reg" "cmac_stat_rx_rsfec_lane_alignment_status_sync_2_reg_reg" + constrain_sync_chain_async $inst "cmac_stat_rx_rsfec_lane_fill_sync_1_reg_reg[*]" "cmac_stat_rx_rsfec_lane_fill_sync_2_reg_reg[*]" + constrain_sync_chain_async $inst "cmac_stat_rx_rsfec_lane_mapping_sync_1_reg_reg[*]" "cmac_stat_rx_rsfec_lane_mapping_sync_2_reg_reg[*]" + + constrain_sync_chain_async $inst "cmac_rx_lane_aligner_fill_sync_1_reg_reg[*]" "cmac_rx_lane_aligner_fill_sync_2_reg_reg[*]" + + constrain_sync_chain_async $inst "cmac_stat_rx_aligned_sync_1_reg_reg" "cmac_stat_rx_aligned_sync_2_reg_reg" + constrain_sync_chain_async $inst "cmac_stat_rx_aligned_err_sync_1_reg_reg" "cmac_stat_rx_aligned_err_sync_2_reg_reg" + constrain_sync_chain_async $inst "cmac_stat_rx_block_lock_sync_1_reg_reg[*]" "cmac_stat_rx_block_lock_sync_2_reg_reg[*]" + constrain_sync_chain_async $inst "cmac_stat_rx_hi_ber_sync_1_reg_reg" "cmac_stat_rx_hi_ber_sync_2_reg_reg" + constrain_sync_chain_async $inst "cmac_stat_rx_internal_local_fault_sync_1_reg_reg" "cmac_stat_rx_internal_local_fault_sync_2_reg_reg" + constrain_sync_chain_async $inst "cmac_stat_rx_local_fault_sync_1_reg_reg" "cmac_stat_rx_local_fault_sync_2_reg_reg" + constrain_sync_chain_async $inst "cmac_stat_rx_mf_len_err_sync_1_reg_reg[*]" "cmac_stat_rx_mf_len_err_sync_2_reg_reg[*]" + constrain_sync_chain_async $inst "cmac_stat_rx_mf_repeat_err_sync_1_reg_reg[*]" "cmac_stat_rx_mf_repeat_err_sync_2_reg_reg[*]" + + constrain_sync_chain $inst "cmac_ctl_rx_enable_drp_reg_reg" "cmac_ctl_rx_enable_sync_reg_reg" "cmac_ctl_rx_enable_reg_reg" + constrain_sync_chain $inst "cmac_ctl_rx_force_resync_drp_reg_reg" "cmac_ctl_rx_force_resync_sync_reg_reg" "cmac_ctl_rx_force_resync_reg_reg" + constrain_sync_chain $inst "cmac_ctl_rx_test_pattern_drp_reg_reg" "cmac_ctl_rx_test_pattern_sync_reg_reg" "cmac_ctl_rx_test_pattern_reg_reg" + + constrain_sync_chain_async $inst "cmac_stat_rx_received_local_fault_sync_1_reg_reg" "cmac_stat_rx_received_local_fault_sync_2_reg_reg" + constrain_sync_chain_async $inst "cmac_stat_rx_remote_fault_sync_1_reg_reg" "cmac_stat_rx_remote_fault_sync_2_reg_reg" + constrain_sync_chain_async $inst "cmac_stat_rx_status_sync_1_reg_reg" "cmac_stat_rx_status_sync_2_reg_reg" + constrain_sync_chain_async $inst "cmac_stat_rx_synced_sync_1_reg_reg[*]" "cmac_stat_rx_synced_sync_2_reg_reg[*]" + constrain_sync_chain_async $inst "cmac_stat_rx_synced_err_sync_1_reg_reg[*]" "cmac_stat_rx_synced_err_sync_2_reg_reg[*]" + constrain_sync_chain_async $inst "cmac_stat_rx_pcsl_demuxed_sync_1_reg_reg[*]" "cmac_stat_rx_pcsl_demuxed_sync_2_reg_reg[*]" + constrain_sync_chain_async $inst "cmac_stat_rx_pcsl_number_sync_1_reg_reg[*]" "cmac_stat_rx_pcsl_number_sync_2_reg_reg[*]" + + constrain_sync_chain_async $inst "cmac_stat_tx_ptp_fifo_read_error_sync_1_reg_reg" "cmac_stat_tx_ptp_fifo_read_error_sync_2_reg_reg" + constrain_sync_chain_async $inst "cmac_stat_tx_ptp_fifo_write_error_sync_1_reg_reg" "cmac_stat_tx_ptp_fifo_write_error_sync_2_reg_reg" + + constrain_sync_chain_async $inst "cmac_stat_tx_local_fault_sync_1_reg_reg" "cmac_stat_tx_local_fault_sync_2_reg_reg" + + constrain_sync_chain $inst "cmac_ctl_tx_enable_drp_reg_reg" "cmac_ctl_tx_enable_sync_reg_reg" "cmac_ctl_tx_enable_reg_reg" + constrain_sync_chain $inst "cmac_ctl_tx_send_idle_drp_reg_reg" "cmac_ctl_tx_send_idle_sync_reg_reg" "cmac_ctl_tx_send_idle_reg_reg" + constrain_sync_chain $inst "cmac_ctl_tx_send_rfi_drp_reg_reg" "cmac_ctl_tx_send_rfi_sync_reg_reg" "cmac_ctl_tx_send_rfi_reg_reg" + constrain_sync_chain $inst "cmac_ctl_tx_send_lfi_drp_reg_reg" "cmac_ctl_tx_send_lfi_sync_reg_reg" "cmac_ctl_tx_send_lfi_reg_reg" + constrain_sync_chain $inst "cmac_ctl_tx_test_pattern_drp_reg_reg" "cmac_ctl_tx_test_pattern_sync_reg_reg" "cmac_ctl_tx_test_pattern_reg_reg" +}