------------------------------------------------------------
-- Copyright: 2011 Integrated Sytems Laboratory, ETH Zurich
--            http://www.iis.ee.ethz.ch/~sha3
------------------------------------------------------------
-------------------------------------------------------------------------------
-- Title      : Groestl implementation
-- Project    : shabziger
-------------------------------------------------------------------------------
-- File       : ethz_groestl.vhd
-- Author     : Frank K. Guerkaynak  
-- Company    : Integrated Systems Laboratory, ETH Zurich
-- Created    : 2011-08-17
-- Last update: 2011-09-05
-- Platform   : ModelSim (simulation), Synopsys (synthesis)
-- Standard   : VHDL'87
-------------------------------------------------------------------------------
-- Description: Original code from sha3 r2 paper
-------------------------------------------------------------------------------
-- Copyright (c) 2011 Integrated Systems Laboratory, ETH Zurich
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author  Description
-- 2011-08-17  1.0      kgf	Created
-- 2011-09-02  2.0      kgf     Complete re-write
-- 2011-09-04  2.1      kgf     Corrections
-------------------------------------------------------------------------------

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

entity ethz_groestl is

  port (
    ClkxCI         : in  std_logic;
    RstxRBI        : in  std_logic;
    ScanInxTI      : in  std_logic;
    ScanOutxTO     : out std_logic;
    ScanEnxTI      : in  std_logic;
    InWrEnxSI      : in  std_logic;
    FinBlockxSI    : in  std_logic;
    OutWrEnxSO     : out std_logic;
    PenUltCyclexSO : out std_logic;
    MsgInxDI       : in  std_logic_vector(511 downto 0);
    HashOutxDO     : out std_logic_vector(255 downto 0));

end ethz_groestl;

architecture rtl of ethz_groestl is


  component groestl_p
    port (
      ClkxCI        : in  std_logic;
      RstxRBI       : in  std_logic;
      RndxSI        : in  std_logic_vector(7 downto 0);
      SubRndxSI     : in  integer range 0 to 7;
      InxDI         : in  std_logic_vector(511 downto 0);
      OutxDO        : out std_logic_vector(511 downto 0));
  end component;

  component groestl_q
    port (
      ClkxCI        : in  std_logic;
      RstxRBI       : in  std_logic;
      RndxSI        : in  std_logic_vector(7 downto 0);
      SubRndxSI     : in  integer range 0 to 7;
      InxDI         : in  std_logic_vector(511 downto 0);
      OutxDO        : out std_logic_vector(511 downto 0));
  end component;

-- state
  type   statetype is (init, first, round, lastround, final, lastfinal);
  signal StatexDN, StatexDP       : statetype;
  signal FinBlockxSN, FinBlockxSP : std_logic;
  signal UseIVxS                  : std_logic;  -- 1: use IV; 0: use Hout
  
-- counters
  signal RndxSN, RndxSP : unsigned(3 downto 0);  -- 8 bit representation of the Groestl round 1..11
  signal RndxS          : std_logic_vector(7 downto 0);
  signal SubRndxS       : integer range 0 to 7;  -- each block is completed in 8 cycles;
  signal CntxDN, CntxDP : unsigned(7 downto 0);  -- The counter
  signal IntCntxS       : integer range 0 to 255;  -- Integer version
  
-- interconnect
  signal   HxDN, HxDP         : std_logic_vector(511 downto 0);
  signal   HinxD, HoutxD      : std_logic_vector(511 downto 0);
  signal   PxD, QxD           : std_logic_vector(511 downto 0);
  signal   PinxD, PHxD, PQHxD : std_logic_vector(511 downto 0);
  constant IV                 : std_logic_vector(511 downto 0) := (8 => '1', others => '0');

-- saving power
  signal BlockOutEnxS : std_logic;      -- 1:when the output is needed

  
begin

