------------------------------------------------------------ -- Copyright: 2011 George Mason University, Virginia USA -- http://www.iis.ee.ethz.ch/~sha3 ------------------------------------------------------------ -- ===================================================================== -- Copyright © 2010-2011 by Cryptographic Engineering Research Group (CERG), -- ECE Department, George Mason University -- Fairfax, VA, U.S.A. -- ===================================================================== library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use work.sha3_pkg.all; use work.keccak_pkg.all; -- Possible generics values: -- hs = {HASH_SIZE_256, HASH_SIZE_512} entity gmu_keccak_control is generic ( RST_ACTIVE_VALUE : std_logic := '0' ); port ( rst : in std_logic; clk : in std_logic; -- processing sel_xor : out std_logic; sel_final : out std_logic; wr_state : out std_logic; rd_ctr : out std_logic_vector(4 downto 0); InEnxSI : in std_logic; FinBlockxSI : in std_logic; OutEnxSO : out std_logic; PenUltCyclexSO : out std_logic ); end gmu_keccak_control; architecture struct of gmu_keccak_control is type stateType is ( initState, idleState, hashBlockState, finBlockState, outputState ); signal cstate, nstate : stateType; signal lastBlockFlag, lastBlockSet, lastBlockClr : std_logic; signal roundCtr : std_logic_vector(4 downto 0); signal loadRoundCtr, incRoundCtr : std_logic; signal roundDoneComp : std_logic; signal firstRoundComp : std_logic; signal secondRoundComp : std_logic; signal sfSet, sfClr, sfFlag : std_logic; constant roundNumber : integer := 24; begin roundCtrGen: process( rst, clk ) begin if (rst = RST_ACTIVE_VALUE) then roundCtr <= (others => '0'); elsif rising_edge( clk ) then if loadRoundCtr = '1' then roundCtr <= (others => '0'); elsif incRoundCtr = '1' then roundCtr <= roundCtr + 1; end if; end if; end process; incRoundCtr <= '1' when (cstate = hashBlockState ) else '0'; loadRoundCtr <= '1' when (cstate = idleState or cstate = finBlockState) else '0'; roundDoneComp <= '1' when roundCtr = roundNumber-2 else '0'; firstRoundComp <= '1' when roundCtr = 0 else '0'; secondRoundComp <= '1' when roundCtr = 1 else '0'; stateReg: process( rst, clk ) begin if (rst = RST_ACTIVE_VALUE) then cstate <= initState; elsif rising_edge( clk ) then cstate <= nstate; end if; end process; -- kgf added lastBlockFlag to the process sensitivity list nextStateComb: process( cstate, InEnxSI, roundDoneComp, lastBlockFlag ) begin case cstate is when initState => nstate <= idleState; when idleState => if InEnxSI = '1' then nstate <= hashBlockState; else nstate <= idleState; end if; when hashBlockState => if roundDoneComp = '1' then nstate <= finBlockState; else nstate <= hashBlockState; end if; when finBlockState => if lastBlockFlag = '1' then nstate <= outputState; elsif InEnxSI = '1' then nstate <= hashBlockState; else nstate <= finBlockState; end if; when outputState => nstate <= idleState; end case; end process; PenUltCyclexSO <= '1' when (cstate = hashBlockState and roundDoneComp = '1' and lastBlockFlag = '0') or (cstate = outputState) else '0'; lastBlockInst: entity work.sr_rega(struct) port map ( rst => rst, clk => clk, set => lastBlockSet, clr => lastBlockClr, output => lastBlockFlag ); lastBlockSet <= '1' when (cstate = idleState or cstate = finBlockState) and (FinBlockxSI = '1' and InEnXSI = '1') else '0'; lastBlockClr <= '1' when (cstate = idleState) else '0'; sfInst: entity work.sr_rega(struct) port map ( rst => rst, clk => clk, set => sfSet, clr => sfClr, output => sfFlag ); sfSet <= '1' when (cstate = initState or cstate = outputState) else '0'; sfClr <= '1' when (cstate = hashBlockState) else '0'; -- Output sel_xor <= sfFlag; sel_final <= '1' when (cstate = idleState or (cstate = finBlockState and lastBlockFlag = '0')) else '0'; wr_state <= '1' when (cstate = idleState and InEnxSI = '1') or (cstate = hashBlockState) or (cstate = finBlockState and (lastBlockFlag = '1' or InEnxSI = '1')) else '0'; OutEnxSO <= '1' when (cstate = outputState) else '0'; rd_ctr <= roundCtr; end struct;