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

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