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

Generated on Fri Sep 24 10:39:12 CEST 2010
Home