// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: sb_crc_error_injector.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
// ========== Copyright Header End ============================================
module sb_crc_error_injector( ps_in, ps_out, init, is_bar, link_clk);
input [SB_LINK-1:0] ps_in;
output [SB_LINK-1:0] ps_out;
reg [11:0] ps_crc_period;
reg [15:0] frame_counter;
wire [15:0] crc_clock_period = (ps_crc_freq+ps_crc_period)*6;
reg header_detected,enable_fsm;
reg [3:0] fsr_counter,lock_counter,prev_counter;
reg [3:0] fsr_counter2,lock_counter2;
wire frm_begin,frm_boundary;
assign ps_out = ( UI_counter == 4'h1 ) & crc_en ? ( ps_in ^ ps0_crc_mask ) :
( UI_counter == 4'h2 ) & crc_en ? ( ps_in ^ ps1_crc_mask ) :
( UI_counter == 4'h3 ) & crc_en ? ( ps_in ^ ps2_crc_mask ) :
( UI_counter == 4'h4 ) & crc_en ? ( ps_in ^ ps3_crc_mask ) :
( UI_counter == 4'h5 ) & crc_en ? ( ps_in ^ ps4_crc_mask ) :
( UI_counter == 4'h6 ) & crc_en ? ( ps_in ^ ps5_crc_mask ) :
( UI_counter == 4'h7 ) & crc_en ? ( ps_in ^ ps6_crc_mask ) :
( UI_counter == 4'h8 ) & crc_en ? ( ps_in ^ ps7_crc_mask ) :
( UI_counter == 4'h9 ) & crc_en ? ( ps_in ^ ps8_crc_mask ) :
( UI_counter == 4'ha ) & crc_en ? ( ps_in ^ ps9_crc_mask ) :
( UI_counter == 4'hb ) & crc_en ? ( ps_in ^ ps10_crc_mask ) :
( UI_counter == 4'hc ) & crc_en ? ( ps_in ^ ps11_crc_mask ) : ps_in;
always@(negedge link_clk)
always@(posedge link_clk) if ( start_UI_counter )
if ( UI_counter == 4'hc )
UI_counter <= UI_counter + 4'h1;
if ( $test$plusargs("bypass_init") ) begin
dummy=$value$plusargs("ps0_crc_mask=%h",ps0_crc_mask);
dummy=$value$plusargs("ps1_crc_mask=%h",ps1_crc_mask);
dummy=$value$plusargs("ps2_crc_mask=%h",ps2_crc_mask);
dummy=$value$plusargs("ps3_crc_mask=%h",ps3_crc_mask);
dummy=$value$plusargs("ps4_crc_mask=%h",ps4_crc_mask);
dummy=$value$plusargs("ps5_crc_mask=%h",ps5_crc_mask);
dummy=$value$plusargs("ps6_crc_mask=%h",ps6_crc_mask);
dummy=$value$plusargs("ps7_crc_mask=%h",ps7_crc_mask);
dummy=$value$plusargs("ps8_crc_mask=%h",ps8_crc_mask);
dummy=$value$plusargs("ps9_crc_mask=%h",ps9_crc_mask);
dummy=$value$plusargs("ps10_crc_mask=%h",ps10_crc_mask);
dummy=$value$plusargs("ps11_crc_mask=%h",ps11_crc_mask);
dummy=$value$plusargs("ps_frame_num=%h",ps_frame_num);
dummy=$value$plusargs("ps_crc_freq=%h",ps_crc_freq);
dummy=$value$plusargs("ps_crc_period=%h",ps_crc_period);
reg [47:0] initialization_register_link0;
initial fsr_counter=4'h7;
initial fsr_counter2=4'hd;
always@(posedge link_clk)
if ( fsr_counter == 4'h1 )
fsr_counter = fsr_counter - 1;
if ( fsr_counter2 == 4'h1 )
fsr_counter2 = fsr_counter2 - 1;
assign frm_begin = ( fsr_counter2 == lock_counter2 );
assign frm_boundary = (fsr_counter2 == lock_counter);
always@(negedge link_clk) if ( ~bypass_init )
lock_counter <= prev_counter;
prev_counter <= fsr_counter2;
reg [9:0] ps0_reg,ps1_reg,ps2_reg,ps3_reg,ps4_reg,ps5_reg,ps6_reg,ps7_reg,ps8_reg,ps9_reg,ps10_reg,ps11_reg;
always@(negedge link_clk)
always@(posedge link_clk) if ( ~bypass_init )
if ( (ps0_reg == 10'h3ff ) &&
(ps10_reg == 10'h3ff ) &&
lock_counter2 <= fsr_counter2;
if( (ps0_reg == 10'h0 ) &&
lock_counter2 <= fsr_counter2;
always@(posedge link_clk) if ( ~bypass_init )
if(is_bar == 1'b0) // Not the sb_bar_crc_error_injector
if ( initialization_register_link0[47:36] == 12'hbfe )
if( initialization_register_link0[47:36] == 12'h401 )
always@(negedge link_clk)
initialization_register_link0[47:0] <= { ps_in[0], initialization_register_link0[47:1]};
always@(posedge link_clk) if ( ~init && (( ps_frame_num !== 0 ) && (crc_clock_period !== 0 )) )
if ( frame_counter !== crc_clock_period )
if ( frame_counter < (ps_crc_freq*12) )
frame_counter=frame_counter+1;
end if ( frame_counter == crc_clock_period )
if ( tr_counter == 4'hc ) begin
// If ps_frame_num is FFF, then all frames will have the same crc
if ( ps_frame_num == 12'hfff ) begin
// If ps_frame_num is non-zero, N number of frames will have crc errors
// then crc will be turned off
else if ( ps_frame_num !== 0 ) begin
ps_frame_num = ps_frame_num - 1;