------------------------------------------------------------ -- 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 fsm is port ( ClkxCI : in std_logic; RstxRBI : in std_logic; NewBlockxSI : in std_logic; StatexDO : out integer range 0 to 6; CntxDO : out integer range 0 to 48; ValidOutxSO : out std_logic ); end fsm; architecture rtl of fsm is type state is (idle, bpm, perm1, perm2, apc, cmm); signal StatexDN, StatexDP : state; signal CntxDN, CntxDP : integer range 0 to 48; -- 0...47 counter signal FinalCntxDN, FinalCntxDP : unsigned(1 downto 0); -- 0...2 counter begin -- rtl p_fsm: process (CntxDP, FinalCntxDP, NewBlockxSI, StatexDP) begin -- process p_fsm CntxDN <= CntxDP; FinalCntxDN <= FinalCntxDP; StatexDN <= StatexDP; StatexDO <= 0; CntxDO <= CntxDP; ValidOutxSO <= '0'; case StatexDP is ------------------------------------------------------------------------- when idle => if NewBlockxSI = '1' then StatexDO <= 1; StatexDN <= bpm; CntxDN <= 0; FinalCntxDN <= (others => '0'); end if; ------------------------------------------------------------------------- -- when incw => -- CntxDN CntxDP + 1; -- StatexDO <= 1; -- if CntxDP = 1 then -- CntxDN <= 0; -- StatexDN <= bpm; -- end if; ----------------------------------------------------------------------- when bpm => CntxDN <= CntxDP + 1; StatexDO <= 2; if CntxDP = 15 then CntxDN <= 0; StatexDN <= perm1; end if; ----------------------------------------------------------------------- when perm1 => StatexDO <= 3; CntxDN <= CntxDP + 1; StatexDN <= perm2; ----------------------------------------------------------------------- when perm2 => StatexDO <= 4; if CntxDP = 48 then CntxDN <= 0; StatexDN <= apc; else StatexDN <= perm1; end if; ------------------------------------------------------------------------- when apc => CntxDN <= CntxDP + 1; StatexDO <= 5; if CntxDP = 35 then CntxDN <= 0; StatexDN <= cmm; end if; ----------------------------------------------------------------------- when cmm => CntxDN <= CntxDP + 1; StatexDO <= 6; if CntxDP = 16 then StatexDO <= 0; if NewBlockxSI = '0' then -- no more blocks: final rounds if FinalCntxDP = 3 then -- 1 ordinary round with last block + 3 CntxDN <= 0; StatexDN <= idle; ValidOutxSO <= '1'; else FinalCntxDN <= FinalCntxDP + 1; CntxDN <= 0; StatexDO <= 1; StatexDN <= bpm; end if; else StatexDO <= 1; CntxDN <= 0; StatexDN <= bpm; end if; 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; CntxDP <= 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;