Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / model / pcie / pl / deserializer.v
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: deserializer.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
`define IDLE 0
`define ACTIVE 1
/// This module deserializes the data after it samples it from the bus
module deserializer( lane_in,
lane_in_bar,
lane_out0,
lane_out1,
lane_out2,
lane_out3,
lane_out4,
lane_out5,
lane_out6,
lane_out7,
lane_out8,
lane_out9,
lane_out0_b,
lane_out1_b,
lane_out2_b,
lane_out3_b,
lane_out4_b,
lane_out5_b,
lane_out6_b,
lane_out7_b,
lane_out8_b,
lane_out9_b,
frm_boundary,
init_done,
ts1_pattern_received,
data_rdy,
link_clk);
output [`LINK_WIDTH-1:0] lane_out0;
output [`LINK_WIDTH-1:0] lane_out1;
output [`LINK_WIDTH-1:0] lane_out2;
output [`LINK_WIDTH-1:0] lane_out3;
output [`LINK_WIDTH-1:0] lane_out4;
output [`LINK_WIDTH-1:0] lane_out5;
output [`LINK_WIDTH-1:0] lane_out6;
output [`LINK_WIDTH-1:0] lane_out7;
output [`LINK_WIDTH-1:0] lane_out8;
output [`LINK_WIDTH-1:0] lane_out9;
output [`LINK_WIDTH-1:0] lane_out0_b;
output [`LINK_WIDTH-1:0] lane_out1_b;
output [`LINK_WIDTH-1:0] lane_out2_b;
output [`LINK_WIDTH-1:0] lane_out3_b;
output [`LINK_WIDTH-1:0] lane_out4_b;
output [`LINK_WIDTH-1:0] lane_out5_b;
output [`LINK_WIDTH-1:0] lane_out6_b;
output [`LINK_WIDTH-1:0] lane_out7_b;
output [`LINK_WIDTH-1:0] lane_out8_b;
output [`LINK_WIDTH-1:0] lane_out9_b;
output data_rdy;
input [`LINK_WIDTH-1:0] lane_in;
input [`LINK_WIDTH-1:0] lane_in_bar;
input init_done;
input link_clk;
input frm_boundary;
input ts1_pattern_received;
reg [3:0] curr_state;
reg [1:0] curr_pl_state;
reg [`LINK_WIDTH-1:0] reg_out0;
reg [`LINK_WIDTH-1:0] reg_out1;
reg [`LINK_WIDTH-1:0] reg_out2;
reg [`LINK_WIDTH-1:0] reg_out3;
reg [`LINK_WIDTH-1:0] reg_out4;
reg [`LINK_WIDTH-1:0] reg_out5;
reg [`LINK_WIDTH-1:0] reg_out6;
reg [`LINK_WIDTH-1:0] reg_out7;
reg [`LINK_WIDTH-1:0] reg_out8;
reg [`LINK_WIDTH-1:0] reg_out9;
reg [`LINK_WIDTH-1:0] reg_out0_b;
reg [`LINK_WIDTH-1:0] reg_out1_b;
reg [`LINK_WIDTH-1:0] reg_out2_b;
reg [`LINK_WIDTH-1:0] reg_out3_b;
reg [`LINK_WIDTH-1:0] reg_out4_b;
reg [`LINK_WIDTH-1:0] reg_out5_b;
reg [`LINK_WIDTH-1:0] reg_out6_b;
reg [`LINK_WIDTH-1:0] reg_out7_b;
reg [`LINK_WIDTH-1:0] reg_out8_b;
reg [`LINK_WIDTH-1:0] reg_out9_b;
reg [`LINK_WIDTH-1:0] reg_in0;
reg [`LINK_WIDTH-1:0] reg_in1;
reg [`LINK_WIDTH-1:0] reg_in2;
reg [`LINK_WIDTH-1:0] reg_in3;
reg [`LINK_WIDTH-1:0] reg_in4;
reg [`LINK_WIDTH-1:0] reg_in5;
reg [`LINK_WIDTH-1:0] reg_in6;
reg [`LINK_WIDTH-1:0] reg_in7;
reg [`LINK_WIDTH-1:0] reg_in8;
reg [`LINK_WIDTH-1:0] reg_in9;
reg [`LINK_WIDTH-1:0] reg_in0_b;
reg [`LINK_WIDTH-1:0] reg_in1_b;
reg [`LINK_WIDTH-1:0] reg_in2_b;
reg [`LINK_WIDTH-1:0] reg_in3_b;
reg [`LINK_WIDTH-1:0] reg_in4_b;
reg [`LINK_WIDTH-1:0] reg_in5_b;
reg [`LINK_WIDTH-1:0] reg_in6_b;
reg [`LINK_WIDTH-1:0] reg_in7_b;
reg [`LINK_WIDTH-1:0] reg_in8_b;
reg [`LINK_WIDTH-1:0] reg_in9_b;
reg [9:0] ireg_in;
reg [9:0] ireg_in_b;
reg [3:0] sym_counter;
reg [3:0] lock_counter;
reg [3:0] prev_sym_counter;
reg com_detected;
wire [`LINK_WIDTH-1:0] in_val;
wire [`LINK_WIDTH-1:0] in_val_bar;
reg data_rdy_reg;
assign lane_out0 = reg_out0;
assign lane_out1 = reg_out1;
assign lane_out2 = reg_out2;
assign lane_out3 = reg_out3;
assign lane_out4 = reg_out4;
assign lane_out5 = reg_out5;
assign lane_out6 = reg_out6;
assign lane_out7 = reg_out7;
assign lane_out8 = reg_out8;
assign lane_out9 = reg_out9;
assign lane_out0_b = reg_out0_b;
assign lane_out1_b = reg_out1_b;
assign lane_out2_b = reg_out2_b;
assign lane_out3_b = reg_out3_b;
assign lane_out4_b = reg_out4_b;
assign lane_out5_b = reg_out5_b;
assign lane_out6_b = reg_out6_b;
assign lane_out7_b = reg_out7_b;
assign lane_out8_b = reg_out8_b;
assign lane_out9_b = reg_out9_b;
assign data_rdy = data_rdy_reg;
assign in_val = lane_in;
assign in_val_bar = lane_in_bar;
initial
begin
curr_state = 4'h0;
curr_pl_state = 2'h0;
sym_counter = 4'h0;
lock_counter = 4'h0;
prev_sym_counter = 0;
end
always @(negedge link_clk)
begin
if(sym_counter === 4'ha)
sym_counter <= 1;
else
sym_counter <= sym_counter + 1;
end
always @(negedge link_clk)
begin
case(curr_pl_state)
`IDLE : begin
if(lane_in !== lane_in_bar)
curr_pl_state <= `ACTIVE;
end
`ACTIVE : begin
if((lane_in === lane_in_bar) && init_done)
curr_pl_state <= `IDLE;
end
endcase
end
/// data shifting logic
always @(posedge link_clk)
begin
if((curr_pl_state === `ACTIVE))
begin
ireg_in[9:0] <= {in_val[0],ireg_in[9:1]};
ireg_in_b[9:0] <= {in_val_bar[0],ireg_in_b[9:1]};
end
end
always @(negedge link_clk)
begin
if(init_done || !ts1_pattern_received)
begin
case(curr_state)
4'h0 : begin curr_state <= 1; end
4'h1 : begin curr_state <= 2; end
4'h2 : begin curr_state <= 3; end
4'h3 : begin curr_state <= 4; end
4'h4 : begin curr_state <= 5; end
4'h5 : begin curr_state <= 6; end
4'h6 : begin curr_state <= 7; end
4'h7 : begin curr_state <= 8; end
4'h8 : begin curr_state <= 9; end
4'h9 : begin if(frm_boundary) curr_state <= 0; end
endcase
end
end
/// Store the incoming data into registers
always @(negedge link_clk)
begin
reg_out0 <= reg_in0;
reg_out1 <= reg_in1;
reg_out2 <= reg_in2;
reg_out3 <= reg_in3;
reg_out4 <= reg_in4;
reg_out5 <= reg_in5;
reg_out6 <= reg_in6;
reg_out7 <= reg_in7;
reg_out8 <= reg_in8;
reg_out9 <= reg_in9;
reg_out0_b <= reg_in0_b;
reg_out1_b <= reg_in1_b;
reg_out2_b <= reg_in2_b;
reg_out3_b <= reg_in3_b;
reg_out4_b <= reg_in4_b;
reg_out5_b <= reg_in5_b;
reg_out6_b <= reg_in6_b;
reg_out7_b <= reg_in7_b;
reg_out8_b <= reg_in8_b;
reg_out9_b <= reg_in9_b;
end
/// Based on the current state counters assign values to registers
/// Reset current state counter if ini not yet done
always @(posedge link_clk)
begin
if(init_done || !ts1_pattern_received)
begin
case(curr_state)
4'h0 : begin reg_in0 <= in_val; reg_in0_b <= in_val_bar; end
4'h1 : begin reg_in1 <= in_val; reg_in1_b <= in_val_bar; end
4'h2 : begin reg_in2 <= in_val; reg_in2_b <= in_val_bar; end
4'h3 : begin reg_in3 <= in_val; reg_in3_b <= in_val_bar; end
4'h4 : begin reg_in4 <= in_val; reg_in4_b <= in_val_bar; end
4'h5 : begin reg_in5 <= in_val; reg_in5_b <= in_val_bar; end
4'h6 : begin reg_in6 <= in_val; reg_in6_b <= in_val_bar; end
4'h7 : begin reg_in7 <= in_val; reg_in7_b <= in_val_bar; end
4'h8 : begin reg_in8 <= in_val; reg_in8_b <= in_val_bar; end
4'h9 : begin reg_in9 <= in_val; reg_in9_b <= in_val_bar; end
endcase
end
else
curr_state <= 4'h0;
end
endmodule