You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

146 lines
8.5 KiB
Verilog

// © IBM Corp. 2020
// Licensed under the Apache License, Version 2.0 (the "License"), as modified by
// the terms below; you may not use the files in this repository except in
// compliance with the License as modified.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//
// Modified Terms:
//
// 1) For the purpose of the patent license granted to you in Section 3 of the
// License, the "Work" hereby includes implementations of the work of authorship
// in physical form.
//
// 2) Notwithstanding any terms to the contrary in the License, any licenses
// necessary for implementation of the Work that are available from OpenPOWER
// via the Power ISA End User License Agreement (EULA) are explicitly excluded
// hereunder, and may be obtained from OpenPOWER under the terms and conditions
// of the EULA.
//
// Unless required by applicable law or agreed to in writing, the reference design
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
// for the specific language governing permissions and limitations under the License.
//
// Additional rights, including the ability to physically implement a softcore that
// is compliant with the required sections of the Power ISA Specification, are
// available at no cost under the terms of the OpenPOWER Power ISA EULA, which can be
// obtained (along with the Power ISA) here: https://openpowerfoundation.org.
`timescale 1 ns / 1 ns
// Description: XU ECC Generation Macro
//
//*****************************************************************************
module tri_eccgen(
din,
syn
);
parameter REGSIZE = 64;
input [0:REGSIZE+8-(64/REGSIZE)] din;
output [0:8-(64/REGSIZE)] syn;
generate // syndrome bits inverted
if (REGSIZE == 64)
begin : ecc64
wire [0:71] e;
wire [0:22] l1term;
// ====================================================================
// 64 data bits, 8 check bits
// single bit error correction, double bit error detection
// ====================================================================
// ecc matrix description
// ====================================================================
// syn 0 111011010011101001100101101101001100101101001011001101001110100110000000
// syn 1 110110101011010101010101011010101010101010101010101010101101010101000000
// syn 2 101101100110110011001100110110011001100110011001100110011011001100100000
// syn 3 011100011110001111000011110001111000011110000111100001111000111100010000
// syn 4 000011111110000000111111110000000111111110000000011111111000000000001000
// syn 5 000000000001111111111111110000000000000001111111111111111000000000000100
// syn 6 000000000000000000000000001111111111111111111111111111111000000000000010
// syn 7 000000000000000000000000000000000000000000000000000000000111111100000001
assign e[0:71] = din[0:71];
assign l1term[0] = e[0] ^ e[10] ^ e[17] ^ e[21] ^ e[32] ^ e[36] ^ e[44] ^ e[56];
assign l1term[1] = e[22] ^ e[23] ^ e[24] ^ e[25] ^ e[53] ^ e[54] ^ e[55] ^ e[56];
assign l1term[2] = e[1] ^ e[4] ^ e[11] ^ e[23] ^ e[26] ^ e[38] ^ e[46] ^ e[50];
assign l1term[3] = e[2] ^ e[5] ^ e[12] ^ e[24] ^ e[27] ^ e[39] ^ e[47] ^ e[51];
assign l1term[4] = e[3] ^ e[6] ^ e[13] ^ e[25] ^ e[28] ^ e[40] ^ e[48] ^ e[52];
assign l1term[5] = e[7] ^ e[8] ^ e[9] ^ e[10] ^ e[37] ^ e[38] ^ e[39] ^ e[40];
assign l1term[6] = e[14] ^ e[15] ^ e[16] ^ e[17] ^ e[45] ^ e[46] ^ e[47] ^ e[48];
assign l1term[7] = e[18] ^ e[19] ^ e[20] ^ e[21] ^ e[49] ^ e[50] ^ e[51] ^ e[52];
assign l1term[8] = e[7] ^ e[14] ^ e[18] ^ e[29] ^ e[33] ^ e[41] ^ e[53] ^ e[57];
assign l1term[9] = e[58] ^ e[60] ^ e[63] ^ e[64];
assign l1term[10] = e[8] ^ e[15] ^ e[19] ^ e[30] ^ e[34] ^ e[42] ^ e[54] ^ e[57];
assign l1term[11] = e[59] ^ e[61] ^ e[63] ^ e[65];
assign l1term[12] = e[9] ^ e[16] ^ e[20] ^ e[31] ^ e[35] ^ e[43] ^ e[55] ^ e[58];
assign l1term[13] = e[59] ^ e[62] ^ e[63] ^ e[66];
assign l1term[14] = e[1] ^ e[2] ^ e[3] ^ e[29] ^ e[30] ^ e[31] ^ e[32] ^ e[60];
assign l1term[15] = e[61] ^ e[62] ^ e[63] ^ e[67];
assign l1term[16] = e[4] ^ e[5] ^ e[6] ^ e[33] ^ e[34] ^ e[35] ^ e[36] ^ e[68];
assign l1term[17] = e[11] ^ e[12] ^ e[13] ^ e[41] ^ e[42] ^ e[43] ^ e[44] ^ e[69];
assign l1term[18] = e[26] ^ e[27] ^ e[28] ^ e[29] ^ e[30] ^ e[31] ^ e[32] ^ e[33];
assign l1term[19] = e[34] ^ e[35] ^ e[36] ^ e[37] ^ e[38] ^ e[39] ^ e[40] ^ e[41];
assign l1term[20] = e[42] ^ e[43] ^ e[44] ^ e[45] ^ e[46] ^ e[47] ^ e[48] ^ e[49];
assign l1term[21] = e[50] ^ e[51] ^ e[52] ^ e[53] ^ e[54] ^ e[55] ^ e[56] ^ e[70];
assign l1term[22] = e[57] ^ e[58] ^ e[59] ^ e[60] ^ e[61] ^ e[62] ^ e[63] ^ e[71];
assign syn[0] = l1term[0] ^ l1term[2] ^ l1term[3] ^ l1term[8] ^ l1term[9];
assign syn[1] = l1term[0] ^ l1term[2] ^ l1term[4] ^ l1term[10] ^ l1term[11];
assign syn[2] = l1term[0] ^ l1term[3] ^ l1term[4] ^ l1term[12] ^ l1term[13];
assign syn[3] = l1term[1] ^ l1term[5] ^ l1term[6] ^ l1term[14] ^ l1term[15];
assign syn[4] = l1term[1] ^ l1term[5] ^ l1term[7] ^ l1term[16];
assign syn[5] = l1term[1] ^ l1term[6] ^ l1term[7] ^ l1term[17];
assign syn[6] = l1term[18] ^ l1term[19] ^ l1term[20] ^ l1term[21];
assign syn[7] = l1term[22];
end
endgenerate
generate // syndrome bits inverted
if (REGSIZE == 32)
begin : ecc32
wire [0:38] e;
wire [0:13] l1term;
// ====================================================================
// 32 Data Bits, 7 Check bits
// Single bit error correction, Double bit error detection
// ====================================================================
// ECC Matrix Description
// ====================================================================
// Syn 0 111011010011101001100101101101001000000
// Syn 1 110110101011010101010101011010100100000
// Syn 2 101101100110110011001100110110010010000
// Syn 3 011100011110001111000011110001110001000
// Syn 4 000011111110000000111111110000000000100
// Syn 5 000000000001111111111111110000000000010
// Syn 6 000000000000000000000000001111110000001
assign e[0:38] = din[0:38];
assign l1term[0] = e[0] ^ e[1] ^ e[4] ^ e[10] ^ e[11] ^ e[17] ^ e[21] ^ e[23];
assign l1term[1] = e[2] ^ e[3] ^ e[9] ^ e[10] ^ e[16] ^ e[17] ^ e[24] ^ e[25];
assign l1term[2] = e[18] ^ e[19] ^ e[20] ^ e[21] ^ e[22] ^ e[23] ^ e[24] ^ e[25];
assign l1term[3] = e[2] ^ e[5] ^ e[7] ^ e[12] ^ e[14] ^ e[18] ^ e[24] ^ e[26];
assign l1term[4] = e[27] ^ e[29] ^ e[32];
assign l1term[5] = e[3] ^ e[6] ^ e[8] ^ e[13] ^ e[15] ^ e[19] ^ e[25] ^ e[26];
assign l1term[6] = e[28] ^ e[30] ^ e[33];
assign l1term[7] = e[0] ^ e[5] ^ e[6] ^ e[12] ^ e[13] ^ e[20] ^ e[21] ^ e[27];
assign l1term[8] = e[28] ^ e[31] ^ e[34];
assign l1term[9] = e[1] ^ e[7] ^ e[8] ^ e[14] ^ e[15] ^ e[22] ^ e[23] ^ e[29];
assign l1term[10] = e[30] ^ e[31] ^ e[35];
assign l1term[11] = e[4] ^ e[5] ^ e[6] ^ e[7] ^ e[8] ^ e[9] ^ e[10] ^ e[36];
assign l1term[12] = e[11] ^ e[12] ^ e[13] ^ e[14] ^ e[15] ^ e[16] ^ e[17] ^ e[37];
assign l1term[13] = e[26] ^ e[27] ^ e[28] ^ e[29] ^ e[30] ^ e[31] ^ e[38];
assign syn[0] = l1term[0] ^ l1term[3] ^ l1term[4];
assign syn[1] = l1term[0] ^ l1term[5] ^ l1term[6];
assign syn[2] = l1term[1] ^ l1term[7] ^ l1term[8];
assign syn[3] = l1term[1] ^ l1term[9] ^ l1term[10];
assign syn[4] = l1term[2] ^ l1term[11];
assign syn[5] = l1term[2] ^ l1term[12];
assign syn[6] = l1term[13];
end
endgenerate
endmodule