------------------------------------------------------------
-- 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;