------------------------------------------------------------ -- Copyright: 2011 Integrated Sytems Laboratory, ETH Zurich -- http://www.iis.ee.ethz.ch/~sha3 ------------------------------------------------------------ ------------------------------------------------------------------------------- -- Title : SHA2 taken from sem10h7 -- Project : Shabziger ------------------------------------------------------------------------------- -- File : ethz_sha2.vhd -- Author : Köppel Benedikt;Schnydrig Mathias -- Company : Integrated Systems Laboratory, ETH Zurich -- Created : 2011-01-13 -- Last update: 2011-09-10 -- Platform : ModelSim (simulation), Synopsys (synthesis) -- Standard : VHDL'87 ------------------------------------------------------------------------------- -- Description: Top module around SHA256 to provide a clean interface to the -- outside world ------------------------------------------------------------------------------- -- Copyright (c) 2011 Integrated Systems Laboratory, ETH Zurich ------------------------------------------------------------------------------- -- Revisions : -- Date Version Author Description -- 2011-01-13 1.0 sem10h7 Created -- 2011-08-25 1.1 kgf Changed entity name -- 2011-09-10 1.2 kgf Changed the Reset name frm RSTxRBI to RstxRBI -- our compile script depends on this name. ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use work.shapkg.all; entity ethz_sha2 is port ( ClkxCI : in std_logic; RstxRBI : in std_logic; FinBlockxSI : in std_logic; InWrEnxSI : in std_logic; PenUltCyclexSO : out std_logic; -- ReadyxSO : out std_logic; -- is 1, when we are ready for a next message OutWrEnxSO : out std_logic; TextInxDI : in std_logic_vector(511 downto 0); -- the message to encrypt, including all padding and stuff HOutxDO : out std_logic_vector(255 downto 0); -- the Hash output, if TextIn was the last message, or intermediary H values if not the last message ScanInxTI : in std_logic; ScanEnxTI : in std_logic; ScanOutxTO : out std_logic ); end ethz_sha2; architecture behavioral of ethz_sha2 is component SHA256Main port ( MessageInxDI : in expmess_arr; InWrEnxSI : in std_logic; HInxDI : in h_arr; CLKxCI : in std_logic; RSTxRBI : in std_logic; VALIDOUTxSO : out std_logic; HOutxDO : out h_arr; MessageReadyxSI : in std_logic; PenUltCyclexSO : out std_logic; MessageReceivedxSO : out std_logic); end component; type state is (Idle, First, Waiting, Running); -- statemachine signal StatexDP : state; signal StatexDN : state; -- pipelining the inputs -- signal TextInxDP : std_logic_vector(511 downto 0); -- signal TextInxDN : std_logic_vector(511 downto 0); signal HxDP : std_logic_vector(255 downto 0); signal HxDN : std_logic_vector(255 downto 0); -- pipelining the outputs -- signal HOutxDP : std_logic_vector(255 downto 0); -- signal HOutxDN : std_logic_vector(255 downto 0); -- connect to SHA256Main signal MessageInxD : expmess_arr; signal HInxD : h_arr; signal HOutxD : h_arr; signal VALIDOUTxS : std_logic; signal MessageReadyxS : std_logic; signal MessageReceivedxS : std_logic; signal FinBlockxSN, FinBlockxSP : std_logic; signal OutWrEnxSN, OutWrEnxSP : std_logic; signal FirstBlockxS : std_logic; signal PenUltCyclexS : std_logic; signal ReadyxS : std_logic; begin -- behavioral SHA256Main_1 : SHA256Main port map ( MessageInxDI => MessageInxD, InWrEnxSI => InWrEnxSI, HInxDI => HInxD, CLKxCI => CLKxCI, RSTxRBI => RstxRBI, VALIDOUTxSO => VALIDOUTxS, HOutxDO => HOutxD, MessageReadyxSI => MessageReadyxS, PenUltCyclexSO => PenUltCyclexS, MessageReceivedxSO => MessageReceivedxS); -- wire pipelined inputs -- MessageInxD TextInxDP(511 downto 480), TextInxDP(479 downto 448), TextInxDP(447 downto 416), TextInxDP(415 downto 384), TextInxDP(383 downto 352), TextInxDP(351 downto 320), TextInxDP(319 downto 288), TextInxDP(287 downto 256), TextInxDP(255 downto 224), TextInxDP(223 downto 192), TextInxDP(191 downto 160), TextInxDP(159 downto 128), TextInxDP(127 downto 96), TextInxDP(95 downto 64), TextInxDP(63 downto 32), TextInxDP(31 downto 0)); HInxD <= (HxDP(255 downto 224), HxDP(223 downto 192), HxDP(191 downto 160), HxDP(159 downto 128), HxDP(127 downto 96), HxDP(95 downto 64), HxDP(63 downto 32), HxDP(31 downto 0)); MessageInxD <= (TextInxDI(511 downto 480), TextInxDI(479 downto 448), TextInxDI(447 downto 416), TextInxDI(415 downto 384), TextInxDI(383 downto 352), TextInxDI(351 downto 320), TextInxDI(319 downto 288), TextInxDI(287 downto 256), TextInxDI(255 downto 224), TextInxDI(223 downto 192), TextInxDI(191 downto 160), TextInxDI(159 downto 128), TextInxDI(127 downto 96), TextInxDI(95 downto 64), TextInxDI(63 downto 32), TextInxDI(31 downto 0)); p_calculate_next_state : process (FinBlockxSP, InWrEnxSI, OutWrEnxSP, PenUltCyclexS, StatexDP, VALIDOUTxS) begin -- process p_calculate_next_state MessageReadyxS <= '0'; ReadyxS <= '0'; OutWrEnxSN <= (VALIDOUTxS and FinBlockxSP); OutWrEnxSO <= OutWrEnxSP; FirstBlockxS <= '0'; -- PenUltCyclexSO PenUltCyclexS xor ReadyxS; PenUltCyclexSO <= PenUltCyclexS; case StatexDP is when Idle => -- we remain idle until someone tells us to start FirstBlockxS <= '1'; ReadyxS <= '1'; if InWrEnxSI = '1' then StatexDN <= First; MessageReadyxS <= '1'; else StatexDN <= Idle; end if; when First => FirstBlockxS <= '0'; if VALIDOUTxS = '1' then if FinBlockxSP = '1' then if InWrEnxSI = '1' then StatexDN <= First; MessageReadyxS <= '1'; FirstBlockxS <= '1'; else StatexDN <= Idle; end if; else if InWrEnxSI = '1' then StatexDN <= Running; MessageReadyxS <= '1'; else StatexDN <= Waiting; end if; end if; ReadyxS <= '1'; else StatexDN <= First; end if; when Waiting => ReadyxS <= '1'; if InWrEnxSI = '1' then StatexDN <= Running; MessageReadyxS <= '1'; else StatexDN <= Waiting; end if; when Running => -- output is valid when it says so if VALIDOUTxS = '1' then if FinBlockxSP = '1' then if InWrEnxSI = '1' then StatexDN <= First; MessageReadyxS <= '1'; FirstBlockxS <= '1'; else StatexDN <= Idle; end if; else if InWrEnxSI = '1' then StatexDN <= Running; MessageReadyxS <= '1'; else StatexDN <= Waiting; end if; end if; ReadyxS <= '1'; else StatexDN <= Running; end if; when others => null; end case; end process p_calculate_next_state; p_calculate_next_inputs : process (FinBlockxSI, FinBlockxSP, FirstBlockxS, HOutxD, HxDP, InWrEnxSI, VALIDOUTxS) begin -- process p_calculate_next_inputs -- if (StatexDP = Idle or StatexDP = Waiting) and InWrEnxSI = '1' then HxDN <= HxDP; if FirstBlockxS = '1' then if InWrEnxSI = '1' then HxDN <= SHA_IV; end if; else if VALIDOUTxS = '1' then HxDN <= (HOutxD(0) & HOutxD(1) & HOutxD(2) & HOutxD(3) & HOutxD(4) & HOutxD(5) & HOutxD(6) & HOutxD(7)); end if; end if; if InWrEnxSI = '1' then -- we are ready for new stuff, and are adviced to start now -- TextInxDN TextInxDI; FinBlockxSN <= FinBlockxSI; -- if FirstBlockxS = '1' then -- HInxDN <= SHA_IV; -- else ---- HInxDN HOutxDP; -- HInxDN HOutxD(0) & HOutxD(1) & HOutxD(2) & HOutxD(3) & HOutxD(4) & HOutxD(5) & HOutxD(6) & HOutxD(7)); -- end if; else -- not ready, or no new inputs: just leave it as it is -- TextInxDN TextInxDP; -- HInxDN HInxDP; FinBlockxSN <= FinBlockxSP; end if; end process p_calculate_next_inputs; p_update_inputs : process (CLKxCI, RstxRBI) begin -- process p_update_inputs if RstxRBI = '0' then -- asynchronous reset (active low) -- TextInxDP others => '0'); HxDP <= (others => '0'); FinBlockxSP <= '0'; OutWrEnxSP <= '0'; elsif CLKxCI'event and CLKxCI = '1' then -- rising clock edge -- TextInxDP TextInxDN; HxDP <= HxDN; FinBlockxSP <= FinBlockxSN; OutWrEnxSP <= OutWrEnxSN; end if; end process p_update_inputs; -- p_calculate_next_outputs : process (HOutxD, HOutxDP, VALIDOUTxS) -- begin -- process p_calculate_next_outputs ---- HOutxDO HOutxDP; ---- if VALIDOUTxS = '1' then ---- -- if SHA gives a valid output, the output can go to the outside world ---- HOutxDN HOutxD(0) & HOutxD(1) & HOutxD(2) & HOutxD(3) & HOutxD(4) & HOutxD(5) & HOutxD(6) & HOutxD(7)); ---- else ---- -- else, keep thelast previous valid value ---- HOutxDN HOutxDP; -- end if; -- end process p_calculate_next_outputs; -- p_update_outputs : process (CLKxCI, RSTxRBI) -- begin -- process p_update_outputs -- if RSTxRBI = '0' then -- asynchronous reset (active low) -- HOutxDP others => '0'); -- elsif CLKxCI'event and CLKxCI = '1' then -- rising clock edge -- HOutxDP HOutxDN; -- end if; -- end process p_update_outputs; p_update_state : process (CLKxCI, RstxRBI) begin -- process p_update_state if RstxRBI = '0' then -- asynchronous reset (active low) StatexDP <= idle; elsif CLKxCI'event and CLKxCI = '1' then -- rising clock edge StatexDP <= StatexDN; end if; end process p_update_state; HOutxDO <= HxDP; end behavioral;