// Copyright 2020 Intel Corporation. // // This software and the related documents are Intel copyrighted materials, // and your use of them is governed by the express license under which they // were provided to you ("License"). Unless the License provides otherwise, // you may not use, modify, copy, publish, distribute, disclose or transmit // this software or the related documents without Intel's prior written // permission. // // This software and the related documents are provided as is, with no express // or implied warranties, other than those that are expressly stated in the // License. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // ACL ECC ENCODER // // This module encodes data using a single error correct, double error detect Hamming code. As the data width get large, // so will the xor network and that would limit fmax. To resolve this, we slice the data into smaller groups and encode // each independently. Essentially we trade off more memory overhead for parity bits in order to limit the fmax // degradation due to ECC. // // The user must specify the data width and the slicing size. From this, one can compute the number of parity bits and // total encoded bits (see the calculations in localparams below). // // Reset: there is no reset. Pipeline stages are purely feed-forward, the intent is that reset will propagate through. // // This module is actually a wrapper around the actual ECC implementation in secded_encoder. Here is the architecture. // For example, suppose DATA_WIDTH is 70 and ECC_GROUP_SIZE is 32, then we will slice input data into 32 + 32 + 6, and // 3 encoders are used to produce 39 + 39 + 11 encoded bits. // // i_data[69:0] // | // +------------------------------------------------------------------------+ // | optional input pipeline stages | // +------------------------------------------------------------------------+ // | | | // data[69:64] data[63:32] data[31:0] // | | | // +----------------+ +----------------+ +----------------+ // | secded_encoder | | secded_encoder | | secded_encoder | // +----------------+ +----------------+ +----------------+ // | | | // encoded[88:78] encoded[77:39] encoded[38:0] // | | | // +------------------------------------------------------------------------+ // | optional output pipeline stages | // +------------------------------------------------------------------------+ // | // o_encoded[88:0] // // Required files: // - dla_acl_ecc_encoder.sv // - dla_acl_ecc_pkg.sv // // Related files (to do the corresponding decoding that this file encodes): // - dla_acl_ecc_decoder.sv // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// `default_nettype none //BEWARE: do not leave the "clock_enable" input port disconnected if any pipeline stages are used, it will default to 0 and nothing will go through module dla_acl_ecc_encoder import dla_acl_ecc_pkg::*; #( parameter int DATA_WIDTH, //number of bits in the unencoded input data parameter int ECC_GROUP_SIZE, //how many bits of unencoded data to group into one ecc block, see description in header comments parameter int INPUT_PIPELINE_STAGES = 0, //number of pipeline stages between i_data and the ecc encoder parameter int OUTPUT_PIPELINE_STAGES = 0 //number of pipeline stages between the ecc encoder and o_encoded ) ( input wire clock, //clock is only needed if pipeline stages are nonzero input wire clock_enable, //set to 1 to sample i_data, intended for integration with altera_syncram, only needed if pipeline stages are nonzero input wire [DATA_WIDTH-1:0] i_data, //unencoded input data output logic [getEncodedBitsEccGroup(DATA_WIDTH,ECC_GROUP_SIZE)-1:0] o_encoded //encoded output data ); //helper functions for determining number of bits are defined in dla_acl_ecc.svh localparam int ECC_NUM_GROUPS = getNumGroups(DATA_WIDTH,ECC_GROUP_SIZE); //how many groups to slice the data into localparam int LAST_GROUP_SIZE = getLastGroupSize(DATA_WIDTH,ECC_GROUP_SIZE); //all groups have size ECC_GROUP_SIZE except possibly the last group which may be smaller since it gets the remaining bits localparam int ENCODED_BITS = getEncodedBitsEccGroup(DATA_WIDTH,ECC_GROUP_SIZE); //internal signals genvar g; logic [DATA_WIDTH-1:0] data; logic [ENCODED_BITS-1:0] encoded; //input pipeline stages generate if (INPUT_PIPELINE_STAGES == 0) begin assign data = i_data; end else begin logic [DATA_WIDTH-1:0] data_pipe [INPUT_PIPELINE_STAGES-1:0]; always_ff @(posedge clock) begin if (clock_enable) data_pipe[0] <= i_data; end for (g=1; g