Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / niu / rtl / xpcs_rxio_ebuffer_sm.v
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: xpcs_rxio_ebuffer_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: Vega
// Block: XPCS Lane-to-lane deskew Interface
// Author: Carlos Castil
//
// Module: xpcs_rxio_ebuffer_sm
// File: xpcs_rxio_ebuffer_sm.v
//
// Description: This block contains the deskew state machine
// compliant to ieee 802.3ae clause 48 fig 48-8.
//
// Revision History
// ------------------------------------------------------------
// Ver Date Comments
// ------------------------------------------------------------
// 1.0 10/11/02 Created
//
// ****************************************************************
module xpcs_rxio_ebuffer_sm (
reset,
rx_clk,
csr_pulse_deskew_error,
csr_link_status,
sync_status,
state,
deskew_init,
deskew_done,
r_byte_0,
r_byte_1,
r_byte_2,
r_byte_3,
r_special_0,
r_special_1,
r_special_2,
r_special_3,
r_error_0,
r_error_1,
r_error_2,
r_error_3 );
input reset;
input rx_clk;
input [7:0] r_byte_0;
input [7:0] r_byte_1;
input [7:0] r_byte_2;
input [7:0] r_byte_3;
input r_special_0;
input r_special_1;
input r_special_2;
input r_special_3;
input r_error_0;
input r_error_1;
input r_error_2;
input r_error_3;
input deskew_done;
input sync_status;
output deskew_init;
output [7:0] state;
output csr_link_status;
output csr_pulse_deskew_error;
parameter DESKEW_LOSS = 8'h00;
parameter ALIGN_DET1 = 8'h01;
parameter ALIGN_DET2 = 8'h02;
parameter ALIGN_DET3 = 8'h04;
parameter DESKEW_OK = 8'h08;
parameter ALIGN_ERR1 = 8'h10;
parameter ALIGN_ERR2 = 8'h20;
parameter ALIGN_ERR3 = 8'h40;
wire [9:0] read_in_0;
wire [9:0] read_in_1;
wire [9:0] read_in_2;
wire [9:0] read_in_3;
wire alg_lane0;
wire alg_lane1;
wire alg_lane2;
wire alg_lane3;
wire alg_present;
wire aligned;
wire csr_deskew_error;
wire got_deskew_ok;
wire deskew_on_pulse;
wire deskew_off_pulse;
wire [7:0] nxt_state;
reg [7:0] state;
reg deskew_done_d;
reg deskew_init_d;
reg deskewing;
// ************************************************************************
// Snoop data out of deskew fifo to check if align characters are deskewed
// ************************************************************************
assign read_in_0[9:0] = {r_error_0, r_special_0, r_byte_0[7:0]};
assign read_in_1[9:0] = {r_error_1, r_special_1, r_byte_1[7:0]};
assign read_in_2[9:0] = {r_error_2, r_special_2, r_byte_2[7:0]};
assign read_in_3[9:0] = {r_error_3, r_special_3, r_byte_3[7:0]};
// check for comma symbol on all lanes
assign alg_lane0 = (read_in_0[9:0] == `XPCS_DEC_ALG);
assign alg_lane1 = (read_in_1[9:0] == `XPCS_DEC_ALG);
assign alg_lane2 = (read_in_2[9:0] == `XPCS_DEC_ALG);
assign alg_lane3 = (read_in_3[9:0] == `XPCS_DEC_ALG);
assign alg_present = alg_lane0 | alg_lane1 | alg_lane2 | alg_lane3 ;
assign aligned = alg_lane0 & alg_lane1 & alg_lane2 & alg_lane3;
assign csr_deskew_error = alg_present & !aligned;
assign got_deskew_ok = alg_present & aligned;
// ********************************
// Deskew init and done handshake
// ********************************
always @ (posedge rx_clk)
if (reset)
begin
deskew_done_d <= 1'b0;
deskew_init_d <= 1'b0;
deskewing <= 1'b0;
end
else
begin
deskew_done_d <= deskew_done;
deskew_init_d <= deskew_init;
deskewing <= deskew_on_pulse ? 1'b1 : deskew_off_pulse ? 1'b0 : deskewing;
end
assign deskew_off_pulse = deskew_done & !deskew_done_d;
assign deskew_on_pulse = deskew_init & !deskew_init_d;
// *****************************************
// Deskew state machine Clause 48 fig 48-8
// *****************************************
always @ (posedge rx_clk)
if (reset)
state <= 8'h00;
else
state <= nxt_state;
wire csr_link_status_temp;
reg csr_link_status;
always @ (posedge rx_clk)
csr_link_status <= csr_link_status_temp;
assign {csr_link_status_temp,
csr_pulse_deskew_error,
deskew_init,
nxt_state} = fn_deskew_sm (reset,
state,
sync_status,
csr_deskew_error,
deskewing,
got_deskew_ok);
function [10:0] fn_deskew_sm;
input reset;
input [7:0] state;
input sync;
input error;
input deskewing;
input got_ok;
reg [7:0] n_state;
reg n_status;
reg n_init;
reg n_inc_deskew_error;
begin
if (reset | !sync)
begin
n_status = 1'b0;
n_init = 1'b0;
n_inc_deskew_error = 1'b0;
n_state = DESKEW_LOSS;
end
else
begin
n_status = 1'b0;
n_init = 1'b0;
n_inc_deskew_error = 1'b0;
n_state = DESKEW_LOSS;
case (state) // synopsys parallel_case
DESKEW_LOSS:
if (!sync)
begin
n_init = 1'b0;
n_state = DESKEW_LOSS;
end
else if (got_ok)
begin
n_init = 1'b0;
n_state = ALIGN_DET1;
end
else if (!deskewing)
begin
n_init = 1'b1;
n_state = DESKEW_LOSS;
end
else
begin
n_init = 1'b0;
n_state = DESKEW_LOSS;
end
ALIGN_DET1:
if (error)
begin
n_state = DESKEW_LOSS;
end
else if (got_ok)
begin
n_state = ALIGN_DET2;
end
else
begin
n_state = ALIGN_DET1;
end
ALIGN_DET2:
if (error)
begin
n_state = DESKEW_LOSS;
end
else if (got_ok)
begin
n_state = ALIGN_DET3;
end
else
begin
n_state = ALIGN_DET2;
end
ALIGN_DET3:
if (error)
begin
n_state = DESKEW_LOSS;
end
else if (got_ok)
begin
n_state = DESKEW_OK;
end
else
begin
n_state = ALIGN_DET3;
end
DESKEW_OK:
if (error)
begin
n_status = 1'b1;
n_state = ALIGN_ERR1;
end
else
begin
n_status = 1'b1;
n_state = DESKEW_OK;
end
ALIGN_ERR1:
if (error)
begin
n_status = 1'b1;
n_state = ALIGN_ERR2;
end
else if (got_ok)
begin
n_status = 1'b1;
n_state = DESKEW_OK;
end
else
begin
n_status = 1'b1;
n_state = ALIGN_ERR1;
end
ALIGN_ERR2:
if (error)
begin
n_status = 1'b1;
n_state = ALIGN_ERR3;
end
else if (got_ok)
begin
n_status = 1'b1;
n_state = ALIGN_ERR1;
end
else
begin
n_status = 1'b1;
n_state = ALIGN_ERR2;
end
ALIGN_ERR3:
if (error)
begin
n_status = 1'b1;
n_inc_deskew_error = 1'b0;
n_state = DESKEW_LOSS;
end
else if (got_ok)
begin
n_status = 1'b1;
n_state = ALIGN_ERR2;
end
else
begin
n_status = 1'b1;
n_state = ALIGN_ERR3;
end
endcase
end
fn_deskew_sm = {n_status, n_inc_deskew_error, n_init, n_state};
end
endfunction
// 0in bits_on -var state -max 1 -clock rx_clk
// 0in state -var state -val DESKEW_LOSS -next ALIGN_DET1 -clock rx_clk -reset (reset |!sync_status)
// 0in state -var state -val ALIGN_DET1 -next DESKEW_LOSS ALIGN_DET2 -clock rx_clk -reset (reset |!sync_status)
// 0in state -var state -val ALIGN_DET2 -next DESKEW_LOSS ALIGN_DET3 -clock rx_clk -reset (reset |!sync_status)
// 0in state -var state -val ALIGN_DET3 -next DESKEW_LOSS DESKEW_OK -clock rx_clk -reset (reset |!sync_status)
// 0in state -var state -val DESKEW_OK -next ALIGN_ERR1 -clock rx_clk -reset (reset |!sync_status)
// 0in state -var state -val ALIGN_ERR1 -next DESKEW_OK ALIGN_ERR2 -clock rx_clk -reset (reset |!sync_status)
// 0in state -var state -val ALIGN_ERR2 -next ALIGN_ERR3 ALIGN_ERR1 -clock rx_clk -reset (reset |!sync_status)
// 0in state -var state -val ALIGN_ERR3 -next DESKEW_LOSS ALIGN_ERR2 -clock rx_clk -reset (reset |!sync_status)
endmodule