Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / niu / rtl / xpcs_rxio_sync_sm.v
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: xpcs_rxio_sync_sm.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
// have any questions.
//
// ========== Copyright Header End ============================================
// ****************************************************************
//
// Sun Proprietary/Confidential: Internal Use Only
//
// ****************************************************************
// Design: XPCS RX IO Interface
// Block: XPCS RX Sync state machine
// Author: Carlos Castil
//
// Module: xpcs_rxio_sync_sm
// File: xpcs_rxio_sync_sm.v
//
// Description: This block contains a comma detector compliant
// to ieee 802.3ae clause 48 fig 48-7.
//
// Revision History
// ------------------------------------------------------------
// Ver Date Comments
// ------------------------------------------------------------
// 1.0 09/24/02 Created
//
// ****************************************************************
module xpcs_rxio_sync_sm (
rx_lane_clk,
rx_lane_reset,
rx_signal_detect,
byte_deskew,
special_deskew,
error_deskew,
state,
csr_lane_sync_status);
input rx_lane_clk;
input rx_lane_reset;
input rx_signal_detect;
input [7:0] byte_deskew;
input special_deskew;
input error_deskew;
output [3:0] state;
output csr_lane_sync_status;
// Wires and Regs which are not flops
wire com_det;
wire [3:0] nxt_state;
// Regs which are flops
reg csr_lane_sync_status;
wire rx_lane_sync_loss;
wire inc_comma_cnt;
wire inc_symbol_cnt;
wire [2:0] nxt_comma_cnt; // counter for number of good commas received
wire [2:0] nxt_symbol_cnt; // counter for number of good symbol received
reg [2:0] comma_cnt;
reg [2:0] symbol_cnt;
wire clr_comma_cnt;
wire clr_symbol_cnt;
wire comma_cnt_eq4;
wire symbol_cnt_eq3;
reg [3:0] state;
wire com_k281_det;
wire com_k285_det;
wire com_k287_det;
wire invalid;
parameter LOSS_SYNC = 4'h0; // word synchronization state machine
parameter IN_SYNC = 4'h1;
parameter ONE_INVALID = 4'h2;
parameter TWO_INVALID = 4'h4;
parameter THREE_INVALID = 4'h8;
// Decode
/*
XPCS_DEC_COM 10'h1BC // K28.5
XPCS_DEC_281 10'h13C
XPCS_DEC_285 10'h1BC
XPCS_DEC_287 10'h1FC
XPCS_DEC_SDP 10'h1FB
XPCS_DEC_SLP 10'h15C
XPCS_DEC_EGP 10'h1FD
XPCS_DEC_EBP 10'h1FE
XPCS_DEC_PAD 10'h1F7
XPCS_DEC_SKP 10'h11C
XPCS_DEC_LN0 10'h000
XPCS_DEC_LN1 10'h001
XPCS_DEC_LN2 10'h002
XPCS_DEC_LN3 10'h004
XPCS_DEC_LN4 10'h008
XPCS_DEC_LN5 10'h00F
XPCS_DEC_LN6 10'h010
XPCS_DEC_LN7 10'h017
XPCS_DEC_LN8 10'h018
XPCS_DEC_LN9 10'h01B
XPCS_DEC_LNA 10'h01D
XPCS_DEC_LNB 10'h01E
*/
assign com_k281_det = ({error_deskew,special_deskew,byte_deskew[7:0]} == `XPCS_DEC_281);
assign com_k285_det = ({error_deskew,special_deskew,byte_deskew[7:0]} == `XPCS_DEC_285);
assign com_k287_det = ({error_deskew,special_deskew,byte_deskew[7:0]} == `XPCS_DEC_287);
assign com_det = com_k281_det | com_k285_det | com_k287_det;
assign invalid = error_deskew; // Disparity and decode errors
/*
** Synchronization COMMA counter
*/
always @ (posedge rx_lane_clk)
if (rx_lane_reset)
comma_cnt <= 3'b0;
else
comma_cnt <= nxt_comma_cnt;
assign nxt_comma_cnt = (rx_lane_reset | clr_comma_cnt) ? 3'h0 :
(inc_comma_cnt) ? comma_cnt + 3'h1 :
comma_cnt;
assign comma_cnt_eq4 = (comma_cnt >= 3'h4);
/*
** Synchronization SYMBOL counter
*/
always @ (posedge rx_lane_clk)
if (rx_lane_reset)
symbol_cnt <= 3'b0;
else
symbol_cnt <= nxt_symbol_cnt;
assign nxt_symbol_cnt = (rx_lane_reset | clr_symbol_cnt) ? 3'h0 :
(inc_symbol_cnt) ? symbol_cnt + 3'h1 :
symbol_cnt;
assign symbol_cnt_eq3 = (symbol_cnt >= 3'h3);
/* ************************************************************* */
always @ (posedge rx_lane_clk)
csr_lane_sync_status <= !rx_lane_sync_loss;
/*
** Call of function word synchronization
*/
assign {rx_lane_sync_loss,inc_symbol_cnt,clr_symbol_cnt,inc_comma_cnt,clr_comma_cnt,nxt_state}
= synchronization_fn(rx_lane_reset,
com_det,
invalid,
comma_cnt_eq4,
symbol_cnt_eq3,
state);
/*
** Word Synchronization state machine
*/
function [8:0] synchronization_fn;
input f_reset;
input f_com_det; // to determine if there is a comma
input f_invalid; // invalid transmission word detected
input f_comma_cnt_eq4;
input f_symbol_cnt_eq3; // found 3 commas with no errors
input [3:0] state;
reg f_loss_sync; // indicates word sync status
reg f_inc_comma_cnt; // increment word sync counter
reg f_clr_comma_cnt; // clear word sync counter
reg f_inc_symbol_cnt; // increment word sync counter
reg f_clr_symbol_cnt; // clear word sync counter
reg [3:0] n_state; // next state
begin
if (f_reset)
begin
f_loss_sync = 1'h1;
f_inc_comma_cnt = 1'h0;
f_clr_comma_cnt = 1'h1;
f_inc_symbol_cnt = 1'h0;
f_clr_symbol_cnt = 1'h1;
n_state = LOSS_SYNC;
end
else
begin
f_loss_sync = 1'h0;
f_inc_comma_cnt = 1'h0;
f_clr_comma_cnt = 1'h0;
f_inc_symbol_cnt = 1'h0;
f_clr_symbol_cnt = 1'h0;
n_state = LOSS_SYNC;
case (state) // synopsys parallel_case
LOSS_SYNC : // 0 // being in this state triggers link config
begin
f_loss_sync = 1'h1;
if (f_reset)
n_state = LOSS_SYNC;
else if (f_invalid)
begin
f_clr_comma_cnt = 1'h1;
f_clr_symbol_cnt = 1'h1;
n_state = LOSS_SYNC;
end
else if (f_comma_cnt_eq4) // got 3 good commas
n_state = IN_SYNC;
else if (f_com_det) // accum good
begin
f_clr_comma_cnt = 1'h0;
f_inc_comma_cnt = 1'h1;
n_state = LOSS_SYNC;
end
else
n_state = LOSS_SYNC;
end
IN_SYNC : // 1
if (f_invalid)
begin
f_clr_comma_cnt = 1'h1;
f_clr_symbol_cnt = 1'h1;
n_state = ONE_INVALID;
end
else
n_state = IN_SYNC;
ONE_INVALID : // 2
if (f_invalid)
begin
f_clr_symbol_cnt = 1'h1;
f_clr_comma_cnt = 1'h1;
n_state = TWO_INVALID;
end
else if (f_symbol_cnt_eq3) // got 3 good symbols
begin
f_clr_symbol_cnt = 1'h1;
f_clr_comma_cnt = 1'h1;
n_state = IN_SYNC; // go to sync state
end
else // inc good symbol count
begin
f_clr_symbol_cnt = 1'h0;
f_inc_symbol_cnt = 1'h1;
n_state = ONE_INVALID;
end
TWO_INVALID : // 4
if (f_invalid)
begin
f_clr_symbol_cnt = 1'h1;
f_clr_comma_cnt = 1'h1;
n_state = THREE_INVALID;
end
else if (f_symbol_cnt_eq3) // got 3 good symbols
begin
f_clr_symbol_cnt = 1'h1;
f_clr_comma_cnt = 1'h1;
n_state = ONE_INVALID; // Need to get 3 more good symbols
end
else // inc good symbol count
begin
f_clr_symbol_cnt = 1'h0;
f_inc_symbol_cnt = 1'h1;
n_state = TWO_INVALID;
end
THREE_INVALID : // 8
if (f_invalid)
begin
f_clr_symbol_cnt = 1'h1;
f_clr_comma_cnt = 1'h1;
n_state = LOSS_SYNC;
end
else if (f_symbol_cnt_eq3) // got 3 good symbols
begin
f_clr_symbol_cnt = 1'h1;
f_clr_comma_cnt = 1'h1;
n_state = TWO_INVALID; // Need to get 6 more good symbols
end
else // inc good symbol count
begin
f_clr_symbol_cnt = 1'h0;
f_inc_symbol_cnt = 1'h1;
n_state = THREE_INVALID;
end
endcase
end
// {rx_lane_sync_loss, inc_symbol_cnt, clr_symbol_cnt, inc_comma_cnt, clr_comma_cnt,nxt_state}
synchronization_fn = {f_loss_sync,f_inc_symbol_cnt,f_clr_symbol_cnt,f_inc_comma_cnt,f_clr_comma_cnt,n_state};
end
endfunction
// ********************************
// Receive State Machine Registers
// ********************************
always @(posedge rx_lane_clk)
if (rx_lane_reset | !rx_signal_detect)
begin
state <= 4'b0;
end
else
begin
state <= nxt_state;
end
// 0in bits_on -var state -max 1 -clock rx_lane_clk
// 0in state -var state -val LOSS_SYNC -next IN_SYNC -clock rx_lane_clk -reset (rx_lane_reset | !rx_signal_detect)
// 0in state -var state -val IN_SYNC -next ONE_INVALID -clock rx_lane_clk -reset (rx_lane_reset | !rx_signal_detect)
// 0in state -var state -val ONE_INVALID -next TWO_INVALID IN_SYNC -clock rx_lane_clk -reset (rx_lane_reset | !rx_signal_detect)
// 0in state -var state -val TWO_INVALID -next THREE_INVALID ONE_INVALID -clock rx_lane_clk -reset (rx_lane_reset | !rx_signal_detect)
// 0in state -var state -val THREE_INVALID -next LOSS_SYNC TWO_INVALID -clock rx_lane_clk -reset (rx_lane_reset | !rx_signal_detect)
endmodule