------------------------------------------------------------
-- 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.groestl_pkg.all;
-- Possible generics values:
-- hs = {HASH_SIZE_256, HASH_SIZE_512}
entity gmu_groestl_control is
generic (
RST_ACTIVE_VALUE : std_logic := '0' );
port (
rst : in std_logic;
clk : in std_logic;
-- processing
init1 : out std_logic;
init2 : out std_logic;
init3 : out std_logic;
last_cycle : out std_logic;
finalization : out std_logic;
wr_state : out std_logic;
wr_result : out std_logic;
load_ctr : out std_logic;
wr_ctr : out std_logic;
p_mode : out std_logic;
InWrEnxSI : in std_logic;
FinBlockxSI : in std_logic;
OutWrEnxSO : out std_logic;
PenUltCyclexSO : out std_logic
);
end gmu_groestl_control;
architecture beh of gmu_groestl_control is
type stateType is ( initState, idleState, hashBlockState, finBlockState, hashLastBlockState, finLastBlockState );
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 := 20;
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 or cstate = hashLastBlockState) else '0';
loadRoundCtr <= '1' when (cstate = idleState or cstate = finBlockState or cstate = finLastBlockState) else '0';
roundDoneComp <= '1' when roundCtr = roundNumber-1 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;
nextStateComb:
process( cstate, InWrEnxSI, roundDoneComp, lastBlockFlag )
begin
case cstate is
when initState =>
nstate <= idleState;
when idleState =>
if InWrEnxSI = '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 <= hashLastBlockState;
elsif InWrEnxSI = '1' then
nstate <= hashBlockState;
else
nstate <= finBlockState;
end if;
when hashLastBlockState =>
if roundDoneComp = '1' then
nstate <= finLastBlockState;
else
nstate <= hashLastBlockState;
end if;
when finLastBlockState =>
nstate <= idleState;
end case;
end process;
PenUltCyclexSO <= '1' when (cstate = hashBlockState and roundDoneComp = '1' and lastBlockFlag = '0') or (cstate = finLastBlockState) 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 InWrEnxSI = '1') else '0';
lastBlockClr <= '1' when (cstate = idleState) else '0';
OutWrEnxSO <= '1' when (cstate = finLastBlockState) 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 = hashBlockState or cstate = hashLastBlockState) else '0';
-- Output
last_cycle <= '1' when (cstate = finBlockState) else '0';
finalization <= '1' when (cstate = finBlockState or cstate = finLastBlockState) else '0';
wr_ctr <= roundCtr(0);
p_mode <= '1' when (cstate = hashBlockState and roundCtr(0) = '1') or
(cstate = hashLastBlockState and roundCtr(0) = '0') else '0';
load_ctr <= '1' when (cstate = idleState) or ((cstate = hashBlockState or cstate = hashLastBlockState) and roundDoneComp = '1') else '0';
wr_state <= '1' when (cstate = hashBlockState or cstate = hashLastBlockState) or
(cstate = finBlockState and (lastBlockFlag = '1' or InWrEnxSI = '1')) or
(cstate = finLastBlockState) else '0';
wr_result <= '1' when (cstate = finBlockState and (lastBlockFlag = '1' or InWrEnxSI = '1')) or
((cstate = hashBlockState or cstate = hashLastBlockState) and roundDoneComp = '1') or
(sfFlag = '1') else '0';
init1 <= '1' when (cstate = hashBlockState and firstRoundComp = '1') else '0';
init2 <= '1' when (cstate = hashBlockState and (firstRoundComp = '1' or secondRoundComp = '1')) else '0';
init3 <= sfFlag;
end beh;