------------------------------------------------------------
-- Copyright: 2011 Integrated Sytems Laboratory, ETH Zurich
--            http://www.iis.ee.ethz.ch/~sha3
------------------------------------------------------------
-------------------------------------------------------------------------------
-- Title      : Keccak
-- Project    : Schabziger
-------------------------------------------------------------------------------
-- File       : keccak_controller.vhd
-- Author     : Frank K. Guerkaynak  
-- Company    : Integrated Systems Laboratory, ETH Zurich
-- Created    : 2011-08-10
-- Last update: 2011-08-17
-- Platform   : ModelSim (simulation), Synopsys (synthesis)
-- Standard   : VHDL'87
-------------------------------------------------------------------------------
-- Description: FSM for Keccak, original by Pietro Gendotti
-------------------------------------------------------------------------------
-- Copyright (c) 2011 Integrated Systems Laboratory, ETH Zurich
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author  Description
-- 2011-08-10  1.0      kgf	Added the BlockDonexSO signal to tell that the
--                              computation has reached the last round
-- 2011-08-16  1.1      kgf     FinBlockxSI is now registered it will be
--                              sampled at the same time as the InEnxEI
-------------------------------------------------------------------------------

library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;

entity keccak_controller is

  port (
    ClkxCI         : in  std_logic;
    RstxRBI        : in  std_logic;
    FinBlockxSI    : in  std_logic;
    INENxEI        : in  std_logic;
    OUTENxEO       : out std_logic;
    StateSelxSO    : out std_logic;
    PenUltCyclexSO : out std_logic;
    RcntxDO        : out unsigned(4 downto 0));


end keccak_controller;

architecture rtl of keccak_controller is

  type   state is (idle, round);
  signal StatexDP, StatexDN : state;
  signal RcntxDP, RcntxDN   : unsigned(4 downto 0);

  -- FinBlockxSI is stored until the last cycle
  signal FinBlockxSP, FinBlockxSN : std_logic;

  
begin  -- rtl

  p_fsm: process (FinBlockxSI, FinBlockxSP, INENxEI, RcntxDP, StatexDP)
  begin  -- process p_fsm

    StatexDN       <= StatexDP;
    RcntxDN        <= (others => '0');  -- default sets the round to '0'
    RcntxDO        <= RcntxDP;
    OUTENxEO       <= '0';
    StateSelxSO    <= '1';
    PenUltCyclexSO <= '0';
    FinBlockxSN    <= FinBlockxSP;

    case StatexDP is
      -------------------------------------------------------------------------
      when idle =>

        if INENxEI = '1' then
          StatexDN    <= round;
          StateSelxSO <= '0';
          FinBlockxSN <= FinBlockxSI;   -- sample the final block input
        end if;

      -------------------------------------------------------------------------
      when round =>
        StateSelxSO <= '1';          
        if RcntxDP = 22 then       -- notify the output one cycle before end
          PenUltCyclexSO <= '1';
          RcntxDN <= RcntxDP + 1;
        elsif RcntxDP = 23 then
          if FinBlockxSP = '1' then
            OUTENxEO <= '1';
            FinBlockxSN <='0';          -- clear the final block, we have the output
            if INENxEI= '1' then        -- chain directly if possible
              StatexDN <= round;
              StateSelxSO <= '0';
              FinBlockxSN <= FinBlockxSI;  -- sample the final block input
            else
              StatexDN <= idle;
            end if;
          else
            FinBlockxSN <= FinBlockxSI;  -- this block is not final, and we
                                         -- have a new block that could be final
            StatexDN <= round;
          end if;
        else
          RcntxDN <= RcntxDP + 1;
        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;
      RcntxDP  <= (others => '0');
      FinBlockxSP <= '0';
      
    elsif ClkxCI'event and ClkxCI = '1' then  -- rising clock edge
      StatexDP <= StatexDN;
      RcntxDP  <= RcntxDN;
      FinBlockxSP <= FinBlockxSN;
    end if;
  end process p_mem;

end rtl;

Generated on Tue Nov 22 15:16:34 CET 2011
Home