------------------------------------------------------------
-- Copyright: 2011 Integrated Sytems Laboratory, ETH Zurich
--            http://www.iis.ee.ethz.ch/~sha3
------------------------------------------------------------
-------------------------------------------------------------------------------
-- Title      : SHA256Main
-- Project    : 
-------------------------------------------------------------------------------
-- File       : SHA256Main.vhdl
-- Author     : Köppel Benedikt;Schnydrig Mathias  
-- Company    : Integrated Systems Laboratory, ETH Zurich
-- Created    : 2010-10-28
-- Last update: 2011-09-08
-- Platform   : ModelSim (simulation), Synopsys (synthesis)
-- Standard   : VHDL'87
-------------------------------------------------------------------------------
-- Description: SHA 256 Main Part which calculates the SHA 256 sum for one
-- message of 512 bits
-------------------------------------------------------------------------------
-- Copyright (c) 2010 Integrated Systems Laboratory, ETH Zurich
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author  Description
-- 2010-10-28  1.0      sem10h7 Created
-------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use work.shapkg.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;

entity SHA256Main is

  port (
    MessageInxDI       : in  expmess_arr;
    InWrEnxSI          : in  std_logic;
    HInxDI             : in  h_arr;
    CLKxCI             : in  std_logic;
    RSTxRBI            : in  std_logic;
    VALIDOUTxSO        : out std_logic;
    HOutxDO            : out h_arr;
    MessageReadyxSI    : in  std_logic;  -- EnablexSI
    PenUltCyclexSO     : out std_logic;
    MessageReceivedxSO : out std_logic   -- bin am shaen
    );

end SHA256Main;

architecture behave of SHA256Main is

  -- for the message
  signal ExpMessxDP : expmess_arr;
  signal ExpMessxDN : expmess_arr;

  -- for the FSM itself
  type   state is (Idle, Read, Hash, Output);
  signal StatexDP : state;
  signal StatexDN : state;

  -- for FSMs counter
  signal KKCounterxDP : std_logic_vector(5 downto 0);  -- count from 0 to 63 for KK
  signal KKCounterxDN : std_logic_vector(5 downto 0);

  -- to connect the MessageExpansion
  signal WKK15xD  : std_logic_vector(31 downto 0);
  signal WKK2xD   : std_logic_vector(31 downto 0);
  signal WKK16xD  : std_logic_vector(31 downto 0);
  signal WKK7xD   : std_logic_vector(31 downto 0);
  signal WKKnewxD : std_logic_vector(31 downto 0);

  component MessageExpansion
    port (
      WKK15xDI : in  std_logic_vector(31 downto 0);
      WKK2xDI  : in  std_logic_vector(31 downto 0);
      WKK16xDI : in  std_logic_vector(31 downto 0);
      WKK7xDI  : in  std_logic_vector(31 downto 0);
      WKKxDO   : out std_logic_vector(31 downto 0));
  end component;



  -- to connect the MainLoop

  signal AtoHmainxD : h_arr;
  signal AtoHnewxD  : h_arr;
  signal WKKmainxD  : std_logic_vector(31 downto 0);
  signal KKKmainxD  : std_logic_vector(31 downto 0);

  component MainLoop
    port (
      KKKxDI  : in  std_logic_vector(31 downto 0);
      WKKxDI  : in  std_logic_vector(31 downto 0);
      AtoHxDI : in  h_arr;
      AtoHxDO : out h_arr
      );
  end component;



  -- to connect StoreAtoH
  signal AtoHxDN : h_arr;
  signal AtoHxDP : h_arr;

  -- Signals in Message Expansion
  signal S0xD      : std_logic_vector(31 downto 0);
  signal S1xD      : std_logic_vector(31 downto 0);
  signal WKKsum1xD : std_logic_vector(31 downto 0);
  signal WKKsum2xD : std_logic_vector(31 downto 0);



begin

