Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / model / verilog / mem / fbdimm / design / fbdimm_sb_fsr.v
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: fbdimm_sb_fsr.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 ============================================
module fbdimm_sb_fsr(reset,
ps_in,
ps_in_bar,
ps0_out,
ps0_out_bar,
ps1_out,
ps1_out_bar,
ps2_out,
ps2_out_bar,
ps3_out,
ps4_out,
ps5_out,
ps6_out,
ps7_out,
ps8_out,
ps9_out,
ps10_out,
ps11_out,
link_clk,
sb_decode_clk,
dtm_tr_complete,
nop_frame_detected,
dtm_enabled_out,
frm_begin,
frm_begin_nb,
frm_boundary_nb,
init_seq_started,
ref_clk);
input reset;
input [9:0] ps_in,ps_in_bar;
output [9:0] ps0_out,ps0_out_bar;
output [9:0] ps1_out,ps1_out_bar;
output [9:0] ps2_out,ps2_out_bar;
output [9:0] ps3_out;
output [9:0] ps4_out;
output [9:0] ps5_out;
output [9:0] ps6_out;
output [9:0] ps7_out;
output [9:0] ps8_out;
output [9:0] ps9_out;
output [9:0] ps10_out;
output [9:0] ps11_out;
output init_seq_started;
output frm_boundary_nb;
output frm_begin_nb;
output nop_frame_detected;
output dtm_tr_complete;
output frm_begin;
input link_clk;
output ref_clk;
output sb_decode_clk;
output dtm_enabled_out;
reg [3:0] fsr_count;
reg [9:0] ps0_out_reg,ps0_out_bar_reg;
reg [9:0] ps1_out_reg,ps1_out_bar_reg;
reg [9:0] ps2_out_reg,ps2_out_bar_reg;
reg [9:0] ps3_out_reg;
reg [9:0] ps4_out_reg;
reg [9:0] ps5_out_reg;
reg [9:0] ps6_out_reg;
reg [9:0] ps7_out_reg;
reg [9:0] ps8_out_reg;
reg [9:0] ps9_out_reg;
reg [9:0] ps10_out_reg;
reg [9:0] ps11_out_reg;
wire [9:0] ps_fsr_in,ps_fsr_in_bar;
wire [9:0] ps_fsr_dtm_in,ps_fsr_dtm_in_bar;
assign ps0_out=ps0_out_reg;
assign ps0_out_bar=ps0_out_bar_reg;
assign ps1_out_bar=ps1_out_bar_reg;
assign ps2_out_bar=ps2_out_bar_reg;
assign ps1_out=ps1_out_reg;
assign ps2_out=ps2_out_reg;
assign ps3_out=ps3_out_reg;
assign ps4_out=ps4_out_reg;
assign ps5_out=ps5_out_reg;
assign ps6_out=ps6_out_reg;
assign ps7_out=ps7_out_reg;
assign ps8_out=ps8_out_reg;
assign ps9_out=ps9_out_reg;
assign ps10_out=ps10_out_reg;
assign ps11_out=ps11_out_reg;
reg [11:0] reg0_dtm,reg1_dtm,reg2_dtm;
`ifdef AXIS_FBDIMM_NO_FSR
wire [11:0] reg0,reg0_b;
wire [11:0] reg1,reg1_b;
wire [11:0] reg2,reg2_b;
wire [11:0] reg3,reg3_b;
wire [11:0] reg4,reg4_b;
wire [11:0] reg5,reg5_b;
wire [11:0] reg6,reg6_b;
wire [11:0] reg7,reg7_b;
wire [11:0] reg8,reg8_b;
wire [11:0] reg9,reg9_b;
`else
reg [11:0] reg0,reg0_b;
reg [11:0] reg1,reg1_b;
reg [11:0] reg2,reg2_b;
reg [11:0] reg3,reg3_b;
reg [11:0] reg4,reg4_b;
reg [11:0] reg5,reg5_b;
reg [11:0] reg6,reg6_b;
reg [11:0] reg7,reg7_b;
reg [11:0] reg8,reg8_b;
reg [11:0] reg9,reg9_b;
`endif
reg header_detected;
reg header_detected_dtm;
reg dtm_seq_host_started;
reg calibrate_detected;
reg [3:0] prev_counter,fsr_counter,prev_counter_dtm,lock_counter,lock_counter_dtm;
reg [3:0] prev_counter2,fsr_counter2,lock_counter2;
reg [3:0] prev_counter2_dtm,lock_counter2_dtm;
reg sequence_start;
reg sequence_start_dtm;
reg bypass_init;
wire frm_boundary;
wire frm_boundary_dtm;
wire frm_begin_dtm;
wire frm_begin_nb;
assign ref_clk = !sequence_start ? link_clk : frm_boundary;
assign init_seq_started=sequence_start | calibrate_detected;
`ifdef DTM_ENABLED
assign frm_boundary_nb = ( fsr_counter == lock_counter );
`else
assign frm_boundary_nb = ref_clk;
`endif
`ifdef AXIS_FBDIMM_NO_FSR
assign sb_decode_clk = link_clk;
`else
assign sb_decode_clk =
(lock_counter == 4'h1 ) ? ( fsr_counter == 4'hc ) | ( fsr_counter == 4'hb ) | ( fsr_counter == 4'h8 ) | ( fsr_counter == 4'h7 ) | ( fsr_counter == 4'h4 ) | ( fsr_counter == 4'h3 ) :
(lock_counter == 4'h2 ) ? ( fsr_counter == 4'h1 ) | ( fsr_counter == 4'hc ) | ( fsr_counter == 4'h9 ) | ( fsr_counter == 4'h8 ) | ( fsr_counter == 4'h5 ) | ( fsr_counter == 4'h4 ) :
(lock_counter == 4'h3 ) ? ( fsr_counter == 4'h2 ) | ( fsr_counter == 4'h1 ) | ( fsr_counter == 4'ha ) | ( fsr_counter == 4'h9 ) | ( fsr_counter == 4'h6 ) | ( fsr_counter == 4'h5 ) :
(lock_counter == 4'h4 ) ? ( fsr_counter == 4'h3 ) | ( fsr_counter == 4'h2 ) | ( fsr_counter == 4'hb ) | ( fsr_counter == 4'ha ) | ( fsr_counter == 4'h7 ) | ( fsr_counter == 4'h6 ) :
(lock_counter == 4'h5 ) ? ( fsr_counter == 4'h4 ) | ( fsr_counter == 4'h3 ) | ( fsr_counter == 4'hc ) | ( fsr_counter == 4'hb ) | ( fsr_counter == 4'h8 ) | ( fsr_counter == 4'h7 ) :
(lock_counter == 4'h6 ) ? ( fsr_counter == 4'h5 ) | ( fsr_counter == 4'h4 ) | ( fsr_counter == 4'h1 ) | ( fsr_counter == 4'hc ) | ( fsr_counter == 4'h9 ) | ( fsr_counter == 4'h8 ) :
(lock_counter == 4'h7 ) ? ( fsr_counter == 4'h6 ) | ( fsr_counter == 4'h5 ) | ( fsr_counter == 4'h2 ) | ( fsr_counter == 4'h1 ) | ( fsr_counter == 4'ha ) | ( fsr_counter == 4'h9 ) :
(lock_counter == 4'h8 ) ? ( fsr_counter == 4'h7 ) | ( fsr_counter == 4'h6 ) | ( fsr_counter == 4'h3 ) | ( fsr_counter == 4'h2 ) | ( fsr_counter == 4'hb ) | ( fsr_counter == 4'ha ) :
(lock_counter == 4'h9 ) ? ( fsr_counter == 4'h8 ) | ( fsr_counter == 4'h7 ) | ( fsr_counter == 4'h4 ) | ( fsr_counter == 4'h3 ) | ( fsr_counter == 4'hc ) | ( fsr_counter == 4'hb ) :
(lock_counter == 4'ha ) ? ( fsr_counter == 4'h9 ) | ( fsr_counter == 4'h8 ) | ( fsr_counter == 4'h5 ) | ( fsr_counter == 4'h4 ) | ( fsr_counter == 4'h1 ) | ( fsr_counter == 4'hc ) :
(lock_counter == 4'hb ) ? ( fsr_counter == 4'ha ) | ( fsr_counter == 4'h9 ) | ( fsr_counter == 4'h6 ) | ( fsr_counter == 4'h5 ) | ( fsr_counter == 4'h2 ) | ( fsr_counter == 4'h1 ) :
(lock_counter == 4'hc ) ? ( fsr_counter == 4'hb ) | ( fsr_counter == 4'ha ) | ( fsr_counter == 4'h7 ) | ( fsr_counter == 4'h6 ) | ( fsr_counter == 4'h3 ) | ( fsr_counter == 4'h2 ) :
1'h0;
`endif
reg dtm_enabled;
assign dtm_enabled_out = dtm_enabled;
initial begin
dtm_enabled=0;
end
`ifdef AXIS_FBDIMM_HW
`else
`ifdef FBDIMM_BUG_107438
always@(posedge link_clk)
dtm_enabled <= tb_top.start_mcu_dtm_training;
//dtm_enabled <= tb_top.cpu.mcu0.ccu_serdes_dtm; // & ~(tb_top.cpu.mcu0.drif.drif_init);
`endif
// DTM training module
dtm_training dtm_ts0_tr(.link_clk (link_clk),
.ps (ps_in),
.ps_bar (ps_in_bar),
.dtm_ps (ps_fsr_dtm_in),
.rst (dtm_rst),
.dtm_ps_bar (ps_fsr_dtm_in_bar),
.dtm_enabled (dtm_enabled),
.tr_complete (dtm_tr_complete));
`endif
assign ps_fsr_in = ( dtm_enabled & !dtm_tr_complete) ? ps_fsr_dtm_in : ps_in;
assign ps_fsr_in_bar = ( dtm_enabled & !dtm_tr_complete) ? ps_fsr_dtm_in_bar : ps_in_bar;
//assign ps_fsr_in = ps_in;
//assign ps_fsr_in_bar = ps_in_bar;
reg [4:0] nop_cnt;
reg nop_frm_detected_reg;
always@(posedge header_detected_dtm ) if ( sequence_start)
dtm_seq_host_started <= 1;
else
dtm_seq_host_started <= 0;
always@(posedge link_clk) if ( dtm_seq_host_started )
begin
if ( ps_in == 10'h0)
nop_cnt <= nop_cnt + 1;
else
nop_cnt <= 0;
if ( nop_cnt == 10'd11 )
nop_frm_detected_reg<=1;
end
else begin
nop_cnt<=0;
nop_frm_detected_reg<=0;
end
assign nop_frame_detected = nop_frm_detected_reg;
`ifdef AXIS_FBDIMM_NO_FSR
always@(posedge link_clk)
begin
if ( fsr_counter == 4'h1 )
fsr_counter = 4'h3;
else
fsr_counter = fsr_counter - 1;
if ( fsr_counter2 == 4'h1 )
fsr_counter2 = 4'h2;
else
fsr_counter2 = fsr_counter2 - 1;
end
`else
always@(posedge link_clk)
begin
if ( fsr_counter == 4'h1 )
fsr_counter = 4'hc;
else
fsr_counter = fsr_counter - 1;
if ( fsr_counter2 == 4'h1 )
fsr_counter2 = 4'h6;
else
fsr_counter2 = fsr_counter2 - 1;
end
`endif
initial begin
dtm_seq_host_started=0;
if ( $test$plusargs("bypass_init")) begin
sequence_start = 1;
`ifdef STINGRAY
lock_counter=4'h7;
`else
lock_counter=4'h1;
`endif
bypass_init = 1;
end else begin
sequence_start = 0;
sequence_start_dtm = 0;
// lock_counter=4'h1;
bypass_init = 0;
end
end
//always@(posedge link_clk )
`ifdef AXIS_FBDIMM_NO_FSR
always@(negedge ref_clk )
if ( reg0 == reg0_b )
sequence_start <= 0;
else if (header_detected)
sequence_start <= 1;
`else
always@(negedge link_clk )
if ( ps_fsr_in == ps_fsr_in_bar )
sequence_start <= 0;
else if (header_detected)
sequence_start <= 1;
always@(negedge link_clk )
if ( ps_fsr_in == ps_fsr_in_bar )
sequence_start_dtm <= 0;
else if (header_detected_dtm)
sequence_start_dtm <= 1;
`endif
assign frm_boundary_dtm = ( fsr_counter == lock_counter_dtm );
assign frm_begin_nb = frm_begin;
assign frm_boundary = (dtm_enabled & dtm_tr_complete ) ? frm_boundary_dtm : ( fsr_counter == lock_counter );
//assign frm_boundary = ( fsr_counter == lock_counter );
`ifdef DTM_ENABLED
assign frm_begin = ( lock_counter2_dtm == 4'h6 ) ? ( fsr_counter2 == 4'h1) : ( fsr_counter2 == lock_counter2_dtm+1 );
`else
assign frm_begin = ( fsr_counter2 == lock_counter2 );
`endif
always@(negedge link_clk) if ( ~bypass_init )
begin
if (header_detected ) begin
lock_counter2 <= prev_counter2;
lock_counter <= prev_counter;
end
else begin
prev_counter <= fsr_counter;
prev_counter2 <= fsr_counter2;
end
if ( header_detected_dtm ) begin
lock_counter2_dtm <= prev_counter2_dtm;
lock_counter_dtm <= prev_counter_dtm;
end
else begin
prev_counter2_dtm <= fsr_counter2;
prev_counter_dtm <= fsr_counter;
end
`ifdef STINGRAY
if ( (reg0 == 12'hfff) &&
(reg1 == 12'hfff) &&
(reg2 == 12'hfff) && !calibrate_detected)
begin
// header_detected <= 1;
lock_counter2 <= prev_counter2;
lock_counter <= prev_counter;
calibrate_detected <= 1;
end
`endif
end
initial calibrate_detected=0;
wire sb_2of3_ok;
voting_logic test_sb_lane (.a ( reg0 == 12'hbfe ),
.b ( reg1 == 12'hbfe ),
.c ( reg2 == 12'hbfe ),
.out ( sb_2of3_ok ));
voting_logic test_sb_lane_dtm (.a ( reg0_dtm == 12'hbfe ),
.b ( reg1_dtm == 12'hbfe ),
.c ( reg2_dtm == 12'hbfe ),
.out ( sb_2of3_ok_dtm ));
//always@(posedge link_clk)
always@(negedge link_clk) if ( ~sequence_start_dtm )
begin
if ( sb_2of3_ok_dtm )
header_detected_dtm <= 1;
else
header_detected_dtm <= 0;
end
always@(posedge link_clk) if ( ~bypass_init & ~sequence_start)
begin
if ( sb_2of3_ok )
header_detected <= 1;
else
header_detected <= 0;
end
initial begin
lock_counter = 4'h0;
lock_counter_dtm = 4'h0;
fsr_counter=4'h7;
fsr_counter2=4'hc;
header_detected=1'b0;
sequence_start=1'b0;
sequence_start_dtm=1'b0;
reg0_dtm=0;
reg1_dtm=0;
reg2_dtm=0;
end
`ifdef AXIS_FBDIMM_NO_FSR
//`include "fbdimm_fsr_xmr.vh"
`else
always@(negedge link_clk)
begin
reg0_dtm <= { ps_in[0], reg0_dtm[11:1]};
reg1_dtm <= { ps_in[1], reg1_dtm[11:1]};
reg2_dtm <= { ps_in[2], reg2_dtm[11:1]};
reg0[11:0] <= { ps_fsr_in[0], reg0[11:1]};
reg1[11:0] <= { ps_fsr_in[1], reg1[11:1]};
reg2[11:0] <= { ps_fsr_in[2], reg2[11:1]};
reg3[11:0] <= { ps_fsr_in[3], reg3[11:1]};
reg4[11:0] <= { ps_fsr_in[4], reg4[11:1]};
reg5[11:0] <= { ps_fsr_in[5], reg5[11:1]};
reg6[11:0] <= { ps_fsr_in[6], reg6[11:1]};
reg7[11:0] <= { ps_fsr_in[7], reg7[11:1]};
reg8[11:0] <= { ps_fsr_in[8], reg8[11:1]};
reg9[11:0] <= { ps_fsr_in[9], reg9[11:1]};
reg0_b[11:0] <= { ps_fsr_in_bar[0], reg0_b[11:1]};
reg1_b[11:0] <= { ps_fsr_in_bar[1], reg1_b[11:1]};
reg2_b[11:0] <= { ps_fsr_in_bar[2], reg2_b[11:1]};
reg3_b[11:0] <= { ps_fsr_in_bar[3], reg3_b[11:1]};
reg4_b[11:0] <= { ps_fsr_in_bar[4], reg4_b[11:1]};
reg5_b[11:0] <= { ps_fsr_in_bar[5], reg5_b[11:1]};
reg6_b[11:0] <= { ps_fsr_in_bar[6], reg6_b[11:1]};
reg7_b[11:0] <= { ps_fsr_in_bar[7], reg7_b[11:1]};
reg8_b[11:0] <= { ps_fsr_in_bar[8], reg8_b[11:1]};
reg9_b[11:0] <= { ps_fsr_in_bar[9], reg9_b[11:1]};
if ( ref_clk) begin
ps0_out_bar_reg <= {reg9_b[1],reg8_b[1],reg7_b[1],reg6_b[1],reg5_b[1],reg4_b[1],reg3_b[1],reg2_b[1],reg1_b[1],reg0_b[1]};
ps1_out_bar_reg <= {reg9_b[2],reg8_b[2],reg7_b[2],reg6_b[2],reg5_b[2],reg4_b[2],reg3_b[2],reg2_b[2],reg1_b[2],reg0_b[2]};
ps2_out_bar_reg <= {reg9_b[3],reg8_b[3],reg7_b[3],reg6_b[3],reg5_b[3],reg4_b[3],reg3_b[3],reg2_b[3],reg1_b[3],reg0_b[3]};
ps0_out_reg <= {reg9[1] ,reg8[1],reg7[1],reg6[1],reg5[1],reg4[1],reg3[1],reg2[1],reg1[1],reg0[1]};
ps1_out_reg <= {reg9[2] ,reg8[2],reg7[2],reg6[2],reg5[2],reg4[2],reg3[2],reg2[2],reg1[2],reg0[2]};
ps2_out_reg <= {reg9[3] ,reg8[3],reg7[3],reg6[3],reg5[3],reg4[3],reg3[3],reg2[3],reg1[3],reg0[3]};
ps3_out_reg <= {reg9[4] ,reg8[4],reg7[4],reg6[4],reg5[4],reg4[4],reg3[4],reg2[4],reg1[4],reg0[4]};
ps4_out_reg <= {reg9[5] ,reg8[5],reg7[5],reg6[5],reg5[5],reg4[5],reg3[5],reg2[5],reg1[5],reg0[5]};
ps5_out_reg <= {reg9[6] ,reg8[6],reg7[6],reg6[6],reg5[6],reg4[6],reg3[6],reg2[6],reg1[6],reg0[6]};
ps6_out_reg <= {reg9[7] ,reg8[7],reg7[7],reg6[7],reg5[7],reg4[7],reg3[7],reg2[7],reg1[7],reg0[7]};
ps7_out_reg <= {reg9[8] ,reg8[8],reg7[8],reg6[8],reg5[8],reg4[8],reg3[8],reg2[8],reg1[8],reg0[8]};
ps8_out_reg <= {reg9[9] ,reg8[9],reg7[9],reg6[9],reg5[9],reg4[9],reg3[9],reg2[9],reg1[9],reg0[9]};
ps9_out_reg <= {reg9[10] ,reg8[10],reg7[10],reg6[10],reg5[10],reg4[10],reg3[10],reg2[10],reg1[10],reg0[10]};
ps10_out_reg <= {reg9[11] ,reg8[11],reg7[11],reg6[11],reg5[11],reg4[11],reg3[11],reg2[11],reg1[11],reg0[11]};
ps11_out_reg <= ps_fsr_in;
end
end
`endif
`ifdef AXIS_FBDIMM_NO_FSR
always@(negedge ref_clk)
begin
ps0_out_reg <= {reg9[0],reg8[0],reg7[0],reg6[0],reg5[0],reg4[0],reg3[0],reg2[0],reg1[0],reg0[0]};
ps0_out_bar_reg <= {reg9_b[0],reg8_b[0],reg7_b[0],reg6_b[0],reg5_b[0],reg4_b[0],reg3_b[0],reg2_b[0],reg1_b[0],reg0_b[0]};
ps1_out_reg <= {reg9[1],reg8[1],reg7[1],reg6[1],reg5[1],reg4[1],reg3[1],reg2[1],reg1[1],reg0[1]};
ps2_out_reg <= {reg9[2],reg8[2],reg7[2],reg6[2],reg5[2],reg4[2],reg3[2],reg2[2],reg1[2],reg0[2]};
ps3_out_reg <= {reg9[3],reg8[3],reg7[3],reg6[3],reg5[3],reg4[3],reg3[3],reg2[3],reg1[3],reg0[3]};
ps4_out_reg <= {reg9[4],reg8[4],reg7[4],reg6[4],reg5[4],reg4[4],reg3[4],reg2[4],reg1[4],reg0[4]};
ps5_out_reg <= {reg9[5],reg8[5],reg7[5],reg6[5],reg5[5],reg4[5],reg3[5],reg2[5],reg1[5],reg0[5]};
ps6_out_reg <= {reg9[6],reg8[6],reg7[6],reg6[6],reg5[6],reg4[6],reg3[6],reg2[6],reg1[6],reg0[6]};
ps7_out_reg <= {reg9[7],reg8[7],reg7[7],reg6[7],reg5[7],reg4[7],reg3[7],reg2[7],reg1[7],reg0[7]};
ps8_out_reg <= {reg9[8],reg8[8],reg7[8],reg6[8],reg5[8],reg4[8],reg3[8],reg2[8],reg1[8],reg0[8]};
ps9_out_reg <= {reg9[9],reg8[9],reg7[9],reg6[9],reg5[9],reg4[9],reg3[9],reg2[9],reg1[9],reg0[9]};
ps10_out_reg <= {reg9[10],reg8[10],reg7[10],reg6[10],reg5[10],reg4[10],reg3[10],reg2[10],reg1[10],reg0[10]};
ps11_out_reg <= {reg9[11],reg8[11],reg7[11],reg6[11],reg5[11],reg4[11],reg3[11],reg2[11],reg1[11],reg0[11]};
end
`endif
endmodule