------------------------------------------------------------
-- 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;

Generated on Tue Nov 22 15:16:34 CET 2011
Home