Commit 4f4faa78 authored by Tristan Gingold's avatar Tristan Gingold

radtol: simplify secded_32b_pkg

parent 045bf49c
......@@ -27,16 +27,16 @@ use ieee.std_logic_1164.all;
package secded_32b_pkg is
subtype data_word_t is std_logic_vector (31 downto 0);
subtype syndrome_word_t is std_logic_vector (6 downto 0);
subtype ecc_word_t is std_logic_vector (6 downto 0);
-- Compute the syndrome for DATA.
function f_calc_syndrome (data : data_word_t) return syndrome_word_t;
-- Compute the ECC bits for DATA.
function f_calc_ecc (data : data_word_t) return ecc_word_t;
function f_ecc_errors (syndrome : syndrome_word_t) return std_logic;
function f_ecc_errors (syndrome : ecc_word_t) return std_logic;
function f_ecc_one_error (syndrome : syndrome_word_t) return std_logic;
function f_ecc_one_error (syndrome : ecc_word_t) return std_logic;
function f_fix_error (syndrome : syndrome_word_t;
function f_fix_error (syndrome : ecc_word_t;
data : std_logic_vector (38 downto 0)) return std_logic_vector;
end secded_32b_pkg;
......@@ -70,59 +70,17 @@ package body secded_32b_pkg is
6 => "10001010100000100000111100011011"
);
type array_syndrome is array (0 to 38) of syndrome_word_t;
constant syn_correction_mask : array_syndrome := (
0 => "1100001",
1 => "1010001",
2 => "0011001",
3 => "1000101",
4 => "1000011",
5 => "0110001",
6 => "0101001",
7 => "0010011",
8 => "1100010",
9 => "1010010",
10 => "1001010",
11 => "1000110",
12 => "0110010",
13 => "0101010",
14 => "0100011",
15 => "0011010",
16 => "0101100",
17 => "1100100",
18 => "0100110",
19 => "0100101",
20 => "0110100",
21 => "0010110",
22 => "0010101",
23 => "1010100",
24 => "0001011",
25 => "1011000",
26 => "0011100",
27 => "1001100",
28 => "0111000",
29 => "0001110",
30 => "0001101",
31 => "1001001",
32 => "0000001",
33 => "0000010",
34 => "0000100",
35 => "0001000",
36 => "0010000",
37 => "0100000",
38 => "1000000");
function f_calc_syndrome (data : data_word_t) return syndrome_word_t
function f_calc_ecc (data : data_word_t) return ecc_word_t
is
variable result : syndrome_word_t;
variable result : ecc_word_t;
begin
for i in result'range loop
result (i) := f_xor (data and syndrome_masks (i));
end loop;
return result;
end f_calc_syndrome;
end f_calc_ecc;
function f_ecc_errors (syndrome : syndrome_word_t) return std_logic is
function f_ecc_errors (syndrome : ecc_word_t) return std_logic is
begin
if Is_x (syndrome (0)) then
-- report "memory wrong" severity error;
......@@ -131,7 +89,7 @@ package body secded_32b_pkg is
return f_or (syndrome);
end f_ecc_errors;
function f_ecc_one_error (syndrome : syndrome_word_t) return std_logic is
function f_ecc_one_error (syndrome : ecc_word_t) return std_logic is
begin
if Is_x (syndrome (0)) then
return '0';
......@@ -139,26 +97,25 @@ package body secded_32b_pkg is
return f_ecc_errors (syndrome) and f_xor (syndrome);
end f_ecc_one_error;
function f_fix_error (syndrome : syndrome_word_t;
function f_fix_error (syndrome : ecc_word_t;
data : std_logic_vector (38 downto 0)) return std_logic_vector
is
variable result : std_logic_vector (38 downto 0) := (others => '1');
variable mask : syndrome_word_t;
variable result : std_logic_vector (31 downto 0) := (others => '1');
variable corrected_word : std_logic_vector (38 downto 0);
begin
for i in 0 to 38 loop
mask := syn_correction_mask(i);
for k in mask'range loop
if mask (k) = '1' then
-- The data bits
for i in 0 to 31 loop
for k in 0 to 6 loop
if syndrome_masks(k)(i) = '1' then
result(i) := result(i) and syndrome(k);
end if;
end loop;
end loop;
if f_or (result(31 downto 0)) = '1' then
corrected_word := data (38 downto 32) & (result (31 downto 0) xor data(31 downto 0));
elsif f_or (result(38 downto 32)) = '1' then
corrected_word := result xor data;
if f_or (result) = '1' then
corrected_word := data (38 downto 32) & (result xor data(31 downto 0));
elsif f_or (syndrome) = '1' then
corrected_word := (syndrome & result) xor data;
else
corrected_word := "0000000" & x"00000000";
end if;
......
......@@ -103,7 +103,7 @@ begin
q_o <= d_ram_i (31 downto 0);
re_ram_o <= '1' when (fsm_read /= normal_op) else re;
syndrome <= f_calc_syndrome (d_ram_i (31 downto 0)) xor d_ram_i(38 downto 32);
syndrome <= f_calc_ecc (d_ram_i (31 downto 0)) xor d_ram_i(38 downto 32);
ecc_errors <= f_ecc_errors(syndrome);
ecc_correctable_error <= f_ecc_one_error (syndrome);
......@@ -256,7 +256,7 @@ begin
fsm_write <= check_write;
elsif we = '1' then
q_ram(31 downto 0) <= d;
q_ram(38 downto 32) <= f_calc_syndrome(d);
q_ram(38 downto 32) <= f_calc_ecc(d);
we_ram_o <= '1';
fsm_write <= check_write;
end if;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment