harv/hdl/ft_components/alu_tmr.vhd
2022-03-10 19:12:20 +01:00

80 lines
2.5 KiB
VHDL

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
library work;
use work.harv_pkg.all;
entity alu_tmr is
port (
-- input ports
data1_i : in std_logic_vector(31 downto 0);
data2_i : in std_logic_vector(31 downto 0);
operation_i : in std_logic_vector(ALUOP_SIZE-1 downto 0);
correct_error_i : in std_logic;
-- output ports
error_o : out std_logic;
zero_o : out std_logic;
data_o : out std_logic_vector(31 downto 0)
);
end entity;
architecture arch of alu_tmr is
type tmr_std_logic_t is array(2 downto 0) of std_logic;
signal zero_w : tmr_std_logic_t;
signal corr_zero_w : std_logic;
signal error_zero_w : std_logic;
type tmr_data_t is array(2 downto 0) of std_logic_vector(31 downto 0);
signal data_w : tmr_data_t;
signal corr_data_w : std_logic_vector(31 downto 0);
signal error_data_w : std_logic;
begin
gen_TMR : for i in 2 downto 0 generate
-- Xilinx attributes to prevent optimization of TMR
attribute DONT_TOUCH : string;
attribute DONT_TOUCH of alu_u : label is "TRUE";
-- Synplify attributes to prevent optimization of TMR
attribute syn_radhardlevel : string;
attribute syn_keep : boolean;
attribute syn_safe_case : boolean;
attribute syn_noprune : boolean;
attribute syn_radhardlevel of alu_u : label is "tmr";
attribute syn_keep of alu_u : label is TRUE;
attribute syn_safe_case of alu_u : label is TRUE;
attribute syn_noprune of alu_u : label is TRUE;
begin
alu_u : alu
port map (
data1_i => data1_i,
data2_i => data2_i,
operation_i => operation_i,
zero_o => zero_w(i),
data_o => data_w(i)
);
end generate;
corr_zero_w <= (zero_w(2) and zero_w(1)) or
(zero_w(2) and zero_w(0)) or
(zero_w(1) and zero_w(0));
corr_data_w <= (data_w(2) and data_w(1)) or
(data_w(2) and data_w(0)) or
(data_w(1) and data_w(0));
error_zero_w <= (zero_w(2) xor zero_w(1)) or
(zero_w(2) xor zero_w(0)) or
(zero_w(1) xor zero_w(0));
error_data_w <= or_reduce((data_w(2) xor data_w(1)) or
(data_w(2) xor data_w(0)) or
(data_w(1) xor data_w(0)));
error_o <= error_zero_w or error_data_w;
zero_o <= corr_zero_w when correct_error_i = '1' else zero_w(0);
data_o <= corr_data_w when correct_error_i = '1' else data_w(0);
end architecture;