Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / model / pcie / pl / serializer.v
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: serializer.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 ============================================
`timescale 100ps / 10ps
`ifdef LINK_1
`define LINK_WIDTH 1
`else
`ifdef LINK_2
`define LINK_WIDTH 2
`else
`ifdef LINK_4
`define LINK_WIDTH 4
`else
`ifdef LINK_12
`define LINK_WIDTH 12
`else
`ifdef LINK_16
`define LINK_WIDTH 16
`else
`ifdef LINK_24
`define LINK_WIDTH 24
`else
`ifdef LINK_32
`define LINK_WIDTH 32
`else
`define LINK_WIDTH 8
`endif
`endif
`endif
`endif
`endif
`endif
`endif
/// Module to serialize the data before putting it on the bus
module serializer( lane_in0,
lane_in1,
lane_in2,
lane_in3,
lane_in4,
lane_in5,
lane_in6,
lane_in7,
lane_in8,
lane_in9,
link_clk,
out,
out_bar,
frame_boundary
);
input [`LINK_WIDTH-1:0] lane_in0;
input [`LINK_WIDTH-1:0] lane_in1;
input [`LINK_WIDTH-1:0] lane_in2;
input [`LINK_WIDTH-1:0] lane_in3;
input [`LINK_WIDTH-1:0] lane_in4;
input [`LINK_WIDTH-1:0] lane_in5;
input [`LINK_WIDTH-1:0] lane_in6;
input [`LINK_WIDTH-1:0] lane_in7;
input [`LINK_WIDTH-1:0] lane_in8;
input [`LINK_WIDTH-1:0] lane_in9;
input link_clk; // SymbolClk/10
input frame_boundary;
output [`LINK_WIDTH-1:0] out, out_bar;
reg [3:0] counter, prev_counter, lock_counter;
reg [3:0] curr_state;
reg [5:0] tx_lane0_deskew,tx_lane1_deskew,tx_lane2_deskew,tx_lane3_deskew;
reg [5:0] tx_lane4_deskew,tx_lane5_deskew,tx_lane6_deskew,tx_lane7_deskew;
integer i;
reg val;
reg [`LINK_WIDTH-1:0] out_reg,out_bar_reg;
reg comma_detected;
reg sequence_start;
wire all_lanes_detected;
wire sym_boundary;
// Inputs to this module do not have any skew, since they come from the TL,DLL
// Only outputs to the bus will have necessary skew
// Max skew = 20ns or 50 UI
assign out = out_reg[`LINK_WIDTH-1:0];
assign out_bar = out_bar_reg[`LINK_WIDTH-1:0];
initial begin
comma_detected = 1'b0;
sequence_start = 1'b0;
counter = 4'ha;
lock_counter = 4'h0;
prev_counter = 4'h0;
curr_state = 4'h0;
//$fsdbDumpvars;
end
// Above codes for getting symbol boundary lock...
// Now the main code for reading in incoming data and do the work of serial-parallel
// Always block takes care of the serialization.
// If only some of the 32 lanes are active, the inactive ones will have all zeroes(or encoded version of zeroes, which have no meaning)
always @(posedge link_clk)
begin
case(curr_state)
4'h0 : begin
for(i=0;i<`LINK_WIDTH;i=i+1)
begin
out_reg[i] <= lane_in0[i] ; out_bar_reg[i] <= ~lane_in0[i] ;
end
end
4'h1 : begin
for(i=0;i<`LINK_WIDTH;i=i+1)
begin
out_reg[i] <= lane_in1[i] ; out_bar_reg[i] <= ~lane_in1[i] ;
end
end
4'h2 : begin
for(i=0;i<`LINK_WIDTH;i=i+1)
begin
out_reg[i] <= lane_in2[i] ; out_bar_reg[i] <= ~lane_in2[i] ;
end
end
4'h3 : begin
for(i=0;i<`LINK_WIDTH;i=i+1)
begin
out_reg[i] <= lane_in3[i] ; out_bar_reg[i] <= ~lane_in3[i] ;
end
end
4'h4 : begin
for(i=0;i<`LINK_WIDTH;i=i+1)
begin
out_reg[i] <= lane_in4[i] ; out_bar_reg[i] <= ~lane_in4[i] ;
end
end
4'h5 : begin
for(i=0;i<`LINK_WIDTH;i=i+1)
begin
out_reg[i] <= lane_in5[i] ; out_bar_reg[i] <= ~lane_in5[i] ;
end
end
4'h6 : begin
for(i=0;i<`LINK_WIDTH;i=i+1)
begin
out_reg[i] <= lane_in6[i] ; out_bar_reg[i] <= ~lane_in6[i] ;
end
end
4'h7 : begin
for(i=0;i<`LINK_WIDTH;i=i+1)
begin
out_reg[i] <= lane_in7[i] ; out_bar_reg[i] <= ~lane_in7[i] ;
end
end
4'h8 : begin
for(i=0;i<`LINK_WIDTH;i=i+1)
begin
out_reg[i] <= lane_in8[i] ; out_bar_reg[i] <= ~lane_in8[i] ;
end
end
4'h9 : begin
for(i=0;i<`LINK_WIDTH;i=i+1)
begin
out_reg[i] <= lane_in9[i] ; out_bar_reg[i] <= ~lane_in9[i] ;
end
end
endcase
end
/// State counter block
always @(negedge link_clk)
begin
case(curr_state)
4'h0 : begin curr_state <= 4'h1 ; end
4'h1 : begin curr_state <= 4'h2 ; end
4'h2 : begin curr_state <= 4'h3 ; end
4'h3 : begin curr_state <= 4'h4 ; end
4'h4 : begin curr_state <= 4'h5 ; end
4'h5 : begin curr_state <= 4'h6 ; end
4'h6 : begin curr_state <= 4'h7 ; end
4'h7 : begin curr_state <= 4'h8 ; end
4'h8 : begin curr_state <= 4'h9 ; end
4'h9 : begin if(frame_boundary) curr_state <= 4'h0 ; end
endcase
end
endmodule