------------------------------------------------------------
-- Copyright: 2010 Integrated Sytems Laboratory, ETH Zurich
-- http://www.iis.ee.ethz.ch/~sha3
------------------------------------------------------------
library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
entity controller is
port (
BlockAvailablexSI : in std_logic;
ClkxCI : in std_logic;
RstxRBI : in std_logic;
SxSO : out std_logic_vector(4 downto 0);
MenablexSO : out std_logic;
GselectxSO : out std_logic;
PerselectxSO : out std_logic;
KenablexSO : out std_logic;
BcontrolxSO : out std_logic_vector(1 downto 0);
FirstxSO : out std_logic;
FinBlockxSI : in std_logic;
OutxSO : out std_logic;
KinitxSO : out std_logic;
MzeroxSO : out std_logic;
HashAvailablexSO : out std_logic);
end controller;
architecture rtl of controller is
type state is (idle, iss, ss, fss);
signal StatexDP, StatexDN : state;
signal StCntxDP, StCntxDN : unsigned(4 downto 0);
signal CntxDN, CntxDP : unsigned(2 downto 0);
begin -- rtl
--CntxDO CntxDP;
p_fsm : process (BlockAvailablexSI, FinBlockxSI, StCntxDP, StatexDP)
begin -- process p_fsm
StatexDN <= StatexDP;
StCntxDN <= StCntxDP;
CntxDN <= (others => '0');
HashAvailablexSO <= '0';
MenablexSO <= '0';
GselectxSO <= '0';
SxSO <= "00000";
KenablexSO <= '0';
BcontrolxSO <= "10";
FirstxSO <= '1';
OutxSO <= '0';
KinitxSO <= '0';
MzeroxSO <= '0';
PerselectxSO <= '1';
case StatexDP is
-------------------------------------------------------------------------
when idle =>
if BlockAvailablexSI = '1' then
StatexDN <= iss;
end if;
MenablexSO <= '1';
KinitxSO <= '1';
KenablexSO <= '1';
-------------------------------------------------------------------------
when iss =>
SxSO <= std_logic_vector(StCntxDP);
GselectxSO <= '1';
BcontrolxSO <= "11";
PerselectxSO <= not StCntxDP(0);
StCntxDN <= StCntxDP + 1;
if StCntxDP = 17 then
if FinBlockxSI = '0' then
BcontrolxSO <= "01";
else
BcontrolxSO <= "00";
end if;
elsif StCntxDP = 18 then
GselectxSO <= '0';
KenablexSO <= '1';
FirstxSO <= FinBlockxSI;
OutxSO <= FinBlockxSI;
MenablexSO <= '1';
StCntxDN <= (others => '0');
if FinBlockxSI = '0' then
StatexDN <= ss;
else
StatexDN <= fss;
end if;
else
StCntxDN <= StCntxDP + 1;
end if;
-------------------------------------------------------------------------
when ss =>
SxSO <= std_logic_vector(StCntxDP);
GselectxSO <= '1';
BcontrolxSO <= "11";
PerselectxSO <= not StCntxDP(0);
FirstxSO <= '0';
StCntxDN <= StCntxDP + 1;
if StCntxDP = 17 then
if FinBlockxSI = '0' then
BcontrolxSO <= "01";
else
BcontrolxSO <= "00";
end if;
elsif StCntxDP = 18 then
GselectxSO <= '0';
KenablexSO <= '1';
FirstxSO <= FinBlockxSI;
OutxSO <= FinBlockxSI;
MenablexSO <= '1';
StCntxDN <= (others => '0');
if FinBlockxSI = '0' then
StatexDN <= ss;
else
StatexDN <= fss;
end if;
end if;
-------------------------------------------------------------------------
when fss =>
SxSO <= std_logic_vector(StCntxDP);
GselectxSO <= '1';
BcontrolxSO <= "11";
PerselectxSO <= not StCntxDP(0);
OutxSO <= '1';
StCntxDN <= StCntxDP + 1;
if StCntxDP = 0 then
MenablexSO <= '1';
MzeroxSO <= '1';
elsif StCntxDP = 18 then
HashAvailablexSO <= '1';
KenablexSO <= '1';
FirstxSO <= '1';
OutxSO <= '0';
MenablexSO <= '1';
StCntxDN <= (others => '0');
if BlockAvailablexSI = '0' then
StatexDN <= idle;
else
StatexDN <= iss;
end if;
end if;
-------------------------------------------------------------------------
when others => StatexDN <= idle;
end case;
end process p_fsm;
-- Memory
-----------------------------------------------------------------------------
p_mem : process (ClkxCI, RstxRBI)
begin -- process p_mem
if RstxRBI = '0' then -- asynchronous reset (active low)
StatexDP <= idle;
StCntxDP <= (others => '0');
CntxDP <= (others => '0');
elsif ClkxCI'event and ClkxCI = '1' then -- rising clock edge
StatexDP <= StatexDN;
StCntxDP <= StCntxDN;
CntxDP <= CntxDN;
end if;
end process p_mem;
end rtl;