// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: esr_ctl2.v
// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// For the avoidance of doubt, and except that if any non-GPL license
// choice is available it will apply instead, Sun elects to use only
// the General Public License version 2 (GPLv2) at this time for any
// software where a choice of GPL license versions is made
// available with the language indicating that GPLv2 or any later version
// may be used, or where a choice of which version of the GPL is applied is
// otherwise unspecified.
// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
// CA 95054 USA or visit www.sun.com if you need additional information or
// ========== Copyright Header End ============================================
/*************************************************************************
* Description : ethernet serdes controller.
* This module main function is to produce
* This module is in sys_clk domain.
* The corresponding data path is in sphy_dpath4.
* The corresponding clock path is in phy_clock_2ports.
* The muxing on esr_ctl2, sphy_dpath2, and phy_clock_2ports
* should be in sync. -> This is very important.
* Parent Module: mac_2ports
* Copyright (c) 2020, Sun Microsystems, Inc.
* Sun Proprietary and Confidential
*************************************************************************/
pio_addr, // pio global signal
pio_rd, // pio global signal
pio_wdata, // pio global signal
// port0 xpcs, pcs signals
// port1 xpcs, pcs signals
/* ----- debug data ----- */
output blunt_end_loopback;
input [8:0] pio_addr; // pio global signal
input pio_rd; // pio global signal
input [31:0] pio_wdata; // pio global signal
// port0 xpcs, pcs signals
input [3:0] esr_mac_los_0;
output [3:0] xsignal_detect_0;
// port1 xpcs, pcs signals
input [3:0] esr_mac_los_1;
output [3:0] xsignal_detect_1;
/* ----- debug data ----- */
input [39:0] xtx_code_group0;
input [9:0] tx_code_group0;
input [9:0] mac_esr_txd0_0;
input [9:0] mac_esr_txd1_0;
input [9:0] mac_esr_txd2_0;
input [9:0] mac_esr_txd3_0;
input [9:0] esr_mac_rxd0_0;
input [9:0] esr_mac_rxd1_0;
input [9:0] esr_mac_rxd2_0;
input [9:0] esr_mac_rxd3_0;
input [39:0] xrx_code_group0;
input [9:0] rx_code_group0;
input [39:0] xtx_code_group1;
input [9:0] tx_code_group1;
input [9:0] mac_esr_txd0_1;
input [9:0] mac_esr_txd1_1;
input [9:0] mac_esr_txd2_1;
input [9:0] mac_esr_txd3_1;
input [9:0] esr_mac_rxd0_1;
input [9:0] esr_mac_rxd1_1;
input [9:0] esr_mac_rxd2_1;
input [9:0] esr_mac_rxd3_1;
input [39:0] xrx_code_group1;
input [9:0] rx_code_group1;
output [31:0] esrctl_debug;
///////////////////////////////////////////////////////////////
wire [3:0] esr_mac_los_0;
wire [3:0] xsignal_detect_0;
wire [3:0] esr_mac_los_1;
wire [3:0] xsignal_detect_1;
reg non_qualified_addr_err;
wire blunt_end_loopback ;
wire [1:0] serdes_reset ;
// vlint flag_dangling_net_within_module off
// vlint flag_net_has_no_load off
// vlint flag_net_has_no_load on
// vlint flag_dangling_net_within_module on
// **********************************
// **********************************
SYNC_CELL lock_0_SYNC_CELL (.D(esr_mac_lock_0),.CP(clk),.Q(lock_0));
SYNC_CELL lock_1_SYNC_CELL (.D(esr_mac_lock_1),.CP(clk),.Q(lock_1));
// **********************************
// **********************************
SYNC_CELL los0_0_SYNC_CELL (.D(esr_mac_los_0[0]),.CP(clk),.Q(los0_0));
SYNC_CELL los1_0_SYNC_CELL (.D(esr_mac_los_0[1]),.CP(clk),.Q(los1_0));
SYNC_CELL los2_0_SYNC_CELL (.D(esr_mac_los_0[2]),.CP(clk),.Q(los2_0));
SYNC_CELL los3_0_SYNC_CELL (.D(esr_mac_los_0[3]),.CP(clk),.Q(los3_0));
wire set_serdes_rdy0_0 = (lock_0 & ~los0_0) | force_serdes_rdy;
wire set_serdes_rdy1_0 = (lock_0 & ~los1_0) | force_serdes_rdy;
wire set_serdes_rdy2_0 = (lock_0 & ~los2_0) | force_serdes_rdy;
wire set_serdes_rdy3_0 = (lock_0 & ~los3_0) | force_serdes_rdy;
SRFF serdes_rdy0_0_SRFF (.reset(reset),.clk(clk),.iSet(set_serdes_rdy0_0),.iRst(los0_0),.oQ(serdes_rdy0_0));
SRFF serdes_rdy1_0_SRFF (.reset(reset),.clk(clk),.iSet(set_serdes_rdy1_0),.iRst(los1_0),.oQ(serdes_rdy1_0));
SRFF serdes_rdy2_0_SRFF (.reset(reset),.clk(clk),.iSet(set_serdes_rdy2_0),.iRst(los2_0),.oQ(serdes_rdy2_0));
SRFF serdes_rdy3_0_SRFF (.reset(reset),.clk(clk),.iSet(set_serdes_rdy3_0),.iRst(los3_0),.oQ(serdes_rdy3_0));
assign signal_detect0_0 = ~los0_0;
xserdes_rdy_0 <= serdes_rdy0_0 &
assign xsignal_detect_0[3:0] = {~los3_0,~los2_0,~los1_0,~los0_0};
// **********************************
// **********************************
SYNC_CELL los0_1_SYNC_CELL (.D(esr_mac_los_1[0]),.CP(clk),.Q(los0_1));
SYNC_CELL los1_1_SYNC_CELL (.D(esr_mac_los_1[1]),.CP(clk),.Q(los1_1));
SYNC_CELL los2_1_SYNC_CELL (.D(esr_mac_los_1[2]),.CP(clk),.Q(los2_1));
SYNC_CELL los3_1_SYNC_CELL (.D(esr_mac_los_1[3]),.CP(clk),.Q(los3_1));
wire set_serdes_rdy0_1 = (lock_1 & ~los0_1) | force_serdes_rdy;
wire set_serdes_rdy1_1 = (lock_1 & ~los1_1) | force_serdes_rdy;
wire set_serdes_rdy2_1 = (lock_1 & ~los2_1) | force_serdes_rdy;
wire set_serdes_rdy3_1 = (lock_1 & ~los3_1) | force_serdes_rdy;
SRFF serdes_rdy0_1_SRFF (.reset(reset),.clk(clk),.iSet(set_serdes_rdy0_1),.iRst(los0_1),.oQ(serdes_rdy0_1));
SRFF serdes_rdy1_1_SRFF (.reset(reset),.clk(clk),.iSet(set_serdes_rdy1_1),.iRst(los1_1),.oQ(serdes_rdy1_1));
SRFF serdes_rdy2_1_SRFF (.reset(reset),.clk(clk),.iSet(set_serdes_rdy2_1),.iRst(los2_1),.oQ(serdes_rdy2_1));
SRFF serdes_rdy3_1_SRFF (.reset(reset),.clk(clk),.iSet(set_serdes_rdy3_1),.iRst(los3_1),.oQ(serdes_rdy3_1));
assign signal_detect0_1 = ~los0_1;
xserdes_rdy_1 <= serdes_rdy0_1 &
assign xsignal_detect_1[3:0] = {~los3_1,~los2_1,~los1_1,~los0_1};
// **********************************
// **********************************
//***** Register the bif interface signals *********************
// To reduce gate count -> take register away
// If there is a timing problem then register them again here.
//**************************************************************
FD1 core_reset_FD1 (.D(pio_core_reset),.CP(clk),.Q(reset));
FD1 rd_wr_FD1 (.D(pio_rd), .CP(clk),.Q(rd_wr));
FD1 core_sel_FD1 (.D(sel_esr), .CP(clk),.Q(core_sel));
RegDff #(9) reg_offset_RegDff(.din(pio_addr[8:0]),
RegDff #(32) wr_data_RegDff (.din(pio_wdata[31:0]),
PlsGen2 core_sel_PlsGen2(.sig_in(core_sel),.clk(clk),
assign rd_en = core_sel & rd_wr;
wire rac_ok = core_sel_lead & rd_wr;
assign wr_en = core_sel_lead & (~rd_wr);
RegDff #(32) pio_rd_data_RegDff (.din(rd_data),.clk(clk),
FD1 pio_ack_FD1 (.D(core_sel_lead),.CP(clk),.Q(ack_esr));
FD1 rac_pls_FD1 (.D(rac_ok),.CP(clk),.Q(rac_pls));
assign addr_err = non_qualified_addr_err & core_sel_lead;
FD1 pio_err_FD1 (.D(addr_err),.CP(clk),.Q(pio_err_esr));
/* ----------- Read and Write Address Decoder -------------------------- */
always @ (/*AUTOSENSE*/configa or debug_sel or lock_0 or lock_1
or los0_0 or los0_1 or los1_0 or los1_1 or los2_0 or los2_1
or los3_0 or los3_1 or reg_offset or serdes_rdy0_0
or serdes_rdy0_1 or serdes_reset or signal_detect0_0
or signal_detect0_1 or wr_en or xserdes_rdy_0
or xserdes_rdy_1 or xsignal_detect_0 or xsignal_detect_1)
ld_configa = 0; // serdes_0
non_qualified_addr_err= 0;
case (reg_offset[8:0]) // synopsys parallel_case full_case infer_mux
rd_data = {30'b0,serdes_reset[1:0]};
rd_data = {30'b0,configa};
rd_data = {lock_0,lock_1,
serdes_rdy0_0,signal_detect0_0,
serdes_rdy0_1,signal_detect0_1,
xserdes_rdy_0,xsignal_detect_0[3:0],
xserdes_rdy_1,xsignal_detect_1[3:0],
los3_1,los2_1,los1_1,los0_1,
los3_0,los2_0,los1_0,los0_0};
non_qualified_addr_err= 1;
endcase // case(reg_offset[8:0])
/* -------------------- serdes -------------------- */
xREG2 #(6) debug_sel_xREG2 (.clk(clk),
.din(wr_data[5:0]), // Bits[2:0] are ignored.
assign debug_sel[31:6] = 0;
always @ (/*AUTOSENSE*/debug_sel or esr_mac_rxd0_0
or esr_mac_rxd0_1 or esr_mac_rxd1_0 or esr_mac_rxd1_1
or esr_mac_rxd2_0 or esr_mac_rxd2_1 or esr_mac_rxd3_0
or esr_mac_rxd3_1 or mac_esr_txd0_0 or mac_esr_txd0_1
or mac_esr_txd1_0 or mac_esr_txd1_1 or mac_esr_txd2_0
or mac_esr_txd2_1 or mac_esr_txd3_0 or mac_esr_txd3_1
or rx_code_group0 or rx_code_group1 or tx_code_group0
or tx_code_group1 or xrx_code_group0 or xrx_code_group1
or xtx_code_group0 or xtx_code_group1)
case (debug_sel[3:0]) // synopsys parallel_case full_case
4'h0 : esrctl_debug = xtx_code_group0[31:0];
4'h1 : esrctl_debug = {4'b0,mac_esr_txd0_0[9:0],tx_code_group0[9:0],xtx_code_group0[39:32]};
4'h2 : esrctl_debug = {2'b0,mac_esr_txd3_0[9:0],mac_esr_txd2_0[9:0],mac_esr_txd1_0[9:0]};
4'h3 : esrctl_debug = xrx_code_group0[31:0];
4'h4 : esrctl_debug = {4'b0,esr_mac_rxd0_0[9:0],rx_code_group0[9:0],xrx_code_group0[39:32]};
4'h5 : esrctl_debug = {2'b0,esr_mac_rxd3_0[9:0],esr_mac_rxd2_0[9:0],esr_mac_rxd1_0[9:0]};
4'h6 : esrctl_debug = xtx_code_group1[31:0];
4'h7 : esrctl_debug = {4'b0,mac_esr_txd0_1[9:0],tx_code_group1[9:0],xtx_code_group1[39:32]};
4'h8 : esrctl_debug = {2'b0,mac_esr_txd3_1[9:0],mac_esr_txd2_1[9:0],mac_esr_txd1_1[9:0]};
4'h9 : esrctl_debug = xrx_code_group1[31:0];
4'ha : esrctl_debug = {4'b0,esr_mac_rxd0_1[9:0],rx_code_group1[9:0],xrx_code_group1[39:32]};
4'hb : esrctl_debug = {2'b0,esr_mac_rxd3_1[9:0],esr_mac_rxd2_1[9:0],esr_mac_rxd1_1[9:0]};
default: esrctl_debug = xtx_code_group0[31:0];
/***************************************************************
* register instantiation secton
***************************************************************/
/* ------------------------- serdes_reset ------------------------------- */
xREG #(2) serdes_reset_xREG(.clk(clk),.reset(reset),.en(ld_serdes_reset),.din(wr_data[1:0]),.qout(serdes_reset[1:0]));
wire serdes_reset_0 = serdes_reset[0];
wire serdes_reset_1 = serdes_reset[1];
/* ------------------------------------------------------------------------- */
/* ------------------------- configa ------------------------------ */
// For some reason synopsys does not like "config" as signal name.
xREG #(2) configa_xREG(.clk(clk),.reset(reset),.en(ld_configa),.din(wr_data[1:0]),.qout(configa[1:0]));
assign force_serdes_rdy = configa[0];
assign blunt_end_loopback = configa[1];
/* ------------------------------------------------------------------------- */