------------------------------------------------------------ -- 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; CntxDO : out unsigned(2 downto 0); BcontrolxSO : out std_logic_vector(1 downto 0); FirstxSO : out std_logic; FinBlockxSI : in std_logic; OutxSO : out std_logic; KinitxSO : out std_logic; LastxSO : 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, CntxDP, 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'; LastxSO <= '0'; 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); CntxDN <= CntxDP + 1; if StCntxDP = 18 then KenablexSO <= '1'; FirstxSO <= FinBlockxSI; OutxSO <= FinBlockxSI; end if; if StCntxDP = 17 and CntxDP = 7 then StCntxDN <= StCntxDP + 1; if FinBlockxSI = '0' then BcontrolxSO <= "01"; else BcontrolxSO <= "00"; end if; elsif StCntxDP = 18 and CntxDP = 7 then GselectxSO <= '0'; MenablexSO <= '1'; StCntxDN <= (others => '0'); if FinBlockxSI = '0' then StatexDN <= ss; else StatexDN <= fss; end if; else if CntxDP = 7 then StCntxDN <= StCntxDP + 1; end if; end if; ------------------------------------------------------------------------- when ss => SxSO <= std_logic_vector(StCntxDP); GselectxSO <= '1'; BcontrolxSO <= "11"; PerselectxSO <= not StCntxDP(0); FirstxSO <= '0'; CntxDN <= CntxDP + 1; if StCntxDP = 18 then KenablexSO <= '1'; FirstxSO <= FinBlockxSI; OutxSO <= FinBlockxSI; end if; if StCntxDP = 17 and CntxDP = 7 then StCntxDN <= StCntxDP + 1; if FinBlockxSI = '0' then BcontrolxSO <= "01"; else BcontrolxSO <= "00"; end if; elsif StCntxDP = 18 and CntxDP = 7 then GselectxSO <= '0'; MenablexSO <= '1'; StCntxDN <= (others => '0'); if FinBlockxSI = '0' then StatexDN <= ss; else StatexDN <= fss; end if; else if CntxDP = 7 then StCntxDN <= StCntxDP + 1; end if; end if; ------------------------------------------------------------------------- when fss => SxSO <= std_logic_vector(StCntxDP); GselectxSO <= '1'; BcontrolxSO <= "11"; PerselectxSO <= not StCntxDP(0); OutxSO <= '1'; CntxDN <= CntxDP + 1; if StCntxDP = 18 then KenablexSO <= '1'; if CntxDP = 0 then LastxSO <= '1'; elsif CntxDP = 1 then HashAvailablexSO <= '1'; end if; end if; if StCntxDP = 0 and CntxDP = 0 then MenablexSO <= '1'; MzeroxSO <= '1'; elsif StCntxDP = 18 and CntxDP = 7 then FirstxSO <= '1'; OutxSO <= '0'; MenablexSO <= '1'; StCntxDN <= (others => '0'); if BlockAvailablexSI = '0' then StatexDN <= idle; else StatexDN <= iss; end if; else if CntxDP = 7 then StCntxDN <= StCntxDP + 1; 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;