-
Notifications
You must be signed in to change notification settings - Fork 191
Expand file tree
/
Copy pathecc_encode.sv
More file actions
78 lines (71 loc) · 2.83 KB
/
ecc_encode.sv
File metadata and controls
78 lines (71 loc) · 2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// Copyright 2020 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this 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.
//
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
/// # ECC Encoder
///
/// Implements SECDED (Single Error Correction, Double Error Detection) Hamming Code
/// with extended parity bit [1].
/// The module receives a data word and encodes it using above mentioned error
/// detection and correction code. The corresponding decode module
/// can be found in `ecc_decode.sv`
///
/// [1] https://en.wikipedia.org/wiki/Hamming_code
module ecc_encode import ecc_pkg::*; #(
/// Data width of unencoded word.
parameter int unsigned DataWidth = 64,
// Do not change
parameter type data_t = logic [DataWidth-1:0],
parameter type parity_t = logic [get_parity_width(DataWidth)-1:0],
parameter type code_word_t = logic [get_cw_width(DataWidth)-1:0],
parameter type encoded_data_t = struct packed {
logic parity;
code_word_t code_word;
}
) (
/// Unencoded data in
input data_t data_i,
/// Encoded data out
output encoded_data_t data_o
);
parity_t parity_code_word;
code_word_t data, codeword;
// Expand incoming data to codeword width
always_comb begin : expand_data
automatic int unsigned idx;
data = '0;
idx = 0;
for (int unsigned i = 1; i < unsigned'($bits(code_word_t)) + 1; i++) begin
// if it is not a power of two word it is a normal data index
if (unsigned'(2**$clog2(i)) != i) begin
data[i - 1] = data_i[idx];
idx++;
end
end
end
// calculate code word
always_comb begin : calculate_syndrome
parity_code_word = 0;
for (int unsigned i = 0; i < unsigned'($bits(parity_t)); i++) begin
for (int unsigned j = 1; j < unsigned'($bits(code_word_t)) + 1; j++) begin
if (|(unsigned'(2**i) & j)) parity_code_word[i] = parity_code_word[i] ^ data[j - 1];
end
end
end
// fuse the final codeword
always_comb begin : generate_codeword
codeword = data;
for (int unsigned i = 0; i < unsigned'($bits(parity_t)); i++) begin
codeword[2**i-1] = parity_code_word[i];
end
end
assign data_o.code_word = codeword;
assign data_o.parity = ^codeword;
endmodule