Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / spc / tlu / rtl / tlu_ecd_dp.v
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: tlu_ecd_dp.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 tlu_ecd_dp (
data_in,
ecc_in,
cerer_ce,
cerer_ue,
syndrome,
cecc_err,
uecc_err,
uecc_err_);
wire [67:0] d;
wire [7:0] e;
wire [37:0] check0_bus;
wire check0_4;
wire check0_3;
wire check0_2;
wire check0_1;
wire check0_0;
wire c0;
wire [37:0] check1_bus;
wire check1_4;
wire check1_3;
wire check1_2;
wire check1_1;
wire check1_0;
wire c1;
wire [35:0] check2_bus;
wire check2_4;
wire check2_3;
wire check2_2;
wire check2_1;
wire check2_0;
wire c2;
wire [35:0] check3_bus;
wire check3_4;
wire check3_3;
wire check3_2;
wire check3_1;
wire check3_0;
wire c3;
wire [31:0] check4_bus;
wire c4;
wire [31:0] check5_bus;
wire c5;
wire [11:0] check6_bus;
wire c6;
wire [74:0] check7_bus;
wire check7_4;
wire check7_3;
wire check7_2;
wire check7_1;
wire check7_0;
wire c7;
wire [7:7] e_;
wire c7_;
wire parity_incorrect;
wire parity_correct;
wire ecc_err_0;
wire ecc_err_1;
wire ecc_err_2;
wire ecc_err;
input [67:0] data_in; // Used for generation and checking
input [7:0] ecc_in; // Used for checking only
input cerer_ce;
input cerer_ue;
output [7:0] syndrome; // Used for generation and checking
output cecc_err; // Used for checking only; unused for gen
output uecc_err; // Used for checking only; unused for gen
output uecc_err_; // Used for checking only; unused for gen
//////////////////////////////////////////////////////////////////////////////
// Position Binary
// 1 0000001 C0
// 2 0000010 C1
// 3 0000011 D0
//
// 4 0000100 C2
// 5 0000101 D1
// 6 0000110 D2
// 7 0000111 D3
//
// 8 0001000 C3
// 9 0001001 D4
// 10 0001010 D5
// 11 0001011 D6
// 12 0001100 D7
// ... ...
// 15 0001111 D10
//
// 16 0010000 C4
// 17 0010001 D11
// ... ...
// 20 0010100 D14
// ... ...
// 24 0011000 D18
// ... ...
// 28 0011100 D22
// ... ...
// 31 0011111 D25
//
// 32 0100000 C5
// 33 0100001 D26
// ... ...
// 36 0100100 D29
// ... ...
// 40 0101000 D33
// ... ...
// 44 0101100 D37
// ... ...
// 48 0110000 D41
// ... ...
// 52 0110100 D45
// ... ...
// 56 0111000 D49
// ... ...
// 60 0111100 D53
// ... ...
// 63 0111111 D56
//
// 64 1000000 C6
// 65 1000001 D57
// ... ...
// 68 1000100 D60
// ... ...
// 72 1001000 D64
// 73 1001001 D65
// 74 1001010 D66
// 75 1001011 D67
//
// 76 1001100 C7
assign d[67:0] =
data_in[67:0];
assign e[7:0] =
ecc_in[7:0];
// All odd positions (LSB of position set)
assign check0_bus[37:0] =
{d[67], d[65], d[63], d[61], d[59], d[57],
d[56], d[54], d[52], d[50], d[48], d[46], d[44], d[42],
d[40], d[38], d[36], d[34], d[32], d[30], d[28], d[26],
d[25], d[23], d[21], d[19], d[17], d[15], d[13], d[11],
d[10], d[8], d[6], d[4],
d[3], d[1],
d[0],
e[0]};
tlu_ecd_dp_prty_macro__width_8 check0_4_pty (
.din (check0_bus [37:30] ),
.dout (check0_4 )
);
tlu_ecd_dp_prty_macro__width_8 check0_3_pty (
.din (check0_bus [29:22] ),
.dout (check0_3 )
);
tlu_ecd_dp_prty_macro__width_8 check0_2_pty (
.din (check0_bus [21:14] ),
.dout (check0_2 )
);
tlu_ecd_dp_prty_macro__width_8 check0_1_pty (
.din (check0_bus [13:6] ),
.dout (check0_1 )
);
tlu_ecd_dp_prty_macro__width_8 check0_0_pty (
.din ({check0_bus [5:0],
{2 {1'b0}} }),
.dout (check0_0 )
);
tlu_ecd_dp_prty_macro__width_8 check0_pty (
.din ({check0_4 ,
check0_3 ,
check0_2 ,
check0_1 ,
check0_0 ,
{3 {1'b0}} }),
.dout (c0 )
);
// All positions with secondmost LSB set
assign check1_bus[37:0] =
{d[67:66], d[63:62], d[59:58],
d[56:55], d[52:51], d[48:47], d[44:43],
d[40:39], d[36:35], d[32:31], d[28:27],
d[25:24], d[21:20], d[17:16], d[13:12],
d[10:9], d[6:5],
d[3:2],
d[0],
e[1]};
tlu_ecd_dp_prty_macro__width_8 check1_4_pty (
.din (check1_bus [37:30] ),
.dout (check1_4 )
);
tlu_ecd_dp_prty_macro__width_8 check1_3_pty (
.din (check1_bus [29:22] ),
.dout (check1_3 )
);
tlu_ecd_dp_prty_macro__width_8 check1_2_pty (
.din (check1_bus [21:14] ),
.dout (check1_2 )
);
tlu_ecd_dp_prty_macro__width_8 check1_1_pty (
.din (check1_bus [13:6] ),
.dout (check1_1 )
);
tlu_ecd_dp_prty_macro__width_8 check1_0_pty (
.din ({check1_bus [5:0],
{2 {1'b0}} }),
.dout (check1_0 )
);
tlu_ecd_dp_prty_macro__width_8 check1_pty (
.din ({check1_0 ,
check1_1 ,
check1_2 ,
check1_3 ,
check1_4 ,
{3 {1'b0}} }),
.dout (c1 )
);
// All positions with thirdmost LSB set
assign check2_bus[35:0] =
{d[63:60],
d[56:53], d[48:45], d[40:37], d[32:29],
d[25:22], d[17:14],
d[10:7],
d[3:1],
e[2]};
tlu_ecd_dp_prty_macro__width_8 check2_4_pty (
.din ({1'b0,
check2_bus [35:29]}),
.dout (check2_4 )
);
tlu_ecd_dp_prty_macro__width_8 check2_3_pty (
.din (check2_bus [28:21] ),
.dout (check2_3 )
);
tlu_ecd_dp_prty_macro__width_8 check2_2_pty (
.din (check2_bus [20:13] ),
.dout (check2_2 )
);
tlu_ecd_dp_prty_macro__width_8 check2_1_pty (
.din (check2_bus [12:5] ),
.dout (check2_1 )
);
tlu_ecd_dp_prty_macro__width_8 check2_0_pty (
.din ({check2_bus [4:0],
{3 {1'b0}} }),
.dout (check2_0 )
);
tlu_ecd_dp_prty_macro__width_8 check2_pty (
.din ({check2_0 ,
check2_1 ,
check2_2 ,
check2_3 ,
check2_4 ,
{3 {1'b0}} }),
.dout (c2 )
);
// All positions with fourthmost LSB set
assign check3_bus[35:0] =
{d[67:64],
d[56:49], d[40:33],
d[25:18],
d[10:4],
e[3]};
tlu_ecd_dp_prty_macro__width_8 check3_4_pty (
.din ({{1 {1'b0}} ,
check3_bus [35:29]}),
.dout (check3_4 )
);
tlu_ecd_dp_prty_macro__width_8 check3_3_pty (
.din (check3_bus [28:21] ),
.dout (check3_3 )
);
tlu_ecd_dp_prty_macro__width_8 check3_2_pty (
.din (check3_bus [20:13] ),
.dout (check3_2 )
);
tlu_ecd_dp_prty_macro__width_8 check3_1_pty (
.din (check3_bus [12:5] ),
.dout (check3_1 )
);
tlu_ecd_dp_prty_macro__width_8 check3_0_pty (
.din ({check3_bus [4:0],
{3 {1'b0}} }),
.dout (check3_0 )
);
tlu_ecd_dp_prty_macro__width_8 check3_pty (
.din ({check3_0 ,
check3_1 ,
check3_2 ,
check3_3 ,
check3_4 ,
{3 {1'b0}} }),
.dout (c3 )
);
// All positions with fifthmost LSB set
assign check4_bus[31:0] =
{d[56:41],
d[25:11],
e[4]};
tlu_ecd_dp_prty_macro__width_32 check4_pty (
.din (check4_bus [31:0] ),
.dout (c4 )
);
// All positions with sixthmost LSB set
assign check5_bus[31:0] =
{d[56:26],
e[5]};
tlu_ecd_dp_prty_macro__width_32 check5_pty (
.din (check5_bus [31:0] ),
.dout (c5 )
);
// All positions with seventhmost LSB set
assign check6_bus[11:0] =
{d[67:57],
e[6]};
tlu_ecd_dp_prty_macro__width_16 check6_pty (
.din ({{4 {1'b0}} ,
check6_bus [11:0]}),
.dout (c6 )
);
// Parity of the whole word (including ECC bits)
// Then xnor with e[07] to check the parity
// (or in this case, xor with e[07] to get miscompare)
assign check7_bus[74:0] =
{d[67:0], e[6:0]};
tlu_ecd_dp_prty_macro__width_16 check7_4_pty (
.din ({{5 {1'b0}} ,
check7_bus [74:64]}),
.dout (check7_4 )
);
tlu_ecd_dp_prty_macro__width_16 check7_3_pty (
.din (check7_bus [63:48] ),
.dout (check7_3 )
);
tlu_ecd_dp_prty_macro__width_16 check7_2_pty (
.din (check7_bus [47:32] ),
.dout (check7_2 )
);
tlu_ecd_dp_prty_macro__width_16 check7_1_pty (
.din (check7_bus [31:16] ),
.dout (check7_1 )
);
tlu_ecd_dp_prty_macro__width_16 check7_0_pty (
.din (check7_bus [15:0] ),
.dout (check7_0 )
);
tlu_ecd_dp_prty_macro__width_8 check7_inv_pty (
.din ({{2 {1'b0}} ,
e [7 ],
check7_0 ,
check7_1 ,
check7_2 ,
check7_3 ,
check7_4 }),
.dout (c7 )
);
tlu_ecd_dp_inv_macro__width_1 e7_inv (
.din (e [7 ] ),
.dout (e_ [7 ] )
);
tlu_ecd_dp_prty_macro__width_8 check7_pty (
.din ({{2 {1'b0}} ,
e_ [7 ],
check7_0 ,
check7_1 ,
check7_2 ,
check7_3 ,
check7_4 }),
.dout (c7_ )
);
assign parity_incorrect =
c7;
assign parity_correct =
c7_;
assign syndrome[7:0] =
{c7, c6, c5, c4, c3, c2, c1, c0};
// If the syndrome is zero and overall parity is correct, then no errors
// If overall parity is incorrect, then correctable
//assign cecc_err =
// c7;
// If overall parity is correct and the syndrome is nonzero, then uncorrectable
//assign uecc_err =
// (| ecc_out[06:00]) & ~c7;
// Also need to factor in CERER bits
tlu_ecd_dp_nor_macro__ports_3__width_1 ecc_err_2_nor (
.din0 (syndrome [6] ),
.din1 (syndrome [5] ),
.din2 (syndrome [4] ),
.dout (ecc_err_0 )
);
tlu_ecd_dp_nor_macro__ports_2__width_1 ecc_err_1_nor (
.din0 (syndrome [3] ),
.din1 (syndrome [2] ),
.dout (ecc_err_1 )
);
tlu_ecd_dp_nor_macro__ports_2__width_1 ecc_err_0_nor (
.din0 (syndrome [1] ),
.din1 (syndrome [0] ),
.dout (ecc_err_2 )
);
tlu_ecd_dp_nand_macro__ports_3__width_1 ecc_err_nand (
.din0 (ecc_err_0 ),
.din1 (ecc_err_1 ),
.din2 (ecc_err_2 ),
.dout (ecc_err )
);
tlu_ecd_dp_and_macro__ports_2__width_1 cecc_err_and (
.din0 (parity_incorrect ),
.din1 (cerer_ce ),
.dout (cecc_err )
);
tlu_ecd_dp_and_macro__ports_3__width_1 uecc_err_and (
.din0 (ecc_err ),
.din1 (parity_correct ),
.din2 (cerer_ue ),
.dout (uecc_err )
);
tlu_ecd_dp_nand_macro__ports_3__width_1 uecc_err_nand (
.din0 (ecc_err ),
.din1 (parity_correct ),
.din2 (cerer_ue ),
.dout (uecc_err_ )
);
supply0 vss; // <- port for ground
supply1 vdd; // <- port for power
endmodule
//
// parity macro (even parity)
//
//
module tlu_ecd_dp_prty_macro__width_8 (
din,
dout);
input [7:0] din;
output dout;
prty #(8) m0_0 (
.in(din[7:0]),
.out(dout)
);
endmodule
//
// parity macro (even parity)
//
//
module tlu_ecd_dp_prty_macro__width_32 (
din,
dout);
input [31:0] din;
output dout;
prty #(32) m0_0 (
.in(din[31:0]),
.out(dout)
);
endmodule
//
// parity macro (even parity)
//
//
module tlu_ecd_dp_prty_macro__width_16 (
din,
dout);
input [15:0] din;
output dout;
prty #(16) m0_0 (
.in(din[15:0]),
.out(dout)
);
endmodule
//
// invert macro
//
//
module tlu_ecd_dp_inv_macro__width_1 (
din,
dout);
input [0:0] din;
output [0:0] dout;
inv #(1) d0_0 (
.in(din[0:0]),
.out(dout[0:0])
);
endmodule
//
// nor macro for ports = 2,3
//
//
module tlu_ecd_dp_nor_macro__ports_3__width_1 (
din0,
din1,
din2,
dout);
input [0:0] din0;
input [0:0] din1;
input [0:0] din2;
output [0:0] dout;
nor3 #(1) d0_0 (
.in0(din0[0:0]),
.in1(din1[0:0]),
.in2(din2[0:0]),
.out(dout[0:0])
);
endmodule
//
// nor macro for ports = 2,3
//
//
module tlu_ecd_dp_nor_macro__ports_2__width_1 (
din0,
din1,
dout);
input [0:0] din0;
input [0:0] din1;
output [0:0] dout;
nor2 #(1) d0_0 (
.in0(din0[0:0]),
.in1(din1[0:0]),
.out(dout[0:0])
);
endmodule
//
// nand macro for ports = 2,3,4
//
//
module tlu_ecd_dp_nand_macro__ports_3__width_1 (
din0,
din1,
din2,
dout);
input [0:0] din0;
input [0:0] din1;
input [0:0] din2;
output [0:0] dout;
nand3 #(1) d0_0 (
.in0(din0[0:0]),
.in1(din1[0:0]),
.in2(din2[0:0]),
.out(dout[0:0])
);
endmodule
//
// and macro for ports = 2,3,4
//
//
module tlu_ecd_dp_and_macro__ports_2__width_1 (
din0,
din1,
dout);
input [0:0] din0;
input [0:0] din1;
output [0:0] dout;
and2 #(1) d0_0 (
.in0(din0[0:0]),
.in1(din1[0:0]),
.out(dout[0:0])
);
endmodule
//
// and macro for ports = 2,3,4
//
//
module tlu_ecd_dp_and_macro__ports_3__width_1 (
din0,
din1,
din2,
dout);
input [0:0] din0;
input [0:0] din1;
input [0:0] din2;
output [0:0] dout;
and3 #(1) d0_0 (
.in0(din0[0:0]),
.in1(din1[0:0]),
.in2(din2[0:0]),
.out(dout[0:0])
);
endmodule