------------------------------------------------------------ -- Copyright: 2011 Integrated Sytems Laboratory, ETH Zurich -- http://www.iis.ee.ethz.ch/~sha3 ------------------------------------------------------------ ------------------------------------------------------------------------------- -- Title : Keccak -- Project : Schabziger ------------------------------------------------------------------------------- -- File : keccak_controller.vhd -- Author : Frank K. Guerkaynak -- Company : Integrated Systems Laboratory, ETH Zurich -- Created : 2011-08-10 -- Last update: 2011-08-17 -- Platform : ModelSim (simulation), Synopsys (synthesis) -- Standard : VHDL'87 ------------------------------------------------------------------------------- -- Description: FSM for Keccak, original by Pietro Gendotti ------------------------------------------------------------------------------- -- Copyright (c) 2011 Integrated Systems Laboratory, ETH Zurich ------------------------------------------------------------------------------- -- Revisions : -- Date Version Author Description -- 2011-08-10 1.0 kgf Added the BlockDonexSO signal to tell that the -- computation has reached the last round -- 2011-08-16 1.1 kgf FinBlockxSI is now registered it will be -- sampled at the same time as the InEnxEI ------------------------------------------------------------------------------- library ieee; use ieee.numeric_std.all; use ieee.std_logic_1164.all; entity keccak_controller is port ( ClkxCI : in std_logic; RstxRBI : in std_logic; FinBlockxSI : in std_logic; INENxEI : in std_logic; OUTENxEO : out std_logic; StateSelxSO : out std_logic; PenUltCyclexSO : out std_logic; RcntxDO : out unsigned(4 downto 0)); end keccak_controller; architecture rtl of keccak_controller is type state is (idle, round); signal StatexDP, StatexDN : state; signal RcntxDP, RcntxDN : unsigned(4 downto 0); -- FinBlockxSI is stored until the last cycle signal FinBlockxSP, FinBlockxSN : std_logic; begin -- rtl p_fsm: process (FinBlockxSI, FinBlockxSP, INENxEI, RcntxDP, StatexDP) begin -- process p_fsm StatexDN <= StatexDP; RcntxDN <= (others => '0'); -- default sets the round to '0' RcntxDO <= RcntxDP; OUTENxEO <= '0'; StateSelxSO <= '1'; PenUltCyclexSO <= '0'; FinBlockxSN <= FinBlockxSP; case StatexDP is ------------------------------------------------------------------------- when idle => if INENxEI = '1' then StatexDN <= round; StateSelxSO <= '0'; FinBlockxSN <= FinBlockxSI; -- sample the final block input end if; ------------------------------------------------------------------------- when round => StateSelxSO <= '1'; if RcntxDP = 22 then -- notify the output one cycle before end PenUltCyclexSO <= '1'; RcntxDN <= RcntxDP + 1; elsif RcntxDP = 23 then if FinBlockxSP = '1' then OUTENxEO <= '1'; FinBlockxSN <='0'; -- clear the final block, we have the output if INENxEI= '1' then -- chain directly if possible StatexDN <= round; StateSelxSO <= '0'; FinBlockxSN <= FinBlockxSI; -- sample the final block input else StatexDN <= idle; end if; else FinBlockxSN <= FinBlockxSI; -- this block is not final, and we -- have a new block that could be final StatexDN <= round; end if; else RcntxDN <= RcntxDP + 1; end if; ------------------------------------------------------------------------- when others => StatexDN <= idle; end case; end process p_fsm; p_mem : process (ClkxCI, RstxRBI) begin -- process p_mem if RstxRBI = '0' then -- asynchronous reset (active low) StatexDP <= idle; RcntxDP <= (others => '0'); FinBlockxSP <= '0'; elsif ClkxCI'event and ClkxCI = '1' then -- rising clock edge StatexDP <= StatexDN; RcntxDP <= RcntxDN; FinBlockxSP <= FinBlockxSN; end if; end process p_mem; end rtl;