-------------------------------------------------------------------------------
-- State Machine
-------------------------------------------------------------------------------
 p_fsm : process (StatexDP, InWrEnxSI, FinBlockxSI, CntxDP, IntCntxS, FinBlockxSP)
 begin  -- process p_fsm
   -- defaults
   StatexDN       <= StatexDP;
   OutWrEnxSO     <= '0';
   PenUltCyclexSO <= '0';
   CntxDN         <= CntxDP + 1;      -- count by default
   FinBlockxSN    <= FinBlockxSP;
   UseIVxS        <= '0';
   BlockOutEnxS   <= '0';
   
   case StatexDP is
     when init =>                          -- Use IV
       CntxDN  <= (others => '0');
       UseIVxS <= '1';                     -- Set the IV 
       if InWrEnxSI = '1' then
         StatexDN    <= round;
         FinBlockxSN <= FinBlockxSI;       -- sample the FinBlockxSI
       end if;
     --------------------------------------------------------------------------
     when first =>                         -- chain use old value, no IV is set
       CntxDN <= (others => '0');
       if InWrEnxSI = '1' then             -- wait till we have something
         StatexDN    <= round;             -- go to round
         FinBlockxSN <= FinBlockxSI;       -- sample FinBlockxSI
       end if;
     --------------------------------------------------------------------------
     when round =>
       if IntCntxS = 79 then
         if FinBlockxSP = '1' then         -- are we finished ?
             StatexDN <= final;            -- go to final
          else
             StatexDN       <= lastround;  -- separate state
             PenUltCyclexSO <= '1';        -- this is the PenUlt
         end if;
       end if;
     --------------------------------------------------------------------------  
     when lastround =>
       CntxDN       <= (others => '0');    -- reset the counter
       StatexDN     <= first;              -- wait for the new input
       BlockOutEnxS <= '1';
       if InWrEnxSI = '1' then             -- if the new input is here
         StatexDN    <= round;             -- jump directly to round
         FinBlockxSN <= FinBlockxSI;       -- sample FinBlockxSI
       end if;
     --------------------------------------------------------------------------  
     when final =>
       if IntCntxS = 159 then              -- penult cycle
         PenUltCyclexSO <= '1';
         StatexDN       <= lastfinal;      -- go to the last final (160)
       end if;
     --------------------------------------------------------------------------
     when lastfinal =>
       OutWrEnxSO   <= '1';                -- set the output
       StatexDN     <= init;               -- wait for new input
       CntxDN       <= (others => '0');    -- reset the counter
       BlockOutEnxS <= '1';
       if InWrEnxSI = '1' then             -- if new input is here
         UseIVxS     <= '1';               -- Take IV
         StatexDN    <= round;             -- continue directly
         FinBlockxSN <= FinBlockxSI;       -- sample the FinBlockxSI
       end if;
     --------------------------------------------------------------------------
     when others => null;
   end case;

   
 end process p_fsm;

  
-------------------------------------------------------------------------------
-- Derive the counters
-------------------------------------------------------------------------------
  SubRndxS <= to_integer(CntxDP(2 downto 0));
  RndxS    <= "0000" & std_logic_vector(RndxSP);
  IntCntxS <= to_integer(unsigned(CntxDP));

  -- The round counter needs to be determined depending on
  -- whether or not we are in the final round
  p_cnt: process (RndxSP, IntCntxS)
  begin  -- process p_cnt
    RndxSN <= RndxSP;
    if (IntCntxS = 79) then
      RndxSN <= (others => '0');
    elsif (IntCntxS = 159) then
      RndxSN <=  (others => '0');  
    elsif (IntCntxS mod 8 = 7) then
      RndxSN <= RndxSP + 1;
    end if;
  end process p_cnt;
 



 
-------------------------------------------------------------------------------
-- Interconnections
-------------------------------------------------------------------------------
  HinxD <= IV when UseIVxS = '1'  else HoutxD;  -- add IV in the first round


  PinxD <= HxDN when StatexDP = final else MsgInxDI xor HxDN;          -- input of P


 
  p_storeH : process (HxDP, StatexDP, HinxD, IntCntxS)
  begin  -- process p_storeH
    HxDN <= HxDP;                       -- keep H value constant
    if IntCntxS = 80 then
      HxDN <= HinxD;                    -- end of the block
    elsif IntCntxS = 160 then           -- technically also at 159..
      HxDN <= HinxD;                    -- end of final
    elsif StatexDP = init then          -- change at Init (IV)
      HxDN <= HinxD;                    -- Sample the output
    end if;
  end process p_storeH;

  PHxD  <= PxD xor HxDP;                -- XOR the output with H
  PQHxD <= PHxD xor QxD;                -- XOR P H and Q

  HoutxD <= PQHxD when  IntCntxS = 80 else PHxD;  -- on round 80 we will sample
                                                  -- P xor Q xor H

  HashOutxDO <= HoutxD(255 downto 0);   -- take the LSB
 
-------------------------------------------------------------------------------
-- Instantiate P and Q 
-------------------------------------------------------------------------------

  i_p : groestl_p
    port map (
      ClkxCI        => ClkxCI,
      RstxRBI       => RstxRBI,
      RndxSI        => RndxS,
      SubRndxSI     => SubRndxS,
      InxDI         => PinxD,
      OutxDO        => PxD);

  i_q : groestl_q
    port map (
      ClkxCI        => ClkxCI,
      RstxRBI       => RstxRBI,
      RndxSI        => RndxS,
      SubRndxSI     => SubRndxS,
      InxDI         => MsgInxDI,
      OutxDO        => QxD);

-----------------------------------------------------------------------------
-- Memory
-----------------------------------------------------------------------------
  p_mem : process (ClkxCI, RstxRBI)
  begin  -- process p_mem
    if RstxRBI = '0' then               -- asynchronous reset (active low)
      StatexDP    <= init;
      CntxDP      <= (others => '0');
      HxDP        <= (others => '0');
      FinBlockxSP <= '0';
      RndxSP      <= (others => '0');
    elsif ClkxCI'event and ClkxCI = '1' then  -- rising clock edge
      StatexDP    <= StatexDN;
      CntxDP      <= CntxDN;
      HxDP        <= HxDN;
      FinBlockxSP <= FinBlockxSN;
      RndxSP      <= RndxSN;
    end if;
  end process p_mem;


  
end rtl;



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