------------------------------------------------------------- -- Component : CPU (Cpu, Cpu_a) -- File name : Cpu_ea.vhd -- Purpose : Emulates CPU read/Write transaction -- : for test of the error injector component -- Library : work (for simplicity) ------------------------------------------------------------- package Cpu_Pkg is signal EndOfCycle_s : boolean := False; end Cpu_Pkg; library IEEE; use IEEE.Std_Logic_1164.all; library Work; use Work.Cpu_Pkg.all; use Work.Cpu_Pkg; entity Cpu is generic(Delay_g : time := 10 ns); port (ADDR : out Std_Logic_Vector(1 downto 0) := (others => '1'); -- 2 bit address DATA : inout Std_Logic_Vector(7 downto 0) := (others => 'Z'); -- 8 bit data RWF : out Std_Logic := '1'; -- Read = '1', Write = '0' Clk : in Std_Logic := '1'); -- For timing synchronization end Cpu; Architecture Cpu_a of Cpu is subtype Std2Bits_Typ is Std_Logic_Vector(1 downto 0); subtype Intgr03_Typ is integer range 0 to 3; type TwoD_Typ is array(Intgr03_Typ) of Std2Bits_Typ; constant Addr_c : TwoD_Typ := ("00", "01", "10", "11"); begin Transaction_Lbl: process variable NextAdr_v : Intgr03_Typ := 0; variable Data_v : Std_Logic_Vector(7 downto 0) := "10110010"; constant Delta_c : Time := Delay_g / 5; begin Wait until Clk'event and Clk = '1'; if NextAdr_v = 0 then -- Set up for synchronization of testbench Cpu_Pkg.EndOfCycle_s <= True, False after 1 ns; end if; -- Do a WRITE ADDR <= Addr_c(NextAdr_v) after Delay_g; -- Address RWF <= '0' after Delay_g - Delta_c; -- Control Data <= Data_v after 2 * Delta_c; -- Data Wait until Clk'event and Clk = '1'; -- Do a READ ADDR <= Addr_c(NextAdr_v) after Delay_g; -- Address RWF <= '1' after Delay_g - Delta_c; -- Control Data <= (others => 'Z') after 2 * Delta_c; -- read -- Setup for next Write/Read NextAdr_v := (NextAdr_v +1) mod (Intgr03_Typ'High + 1); Data_v := Data_v(6 downto 0) & Data_v(7); -- Rotate left logical end process Transaction_Lbl; end Cpu_a; --**************************************** ------------------------------------------------------------- -- Component : Reg (Reg, Reg_a) -- File name : Reg_ea.vhd -- Purpose : Emulates register file -- : for test of the error injector component -- Library : work (for simplicity) ------------------------------------------------------------- library IEEE; use IEEE.Std_Logic_1164.all; entity Reg is generic(Delay_g : time := 14 ns); port (ADDR : in Std_Logic_Vector(1 downto 0); -- 2 bit address DATA : inout Std_Logic_Vector(7 downto 0) := (others => 'Z'); RWF : in Std_Logic; -- Read = '1', Write = '0' Clk : in Std_Logic); -- For timing synchronization end Reg; Architecture Reg_a of Reg is subtype Std8Bits_Typ is Std_Logic_Vector(7 downto 0); subtype Intgr03_Typ is integer range 0 to 3; type TwoD_Typ is array(Intgr03_Typ) of Std8Bits_Typ; begin Reg_Lbl: process(ADDR, DATA, RWF, CLK) variable RegFile_v : TwoD_Typ; constant Delta_c :Time := Delay_g / 5; variable Addr_v : Std_Logic_Vector(1 downto 0); begin Addr_v := To_X01(ADDR); if (RWF = '0' or RWF = 'L') and not (Clk'event and CLK = '1') then DATA <= (others => 'Z'); elsif (RWF = '0' or RWF = 'L') and (Clk'event and CLK = '1') then case ADDR is when "00" => RegFile_v(0) := To_X01(DATA); -- from Std_logic_1164 pckage when "01" => RegFile_v(1) := To_X01(DATA); when "10" => RegFile_v(2) := To_X01(DATA); when "11" => RegFile_v(3) := To_X01(DATA); when others => null; end case; elsif (RWF = '1' or RWF = 'H') then -- Read case ADDR_v is when "00" => DATA <= RegFile_v(0) after 3 * Delta_c; when "01" => DATA <= RegFile_v(1) after 3 * Delta_c; when "10" => DATA <= RegFile_v(2) after 3 * Delta_c; when "11" => DATA <= RegFile_v(3) after 3 * Delta_c; when others => DATA <= (others => 'X') after 3 * Delta_c; end case; else null; --assert false -- report "Error in value RWF, Reg model" -- severity warning; end if; end process Reg_Lbl; end Reg_a; --**************************************** -- Component : TestBench (TestBench, TestBench_a) -- File name : Test_tb.vhd -- Description: This model incorporates the CPU component, the -- : register file component, and the error injector component. -- Library : work (for simplicity) -- Run Time : 20 us ------------------------------------------------------------- Library ErrInj_lib; use ErrInj_Lib.ErrInj_Pkg.all; use ErrInj_Lib.ErrInj_Pkg; library IEEE; use IEEE.Std_Logic_1164.all; library Work; use Work.Cpu_Pkg.all; use Work.Cpu_Pkg; entity TestBench is end TestBench; architecture TestBench_a of TestBench is component Cpu generic(Delay_g : time := 10 ns); port (ADDR : out Std_Logic_Vector(1 downto 0); -- 2 bit address DATA : inout Std_Logic_Vector(7 downto 0); -- 8 bit data RWF : out Std_Logic; -- Read = '1', Write = '0' Clk : in Std_Logic); -- For timing synchronization end component; component ErrInj generic (Width_g : Positive := 11; InjMode_g : ErrInj_Pkg.InjMode_Typ := NoError); port (A : inout Std_Logic_Vector(Width_g - 1 downto 0) := (others => 'Z'); B : inout Std_Logic_Vector(Width_g - 1 downto 0) := (others => 'Z'); C : in Std_Logic_Vector(Width_g - 1 downto 0) := (others => 'Z')); end component; component Reg generic(Delay_g : time := 14 ns); port (ADDR : in Std_Logic_Vector(1 downto 0); -- 2 bit address DATA : inout Std_Logic_Vector(7 downto 0); -- 8 bit data RWF : in Std_Logic; -- Read = '1', Write = '0' Clk : in Std_Logic); -- For timing synchronization end component; signal ADDRa_s : Std_Logic_Vector(1 downto 0) := (others => 'H'); signal ADDRb_s : Std_Logic_Vector(1 downto 0) := (others => 'H'); signal DATAa_s : Std_Logic_Vector(7 downto 0) := (others => 'H'); signal DATAb_s : Std_Logic_Vector(7 downto 0) := (others => 'H'); signal RWFa_s : Std_Logic := 'H'; -- Read = '1', Write = '0' signal RWFb_s : Std_Logic := 'H'; -- Read = '1', Write = '0' signal CNTRL_s : Std_Logic_Vector(10 downto 0) := (others => '-'); alias ADDRc_s : Std_Logic_Vector(1 downto 0) is CNTRL_s(10 downto 9); alias DATAc_s : Std_Logic_Vector(7 downto 0) is CNTRL_s(8 downto 1); alias RWFc_s : Std_Logic is CNTRL_s(0); signal Clk : Std_Logic := '1'; -- For timing synchronization begin Clk <= not Clk after 100 ns; U_Cpu: Cpu generic map (Delay_g => 10 ns) port map (ADDR => ADDRa_s, DATA => DATAa_s, RWF => RWFa_s, Clk => CLK); U_ErrInj: ErrInj generic map (Width_g => 11, InjMode_g => NoError) port map (A(10 downto 9) => ADDRa_s, A( 8 downto 1) => DATAa_s, A(0) => RWFa_s, B(10 downto 9) => ADDRb_s, B( 8 downto 1) => DATAb_s, B(0) => RWFb_s, C => CNTRL_s); U_Reg: Reg generic map (Delay_g => 14 ns) port map (ADDR => ADDRb_s, DATA => DATAb_s, RWF => RWFb_s, CLK => CLK); ErrorCntrl_Lbl: Process variable Count_v : integer := 0; begin ------------------ Normal/Write fault ---------------------- assert false report "No Fault injection" severity note; -- AB switch is pass though ADDRc_s <= "--"; -- transaction to fire the error injector DATAc_s <= "--------"; RWFc_s <= '-'; wait until Cpu_Pkg.EndOfCycle_s; -- ingnore dummy 1st signal wait until Cpu_Pkg.EndOfCycle_s; -- All registers initialized in reg file assert false report "Fault injection, WRF = 0" severity note; -- Error insertion in WRF ADDRc_s <= "--"; DATAc_s <= "--------"; RWFc_s <= '0'; ------------------ Normal/Read fault ---------------------- wait until Cpu_Pkg.EndOfCycle_s; -- All registers initialized in reg file assert false report "No Fault injection" severity note; -- AB switch is pass though ADDRc_s <= "--"; DATAc_s <= "--------"; RWFc_s <= '-'; wait until Cpu_Pkg.EndOfCycle_s; -- All registers initialized in reg file assert false report "Fault injection, WRF = 1" severity note; -- Error insertion in WRF ADDRc_s <= "--"; DATAc_s <= "--------"; RWFc_s <= '1'; ------------------ Normal/DATA fault ---------------------- wait until Cpu_Pkg.EndOfCycle_s; -- All registers initialized in reg file assert false report "No Fault injection" severity note; -- AB switch is pass though ADDRc_s <= "--"; DATAc_s <= "--------"; RWFc_s <= '-'; wait until Cpu_Pkg.EndOfCycle_s; -- All registers initialized in reg file assert false report "Fault injection, DATA = 01XLHUW-" severity note; -- Error insertion in Data ADDRc_s <= "--"; DATAc_s <= "01XLHUW-"; -- no error in bit 0 RWFc_s <= '-'; -------------------- Normal/Open DATA fault -------------------- wait until Cpu_Pkg.EndOfCycle_s; -- All registers initialized in reg file assert false report "No Fault injection" severity note; -- AB switch is pass though ADDRc_s <= "--"; DATAc_s <= "--------"; RWFc_s <= '-'; wait until Cpu_Pkg.EndOfCycle_s; -- All registers initialized in reg file assert false report "Fault injection, DATA = HHHHHHHH" severity note; -- Error insertion in Data ADDRc_s <= "--"; DATAc_s <= "HHHHHHHH"; -- no error in bit 0 RWFc_s <= '-'; ------------------ Normal/Address fault ---------------------- wait until Cpu_Pkg.EndOfCycle_s; -- All registers initialized in reg file assert false report "No Fault injection" severity note; -- AB switch is pass though ADDRc_s <= "--"; DATAc_s <= "--------"; RWFc_s <= '-'; wait until Cpu_Pkg.EndOfCycle_s; -- All registers initialized in reg file assert false report "Fault injection, ADDRESS = 0-" severity note; -- Error insertion in Address ADDRc_s <= "0-"; DATAc_s <= "--------"; RWFc_s <= '-'; ------------------ Normal/OPEN fault ---------------------- wait until Cpu_Pkg.EndOfCycle_s; -- All registers initialized in reg file assert false report "No Fault injection" severity note; -- AB switch is pass though ADDRc_s <= "--"; DATAc_s <= "--------"; RWFc_s <= '-'; wait until Cpu_Pkg.EndOfCycle_s; -- All registers initialized in reg file assert false report "One side OPEN" severity note; ADDRc_s <= "HH"; DATAc_s <= "HHHHHHHH"; RWFc_s <= 'H'; -------------------- END of TEST -------------------- wait until Cpu_Pkg.EndOfCycle_s; -- All registers initialized in reg file assert false report "end of test" severity note; end Process ErrorCntrl_Lbl; end TestBench_a; --**************************************** -- file errinj_c.vhd Library ErrInj_lib; use ErrInj_Lib.ErrInj_Pkg.all; configuration StuckB_Cfg of TestBench is for TestBench_a for U_ErrInj: ErrInj use entity ErrInj_Lib.ErrInj(ErrInj_a) generic map (Width_g => 11, InjMode_g => StuckB); end for; end for; end StuckB_Cfg; -- Library ErrInj_lib; use ErrInj_Lib.ErrInj_Pkg.all; configuration StuckA_Cfg of TestBench is for TestBench_a for U_ErrInj: ErrInj use entity ErrInj_Lib.ErrInj(ErrInj_a) generic map (Width_g => 11, InjMode_g => StuckA); end for; end for; end StuckA_Cfg; -- Library ErrInj_lib; use ErrInj_Lib.ErrInj_Pkg.all; configuration StuckAB_Cfg of TestBench is for TestBench_a for U_ErrInj: ErrInj use entity ErrInj_Lib.ErrInj(ErrInj_a) generic map (Width_g => 11, InjMode_g => StuckAB); end for; end for; end StuckAB_Cfg; -- Library ErrInj_lib; use ErrInj_Lib.ErrInj_Pkg.all; configuration DriverAB_Cfg of TestBench is for TestBench_a for U_ErrInj: ErrInj use entity ErrInj_Lib.ErrInj(ErrInj_a) generic map (Width_g => 11, InjMode_g => DriverAB); end for; end for; end DriverAB_Cfg; --****************************************