-------------------------------------------------------------------------------
-- Message Expansion
-------------------------------------------------------------------------------

  
  S0xD <= ("000"&WKK15xD(31 downto 3)) xor (WKK15xD(17 downto 0)&WKK15xD(31 downto 18)) xor (WKK15xD(6 downto 0)&WKK15xD(31 downto 7));

  S1xD <= ("0000000000"&WKK2xD(31 downto 10)) xor (WKK2xD(18 downto 0)&WKK2xD(31 downto 19)) xor (WKK2xD(16 downto 0)&WKK2xD(31 downto 17));

  WKKsum1xD <= S0xD + S1xD;
  WKKsum2xD <= WKK16xD + WKK7xD;

  WKKnewxD <= WKKsum1xD + WKKsum2xD;




-------------------------------------------------------------------------------
-- Main Loop
-------------------------------------------------------------------------------

  -- instance for MainLoop
  i_MainLoop : MainLoop
    port map (
      KKKxDI  => KKKmainxD,
      WKKxDI  => WKKmainxD,
      AtoHxDI => AtoHmainxD,
      AtoHxDO => AtoHnewxD
      );

-------------------------------------------------------------------------------
-- StreAtoH
-------------------------------------------------------------------------------
  
  p_mem_AtoH : process (CLKxCI, RSTxRBI)
  begin  -- process p_mem
    if RSTxRBI = '0' then               -- asynchronous reset (active low)
      AtoHxDP <= (others => (others => '0'));
    elsif CLKxCI'event and CLKxCI = '1' then  -- rising clock edge
      AtoHxDP <= AtoHxDN;
    end if;
  end process p_mem_AtoH;


-------------------------------------------------------------------------------
-- update H
-------------------------------------------------------------------------------

  HOutxDO(0) <= AtoHxDP(0) + HInxDI(0);
  HOutxDO(1) <= AtoHxDP(1) + HInxDI(1);
  HOutxDO(2) <= AtoHxDP(2) + HInxDI(2);
  HOutxDO(3) <= AtoHxDP(3) + HInxDI(3);
  HOutxDO(4) <= AtoHxDP(4) + HInxDI(4);
  HOutxDO(5) <= AtoHxDP(5) + HInxDI(5);
  HOutxDO(6) <= AtoHxDP(6) + HInxDI(6);
  HOutxDO(7) <= AtoHxDP(7) + HInxDI(7);




  -- purpose: Store the expanded message
  p_mess_mem : process (CLKxCI, RSTxRBI)
  begin  -- process p_mem
    if RSTxRBI = '0' then               -- asynchronous reset (active low)
      ExpMessxDP <= (others => (others => '0'));
    elsif CLKxCI'event and CLKxCI = '1' then  -- rising clock edge
      ExpMessxDP <= ExpMessxDN;
    end if;
  end process p_mess_mem;


  -- purpose: update KK counter
  p_kkcount_mem : process (CLKxCI, RSTxRBI)
  begin  -- process p_kkcount_mem
    if RSTxRBI = '0' then               -- asynchronous reset (active low)
      KKCounterxDP <= (others => '0');
    elsif CLKxCI'event and CLKxCI = '1' then  -- rising clock edge
      KKCounterxDP <= KKCounterxDN;
    end if;
  end process p_kkcount_mem;



  p_update_state_mem_test : process (CLKxCI, RSTxRBI)
  begin  -- process p_update_state_mem_test
    if RSTxRBI = '0' then               -- asynchronous reset (active low)
      StatexDP <= Idle;
    elsif CLKxCI'event and CLKxCI = '1' then  -- rising clock edge
      StatexDP <= StatexDN;
    end if;
  end process p_update_state_mem_test;


  -- purpose: calculate next FSM state
  p_calculate_state_memless : process (AtoHnewxD, AtoHxDP, ExpMessxDP, HInxDI,
                                       InWrEnxSI, KKCounterxDP, MessageInxDI,
                                       MessageReadyxSI, StatexDP, WKKnewxD)
  begin  -- process p_calculate_state_memless

    -- default values
    ExpMessxDN     <= ExpMessxDP;
    StatexDN       <= StatexDP;
    KKCounterxDN   <= KKCounterxDP;
    WKK15xD        <= (others => '0');
    WKK2xD         <= (others => '0');
    WKK16xD        <= (others => '0');
    WKK7xD         <= (others => '0');
    WKKmainxD      <= (others => '0');
    KKKmainxD      <= (others => '0');
    AtoHxDN        <= AtoHxDP;
    AtoHmainxD     <= AtoHxDP;
    VALIDOUTxSO    <= '0';
    PenUltCyclexSO <= '0';

    --
    MessageReceivedxSO <= '0';

    case StatexDP is
      when Idle =>

        if InWrEnxSI = '1' then
          ExpMessxDN <= MessageInxDI;
        end if;



        -- we are waiting for the message to come
        MessageReceivedxSO <= '0';

        -- if input message is ready, go to Read
        -- else, wait in Idle mode
        if MessageReadyxSI = '1' then
          StatexDN <= Read;
        else
          StatexDN <= Idle;
        end if;
        
      when Read =>

        -- we are reading the message (i.e. not yet received)
        MessageReceivedxSO <= '0';

        -- read in the message from MessageInxDI into the FF
        -- reset the KK counter
        -- go into hash state


