// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: xpcs_rxio_sync_fifo_ptr.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 ============================================
// ****************************************************************
// Sun Proprietary/Confidential: Internal Use Only
// ****************************************************************
// Design: IB Phy Interface
// Block: IB RX Phy Interface Controller
// Module: xpcs_rxio_sync_fifo_ptr
// File: xpcs_rxio_sync_fifo_ptr.v
// Description: This block contains a small fifo to allow
// ------------------------------------------------------------
// ------------------------------------------------------------
// 1.0 8/11/03 Created this module to guarantee pointer
// synchronization between hi/lo fifos of
// the same lane. Lane to lane deskew
// assumes fifos will be read at the same
// ****************************************************************
module xpcs_rxio_sync_fifo_ptr (
input w_clk; // Received Clock With Data
input w_rst; // Synchronous Active Low Reset
input rx_clk; // Link Core Receive Clock (recovered clock from lane 0)
input rst; // Synchronous Active Low Reset
input flush; // strobed for one clock to flush fifo (sets the r_ptr = synchronized(w_ptr))
// 4 bit gray code incrementer
// 000,001,011,010,110,111,101,100
assign n_w_ptr[2] = (w_ptr[1] & !w_ptr[0]) | (w_ptr[2] & w_ptr[0]) | (w_ptr[2] & w_ptr[1]);
assign n_w_ptr[1] = (w_ptr[1] & !w_ptr[2]) | (w_ptr[1] & !w_ptr[0]) | (w_ptr[0] & !w_ptr[2]);
assign n_w_ptr[0] = ((!w_ptr[2]) & (!w_ptr[1])) | (w_ptr[2] & w_ptr[1]);
// 2 bit gray code incrementer
// assign n_w_ptr[1] = w_ptr[0];
// assign n_w_ptr[0] = !w_ptr[1];
// Synchronize Write Pointer To rx_clk
assign new_w_ptr_0 = rst ? 1'b0 : w_ptr == 3'b000;
assign new_w_ptr_1 = rst ? 1'b0 : w_ptr == 3'b001;
assign new_w_ptr_2 = rst ? 1'b0 : w_ptr == 3'b010;
assign new_w_ptr_3 = rst ? 1'b0 : w_ptr == 3'b011;
assign new_w_ptr_4 = rst ? 1'b0 : w_ptr == 3'b100;
assign new_w_ptr_5 = rst ? 1'b0 : w_ptr == 3'b101;
assign new_w_ptr_6 = rst ? 1'b0 : w_ptr == 3'b110;
assign new_w_ptr_7 = rst ? 1'b0 : w_ptr == 3'b111;
SYNC_CELL SYNC_W_PTR_0 (.D(new_w_ptr_0), .CP(rx_clk), .Q(w_ptr_sync_0) );
SYNC_CELL SYNC_W_PTR_1 (.D(new_w_ptr_1), .CP(rx_clk), .Q(w_ptr_sync_1) );
SYNC_CELL SYNC_W_PTR_2 (.D(new_w_ptr_2), .CP(rx_clk), .Q(w_ptr_sync_2) );
SYNC_CELL SYNC_W_PTR_3 (.D(new_w_ptr_3), .CP(rx_clk), .Q(w_ptr_sync_3) );
SYNC_CELL SYNC_W_PTR_4 (.D(new_w_ptr_4), .CP(rx_clk), .Q(w_ptr_sync_4) );
SYNC_CELL SYNC_W_PTR_5 (.D(new_w_ptr_5), .CP(rx_clk), .Q(w_ptr_sync_5) );
SYNC_CELL SYNC_W_PTR_6 (.D(new_w_ptr_6), .CP(rx_clk), .Q(w_ptr_sync_6) );
SYNC_CELL SYNC_W_PTR_7 (.D(new_w_ptr_7), .CP(rx_clk), .Q(w_ptr_sync_7) );
assign w_ptr_sync = w_ptr_sync_0 ? 3'b000 :
// 2 bit gray code incrementer
// assign n_r_ptr[1] = r_ptr[0];
// assign n_r_ptr[0] = !r_ptr[1];
assign n_r_ptr[2] = (r_ptr[1] & !r_ptr[0]) | (r_ptr[2] & r_ptr[0]) | (r_ptr[2] & r_ptr[1]);
assign n_r_ptr[1] = (r_ptr[1] & !r_ptr[2]) | (r_ptr[1] & !r_ptr[0]) | (r_ptr[0] & !r_ptr[2]);
assign n_r_ptr[0] = ((!r_ptr[2]) & (!r_ptr[1])) | (r_ptr[2] & r_ptr[1]);
always @ (posedge rx_clk)
flush ? w_ptr_sync[2:0] :
//***********************************************
// Zero In Added Error Checks
//***********************************************
// synopsys translate_off
// START OF GREY CODE LOGIC CHECK FOR 0-in
// 000,001,011,010,110,111,101,100
reg test_w_ptr_grey_code_inc;
always @ (w_ptr or n_w_ptr)
3'b000 : test_w_ptr_grey_code_inc = (n_w_ptr != 3'b001); // 0 -> 1
3'b001 : test_w_ptr_grey_code_inc = (n_w_ptr != 3'b011); // 1 -> 3
3'b011 : test_w_ptr_grey_code_inc = (n_w_ptr != 3'b010); // 3 -> 2
3'b010 : test_w_ptr_grey_code_inc = (n_w_ptr != 3'b110); // 2 -> 6
3'b110 : test_w_ptr_grey_code_inc = (n_w_ptr != 3'b111); // 6 -> 7
3'b111 : test_w_ptr_grey_code_inc = (n_w_ptr != 3'b101); // 7 -> 5
3'b101 : test_w_ptr_grey_code_inc = (n_w_ptr != 3'b100); // 5 -> 4
3'b100 : test_w_ptr_grey_code_inc = (n_w_ptr != 3'b000); // 4 -> 0
// 0in custom -fire test_w_ptr_grey_code_inc -message "Deskew Fifo Grey Code Increment Failure On Write Pointer"
reg test_r_ptr_grey_code_inc;
always @ (r_ptr or n_r_ptr)
3'b000 : test_r_ptr_grey_code_inc = (n_r_ptr != 3'b001); // 0 -> 1
3'b001 : test_r_ptr_grey_code_inc = (n_r_ptr != 3'b011); // 1 -> 3
3'b011 : test_r_ptr_grey_code_inc = (n_r_ptr != 3'b010); // 3 -> 2
3'b010 : test_r_ptr_grey_code_inc = (n_r_ptr != 3'b110); // 2 -> 6
3'b110 : test_r_ptr_grey_code_inc = (n_r_ptr != 3'b111); // 6 -> 7
3'b111 : test_r_ptr_grey_code_inc = (n_r_ptr != 3'b101); // 7 -> 5
3'b101 : test_r_ptr_grey_code_inc = (n_r_ptr != 3'b100); // 5 -> 4
3'b100 : test_r_ptr_grey_code_inc = (n_r_ptr != 3'b000); // 4 -> 0
// 0in custom -fire test_r_ptr_grey_code_inc -message "Deskew Fifo Grey Code Increment Failure On Read Pointer"
// END OF GREY CODE LOGIC CHECK FOR 0-in