------------------------------------------------------------
-- Copyright: 2011 George Mason University, Virginia USA
--            http://www.iis.ee.ethz.ch/~sha3
------------------------------------------------------------
-- =====================================================================

-- Copyright © 2010-11 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.sha2_pkg.all;

entity gmu_sha2_control is	
	generic ( 
		a : integer := LOG_2_64
	);
	port(	
		clk						:in std_logic;
		rst						:in std_logic;	  
		
		-- to datpath

		sel2					:out std_logic;
		sel						:out std_logic;
		sel_gh					:out std_logic;
		sel_gh2					:out std_logic;
		wr_data					:out std_logic;
		kw_wr					:out std_logic;
		wr_state				:out std_logic;
		wr_result				:out std_logic;						  
		init_reg				:out std_logic;
		init_block				:out std_logic;
		rd_num					:out std_logic_vector(a-1 downto 0);
		
		-- external

		InWrEnxSI				: in std_logic;
		FinBlockxSI				: in std_logic;	
		OutWrEnxSO				: out std_logic;
		PenUltCyclexSO 			: out std_logic
	);
end gmu_sha2_control;



architecture asic_controller of gmu_sha2_control is


    type state_type is (
						prep_data,
						wr_get_data, 
						kw_compute, 
						data, 
						data_end, 
						dummy, 
						computation, 
						computation_end, 
						result_delay, 
						result_delay2, 
						result_delay3, 	
						result, 
						mux_gh,
						send_data, 
						done);

	signal next_state, current_state: state_type;
	attribute enum_encoding : string;
						 
	signal roundCtr : std_logic_vector(a-1 downto 0);
	signal incRoundCtr, loadRoundCtr : std_logic;
	signal lastBlockFlag, lastBlockSet, lastBlockClr : std_logic;  	  
	signal nextBlockIsLastFlag, nextBlockIsLastSet : std_logic;
	signal loadFinFlagReg, computedFinFlagReg : std_logic;
	signal loadFinFlag, computedFinFlag : std_logic;