--        ExpMessxDN   MessageInxDI;


        KKCounterxDN <= (others => '0');
        StatexDN     <= Hash;

        -- read in the start values
        AtoHxDN <= HInxDI;

      when Hash =>

        -- the input message was received
        MessageReceivedxSO <= '1';

        -- for the first 16 words, we don't need the expansion and do
        -- only HashMain
        -- for the 16th word, we already need to start with the expansion,
        -- because the expanded word will be needed in the next increment
        if KKCounterxDP < 15 then

          -- no expansion: ExpMessage remains constant
          ExpMessxDN <= ExpMessxDP;

          -- from 16 to 64 we need to expand the next message
        else

          -- bring WKK15, WKK2, WKK16, WKK7 to MessageExpansion and store
          -- the output of the message expansion into the FF
          -- The FF has only 16 words, we can wrap-around it and overwrite the
          -- old words (they're unused)

          -- do the wrap-around with the mod 16 calculation
          WKK15xD <= ExpMessxDP((to_integer(unsigned(KKCounterxDP))-15+1) mod 16);
          WKK2xD  <= ExpMessxDP((to_integer(unsigned(KKCounterxDP))-2+1) mod 16);
          WKK16xD <= ExpMessxDP((to_integer(unsigned(KKCounterxDP))-16+1) mod 16);
          WKK7xD  <= ExpMessxDP((to_integer(unsigned(KKCounterxDP))-7+1) mod 16);
          --WKKnewTempxDN WKKnewxD;    -- in round kk, store the expanded
          -- message word, in kk+1 it will go to
          -- the expanded message, so that it is
          -- valid in round kk+2

          --ExpMessxDN((to_integer(unsigned(KKCounterxDP))+1) mod 16) WKKnewTempxDP;
          ExpMessxDN((to_integer(unsigned(KKCounterxDP))+1) mod 16) <= WKKnewxD;


        end if;


        -- in all cases, we do the MainLoop
        WKKmainxD  <= ExpMessxDP(to_integer(unsigned(KKCounterxDP)) mod 16);
        KKKmainxD  <= K_INITIAL(to_integer(unsigned(KKCounterxDP)));
        -- in the first round, we read AtoH from the inputs HInxDI
        -- all following rounds, we need to continue with the previously
        -- calculated values
--        if KKCounterxDP = 0 then -- init HInx when reading the message
--          AtoHmainxD HInxDI;
--        else
--          AtoHmainxD AtoHxDP;
--        end if;
        AtoHmainxD <= AtoHxDP;


        -- move the new A..H values to StoreAtoH
        AtoHxDN <= AtoHnewxD;

        -- after doing the main loop, we go back to Hash for the first 63 times
        -- when the last one is done, we go to Output


        if KKCounterxDP = 63 then
          StatexDN <= Output;
        else
          StatexDN <= Hash;
        end if;

        -- increase the KK counter
        KKCounterxDN <= KKCounterxDP + 1;

        
        
      when Output =>
        PenUltCyclexSO <= '1';
        -- calculate the actual output
        -- A..H and Harr are connected to UpdateH and get then to output pins
        if MessageReadyxSI = '1' then
          StatexDN <= Read;
        else
          StatexDN <= Idle;
        end if;
        VALIDOUTxSO <= '1';
        
        
      when others => null;
    end case;
  end process p_calculate_state_memless;
  
  
end behave;

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