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