------------------------------------------------------------ -- 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.sha3_blake_package.all; entity gmu_blake_control is generic ( RST_ACTIVE_VALUE : std_logic := '0' ); port ( rst : in std_logic; clk : in std_logic; round : out std_logic_vector(4 downto 0); er : out std_logic; -- enable signal for state register em : out std_logic; -- enable signal for register between the permute and round unit eh : out std_logic; -- enable signal for intermediate hash register sf : out std_logic; -- select signal for first block (IV selection) lm : out std_logic; -- load message for message register InWrEnxSI : in std_logic; FinBlockxSI : in std_logic; OutWrEnxSO : out std_logic; PenUltCyclexSO : out std_logic ); end gmu_blake_control; architecture beh of gmu_blake_control is type stateType is ( initState, idleState, prepMsgState, hashDataState, penultimateState, finalState ); signal cstate, nstate : stateType; signal lastBlockFlag, lastBlockSet, lastBlockClr : std_logic; signal msgReadyFlag, msgReadySet, msgReadyClr : std_logic; signal roundCtr : std_logic_vector(4 downto 0); signal loadRoundCtr, incRoundCtr : std_logic; signal processDoneComp : std_logic; signal sfSet, sfClr, sfFlag : std_logic; signal nextBlockIsLastSet, nextBlockIsLastClr, nextBlockIsLastFlag : std_logic; signal enableRegCtrl : std_logic; 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 = prepMsgState or cstate = hashDataState or (cstate = finalState and msgReadyFlag = '1')) else '0'; --incRoundCtr when (cstate = hashDataState or (cstate = finalState and msgReadyFlag = '1')) else '0'; loadRoundCtr <= '1' when (cstate = penultimateState or cstate = initState) else '0'; processDoneComp <= '1' when roundCtr = 27 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; nextStateComb: process( cstate, InWrEnxSI , processDoneComp, lastBlockFlag, msgReadyFlag ) begin case cstate is when initState => nstate <= idleState; when idleState => if InWrEnxSI = '1' then nstate <= prepMsgState; else nstate <= idleState; end if; when prepMsgState => nstate <= hashDataState; when hashDataState => if processDoneComp = '1' then nstate <= penultimateState; else nstate <= hashDataState; end if; when penultimateState => nstate <= finalState; when finalState => if lastBlockFlag = '1' then nstate <= idleState; elsif msgReadyFlag = '1' then nstate <= hashDataState; elsif InWrEnxSI = '1' then nstate <= prepMsgState; else nstate <= finalState; end if; end case; end process; msgReadyInst: entity work.sr_rega(struct) port map ( rst => rst, clk => clk, set => msgReadySet, clr => msgReadyClr, output => msgReadyFlag ); msgReadySet <= '1' when (cstate = penultimateState and InWrEnxSI = '1' and lastBlockFlag = '0') else '0'; msgReadyClr <= '1' when (cstate = finalState) else '0'; nextBlockIsLastInst: entity work.sr_rega(struct) port map ( rst => rst, clk => clk, set => nextBlockIsLastSet, clr => nextBlockIsLastClr, output => nextBlockIsLastFlag ); nextBlockIsLastSet <= '1' when (cstate = penultimateState) and (FinBlockxSI = '1') else '0'; nextBlockIsLastClr <= '1' when (cstate = penultimateState and nextBlockIsLastFlag = '1') else '0'; lastBlockInst: entity work.sr_rega(struct) port map ( rst => rst, clk => clk, set => lastBlockSet, clr => lastBlockClr, output => lastBlockFlag ); lastBlockSet <= '1' when (cstate = finalState or cstate = idleState) and (FinBlockxSI = '1' or nextBlockIsLastFlag = '1') else '0'; lastBlockClr <= '1' when (cstate = idleState) else '0'; OutWrEnxSO <= '1' when (cstate = finalState and lastBlockFlag = '1') else '0'; sfInst: entity work.sr_rega(struct) port map ( rst => rst, clk => clk, set => sfSet, clr => sfClr, output => sfFlag ); sfSet <= '1' when (cstate = idleState) else '0'; sfClr <= '1' when (cstate = prepMsgState) else '0'; -- Output enableRegCtrl <= '1' when (cstate = prepMsgState or cstate = hashDataState or cstate = penultimateState or (cstate = finalState and msgReadyFlag = '1')) else '0'; er <= enableRegCtrl; em <= enableRegCtrl; lm <= '1' when (cstate = idleState or cstate = penultimateState or (cstate = finalState and msgReadyFlag = '0')) and InWrEnxSI = '1' else '0'; eh <= '1' when (cstate = prepMsgState or (cstate = finalState and msgReadyFlag = '1')) else '0'; sf <= sfFlag; round <= roundCtr; PenUltCyclexSO <= '1' when (cstate = hashDataState and processDoneComp = '1' and lastBlockFlag = '0') or (cstate = finalState and lastblockFlag = '1') else '0'; end beh;