begin
	roundCtrProc:
		process( rst, clk )
		begin
			if (rst = '0') 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; 
		rd_num <= roundCtr;
		
    state_reg: process(clk, rst)
	    begin
			if (rst='0') then
				current_state <= done; -- set to done to reset all the flags

			elsif (clk'event and clk='1') then
				current_state <= next_state;
			end if;
	    end process;
		

	roundCompareRegister : process( clk, rst )
		begin
			if (rst='0') then
				loadFinFlagReg <= '0';
				computedFinFlagReg <= '0';
			elsif (clk'event and clk='1') then
				loadFinFlagReg 	<= loadFinFlag;
				computedFinFlagReg <= computedFinFlag;
			end if;
		end process;	   
		
	loadFinFlag 	<= '1' when roundCtr = 11 else '0';
	computedFinFlag <= '1' when roundCtr = 59 else '0';

    comb_logic: process(current_state, InWrEnxSI, loadFinFlagReg, computedFinFlagReg, lastBlockFlag)
	    begin
			case current_state is
				when prep_data => 
					if InWrEnxSI = '1' then
						next_state <= wr_get_data;
					else
						next_state <= prep_data;
					end if;
		
			    when wr_get_data =>					
					next_state <= kw_compute;					
		
				when kw_compute =>	
					next_state <= data;
		
			    when data =>	
					if loadFinFlagReg='1' then               
		                next_state <= data_end;
		           	else
		            	next_state <= data;
					end if;
			
			    when data_end =>	
					next_state <= dummy;
		
				when dummy =>	
					next_state <= computation;						
		
			    when computation =>	
					if computedFinFlagReg='1' then
					    next_state <= computation_end;
					else
					    next_state <= computation;
					end if;
		
				when computation_end=>			
					next_state <= result_delay;
									  
				when result_delay=>	
						next_state <= result_delay2;
		
				when result_delay2=>
						next_state <= result_delay3;
		
				when result_delay3=>	
					if InWrEnxSI='1' or lastBlockFlag = '1' then
						next_state <= result; 
					else
						next_state <= result_delay3;
					end if;
			    when result =>	
					if lastBlockFlag='1' then
						next_state <= send_data;   
					else
						next_state <= mux_gh;					
					end if;	
			
				when mux_gh =>			   -- if message not done

					next_state <= data;					
		
			    when send_data =>	
					next_state <= done;					
				when done =>
					next_state <= prep_data; 	
			end case;
	    end process;
	
	wr_data <= '1' when  
	(InWrEnxSI = '1'  and 
		((current_state=prep_data) 	
		or (current_state=result_delay3 and lastBlockFlag = '0'))
	)
	or (current_state=dummy)
	or (current_state=result)  
	or (current_state=mux_gh) 																			 
	or (current_state=result)
	or (current_state=wr_get_data) or (current_state=kw_compute) or (current_state=data) or (current_state=data_end)
	or (current_state=computation) or (current_state=computation_end) or (current_state=result_delay) or (current_state=result_delay2) 
	else '0'; 

 	wr_result<= '1' when  (current_state= result_delay) 
	or (current_state= result_delay2) 
	or (current_state= result_delay3 and (InWrEnxSI='1' or lastBlockFlag = '1'))  
	or (current_state=result) 
	or current_state=send_data else '0';
		

	wr_state <= '1' when 
	((InWrEnxSI = '1' or lastBlockFlag = '1') and (current_state=result_delay3))
	or (current_state=data_end) 
	or (current_state=dummy) 
	or (current_state = kw_compute)
	or (current_state = data) 
	or (current_state=result)  
	or (current_state=mux_gh) 
	or (current_state=computation or current_state=computation_end or current_state=result_delay or current_state=result_delay2)  
	else '0';
	
	incRoundCtr <= '1' when 
	(current_state=wr_get_data) 
	or (current_state=kw_compute)
	or (current_state=data) 
	or (current_state=data_end) 	
	or (current_state=dummy)		
	or (current_state=mux_gh)
	or (current_state=result and lastBlockFlag = '0') 
	or (current_state=computation) or (current_state=computation_end) or (current_state=result_delay) or (current_state=result_delay2)  
	else '0';				 
	
	loadRoundCtr <= '1' when (current_state=done) else '0';
	init_reg <= loadRoundCtr;
	
	kw_wr <='1' when 
	(current_state=kw_compute) 
	or (current_state = wr_get_data)
	or (current_state=data) 
	or (current_state=data_end) 
	or (current_state=dummy)		  
	or ((current_state=result or current_state=mux_gh) and lastBlockFlag = '0')
	or (current_state=computation) or (current_state=computation_end) or (current_state=result_delay) or (current_state=result_delay2)  
	else '0';
		
	sel	<= '1' when (current_state=result) else '0';
	
	init_block <= '1' when (current_state=result_delay3) or (current_state=prep_data) else '0'; 
	sel2 <='1' when  (current_state=computation) or (current_state=computation_end) or (current_state=result_delay)  else '0';

	sel_gh <= '1' when (current_state=wr_get_data) or (current_state=result)  else '0';

	sel_gh2 <= '1' when  (current_state=result) else '0';
	
	OutWrEnxSO <= '1' when (current_state=send_data) else '0';		  
	
	lastBlockInst: 
		entity work.sr_rega(struct) 
		port map ( rst => rst, clk => clk, set => lastBlockSet, clr => lastBlockClr, output => lastBlockFlag );
	lastBlockSet <= '1' when ((current_state = prep_data ) and (FinBlockxSI = '1' and InWrEnxSI = '1')) or
							 (current_state = mux_gh and nextBlockIsLastFlag = '1') else '0';
	lastBlockClr <= '1' when (current_state = send_data) else '0';	
	
	nextBlockIslastInst: 
		entity work.sr_rega(struct) 
		port map ( rst => rst, clk => clk, set => nextBlockIsLastSet, clr => lastBlockClr, output => nextBlockIsLastFlag );
	nextBlockIsLastSet <= '1' when (current_state = result_delay3 and (FinBlockxSI = '1' and InWrEnxSI = '1')) else '0';

	PenUltCyclexSO <= '1' when (current_state = result_delay2 and lastBlockFlag = '0') or (current_state = done) else '0';	
	
end asic_controller;

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