220 lines
7.9 KiB
Systemverilog
220 lines
7.9 KiB
Systemverilog
/////////////////////////////////////////////////////////////////////
|
|
// ,------. ,--. ,--. //
|
|
// | .--. ' ,---. ,--,--. | | ,---. ,---. `--' ,---. //
|
|
// | '--'.'| .-. |' ,-. | | | | .-. | .-. |,--.| .--' //
|
|
// | |\ \ ' '-' '\ '-' | | '--.' '-' ' '-' || |\ `--. //
|
|
// `--' '--' `---' `--`--' `-----' `---' `- /`--' `---' //
|
|
// `---' //
|
|
// Error Correction and Detection Encoder //
|
|
// Parameterized Extended Hamming Code Encoder //
|
|
// //
|
|
/////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// Copyright (C) 2017 ROA Logic BV //
|
|
// www.roalogic.com //
|
|
// //
|
|
// This source file may be used and distributed without //
|
|
// restriction provided that this copyright statement is not //
|
|
// removed from the file and that any derivative work contains //
|
|
// the original copyright notice and the associated disclaimer. //
|
|
// //
|
|
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //
|
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //
|
|
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //
|
|
// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR OR //
|
|
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, //
|
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT //
|
|
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; //
|
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) //
|
|
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN //
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR //
|
|
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS //
|
|
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //
|
|
// //
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
// +FHDR - Semiconductor Reuse Standard File Header Section -------
|
|
// FILE NAME : ecc_enc.sv
|
|
// DEPARTMENT :
|
|
// AUTHOR : rherveille
|
|
// AUTHOR'S EMAIL :
|
|
// ------------------------------------------------------------------
|
|
// RELEASE HISTORY
|
|
// VERSION DATE AUTHOR DESCRIPTION
|
|
// 1.0 2017-04-07 rherveille initial release
|
|
// ------------------------------------------------------------------
|
|
// KEYWORDS : HAMMING ERROR CORRECTION ENCODER
|
|
// ------------------------------------------------------------------
|
|
// PURPOSE : Adds ECC bits to incoming data
|
|
// ------------------------------------------------------------------
|
|
// PARAMETERS
|
|
// PARAM NAME RANGE DESCRIPTION DEFAULT UNITS
|
|
// K 1+ Information vector size 8
|
|
// P0_LSB 0,1 0: p0 located at MSB 1
|
|
// 1: p0 located at LSB
|
|
// ------------------------------------------------------------------
|
|
// REUSE ISSUES
|
|
// Reset Strategy : none
|
|
// Clock Domains : none
|
|
// Critical Timing :
|
|
// Test Features : na
|
|
// Asynchronous I/F : yes
|
|
// Scan Methodology : na
|
|
// Instantiations : none
|
|
// Synthesizable (y/n) : Yes
|
|
// Other :
|
|
// -FHDR-------------------------------------------------------------
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Hamming codes can detect and correct a single bit error.
|
|
// An extended Hamming code allows detection of double bit errors and
|
|
// correction of single bit errors.
|
|
// This is called SECDED; Single Error Correction, Double Error Detection
|
|
//
|
|
// Number of bits required by a Hamming code: n = m + k
|
|
// n = code length
|
|
// m = number of check bits
|
|
// k = number of information bits
|
|
//
|
|
// Information, parity, and syndrome expressed as vectors:
|
|
// u = Information bit vector
|
|
// p = Parity check bit vector
|
|
// s = Syndrome vector
|
|
//
|
|
// The parity vector is encoded in 'n'.
|
|
// The information bit vector is part of 'p'
|
|
// The syndrome vector needs to be calculated.
|
|
//
|
|
// Bits required:
|
|
// p ranges from 0 to m+k; or p_range=m+k+1
|
|
// As a result 2^m >= m+k+1
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
module ecc_enc #(
|
|
parameter K = 8, //Information bit vector size
|
|
parameter P0_LSB = 1, //0: p0 is located at MSB
|
|
//1: p0 is located at LSB
|
|
|
|
//these should be localparams
|
|
parameter m = calculate_m(K),
|
|
parameter n = m + K
|
|
)
|
|
(
|
|
input [K-1:0] d_i, //information bit vector input
|
|
output [n :0] q_o, //encoded data word output
|
|
|
|
output [m :1] p_o, //parity vector output
|
|
output p0_o //extended parity bit
|
|
);
|
|
|
|
|
|
//---------------------------------------------------------
|
|
// Functions
|
|
//---------------------------------------------------------
|
|
function integer calculate_m;
|
|
input integer k;
|
|
|
|
integer m_local;
|
|
begin
|
|
m_local=1;
|
|
while (2**m_local < m_local+k+1) m_local++;
|
|
|
|
calculate_m = m_local;
|
|
end
|
|
endfunction //calculate_m
|
|
|
|
|
|
function [n:1] store_dbits_in_codeword;
|
|
input [K-1:0] d;
|
|
|
|
integer bit_idx, cw_idx;
|
|
begin
|
|
//This function puts the information bits vector in the correct location
|
|
//Information bits are stored in non-power-of-2 locations
|
|
|
|
//clear all bits
|
|
store_dbits_in_codeword = 0;
|
|
|
|
bit_idx=0; //information vector bit index
|
|
for (cw_idx=1; cw_idx<=n; cw_idx++)
|
|
if (2**$clog2(cw_idx) != cw_idx)
|
|
/* verilator lint_off UNUSEDSIGNAL */
|
|
store_dbits_in_codeword[cw_idx] = d[bit_idx++];
|
|
/* verilator lint_on UNUSEDSIGNAL */
|
|
end
|
|
endfunction //store_dbits_in_codeword
|
|
|
|
|
|
function [m:1] calculate_p;
|
|
input [n:1] cw;
|
|
|
|
integer p_idx, cw_idx;
|
|
begin
|
|
//clear p
|
|
calculate_p = 0;
|
|
|
|
for (p_idx =1; p_idx <=m; p_idx++) //parity-index
|
|
for (cw_idx=1; cw_idx<=n; cw_idx++) //codeword-index
|
|
if (|(2**(p_idx-1) & cw_idx)) calculate_p[p_idx] = calculate_p[p_idx] ^ cw[cw_idx];
|
|
end
|
|
endfunction //calculate_p
|
|
|
|
|
|
function [n:1] store_p_in_codeword;
|
|
input [n:1] cw;
|
|
input [m:1] p;
|
|
|
|
integer i;
|
|
begin
|
|
//databits don't change ... copy into codeword
|
|
store_p_in_codeword = cw;
|
|
|
|
//put parity vector at power-of-2 locations
|
|
for (i=1; i<=m; i=i+1)
|
|
store_p_in_codeword[2**(i-1)] = p[i];
|
|
end
|
|
endfunction //store_p_in_codeword
|
|
|
|
|
|
//---------------------------------------------------------
|
|
// Variables
|
|
//---------------------------------------------------------
|
|
logic [n:1] cw_w_dbits; //codeword with loaded data bits
|
|
logic [n:1] cw; //codeword with information + parity bits
|
|
|
|
|
|
//---------------------------------------------------------
|
|
// Module Body
|
|
//---------------------------------------------------------
|
|
|
|
/*
|
|
Below diagram indicates the locations of the parity and data bits
|
|
in the final 'p' vector.
|
|
It also shows what databits each parity bit operates on
|
|
|
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
|
p1 p2 d1 p4 d2 d3 d4 p8 d5 d6 d7 d8 d9 d10 d11
|
|
p1 x x x x x x x x
|
|
p2 x x x x x x x x
|
|
p4 x x x x x x x x
|
|
p8 x x x x x x x x
|
|
*/
|
|
|
|
//Step 1: Load all databits in codeword
|
|
assign cw_w_dbits = store_dbits_in_codeword(d_i);
|
|
|
|
//Step 2: Calculate p-vector
|
|
assign p_o = calculate_p(cw_w_dbits);
|
|
|
|
//Step 3: Store p-vector in codeword
|
|
assign cw = store_p_in_codeword(cw_w_dbits, p_o);
|
|
|
|
//Step 4: Calculate p0 (extended parity bit)
|
|
// and store it in the codeword
|
|
assign p0_o = ^cw;
|
|
assign q_o = P0_LSB ? {cw,p0_o} : {p0_o,cw};
|
|
|
|
endmodule
|