------------------------------------------------------------ -- Copyright: 2010 Integrated Sytems Laboratory, ETH Zurich -- http://www.iis.ee.ethz.ch/~sha3 ------------------------------------------------------------ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity controller is port ( ClkxCI : in std_logic; RstxRBI : in std_logic; NewBlockxSI : in std_logic; StatexDO : out std_logic_vector(1 downto 0); CntxDO : out unsigned(1 downto 0); LastxSO : out std_logic; ValidOutxSO : out std_logic ); end controller; architecture rtl of controller is type state is (idle, core, apc); signal StatexDN, StatexDP : state; signal CntxDN, CntxDP : unsigned(5 downto 0); -- 0...47 counter signal FinalCntxDN, FinalCntxDP : unsigned(1 downto 0); -- 0...2 counter begin -- rtl p_fsm: process (FinalCntxDP, NewBlockxSI, CntxDP, StatexDP) begin -- process p_fsm StatexDN <= idle; CntxDN <= CntxDP; FinalCntxDN <= FinalCntxDP; StatexDO <= "00"; ValidOutxSO <= '0'; LastxSO <= '0'; CntxDO <= CntxDP(1 downto 0); case StatexDP is ------------------------------------------------------------------------- when idle => StatexDN <= idle; if NewBlockxSI = '1' then StatexDO <= "11"; StatexDN <= core; FinalCntxDN <= (others => '0'); CntxDN <= (others => '0'); end if; ------------------------------------------------------------------------- when core => StatexDO <= "01"; if CntxDP = 47 then CntxDN <= (others => '0'); StatexDN <= apc; else CntxDN <= CntxDP + 1; StatexDN <= core; end if; ------------------------------------------------------------------------- when apc => StatexDO <= "10"; if CntxDP = 3 then if NewBlockxSI = '0' then -- no more blocks: final rounds if FinalCntxDP = 3 then -- 1 ordinary round with last block + 3 StatexDO <= "00"; -- final rounds StatexDN <= idle; ValidOutxSO <= '1'; else FinalCntxDN <= FinalCntxDP + 1; CntxDN <= (others => '0'); StatexDO <= "11"; LastxSO <= '1'; StatexDN <= core; end if; else CntxDN <= (others => '0'); StatexDO <= "11"; StatexDN <= core; end if; else CntxDN <= CntxDP + 1; StatexDN <= apc; end if; ------------------------------------------------------------------------- when others => null; 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; CntxDP <= (others => '0'); FinalCntxDP <= (others => '0'); elsif ClkxCI'event and ClkxCI = '1' then -- rising clock edge StatexDP <= StatexDN; CntxDP <= CntxDN; FinalCntxDP <= FinalCntxDN; end if; end process p_mem; end rtl;