------------------------------------------------------------
-- Copyright: 2011 Integrated Sytems Laboratory, ETH Zurich
-- http://www.iis.ee.ethz.ch/~sha3
------------------------------------------------------------
-------------------------------------------------------------------------------
-- Title : SHA2 taken from sem10h7
-- Project : Shabziger
-------------------------------------------------------------------------------
-- File : ethz_sha2.vhd
-- Author : Köppel Benedikt;Schnydrig Mathias
-- Company : Integrated Systems Laboratory, ETH Zurich
-- Created : 2011-01-13
-- Last update: 2011-09-10
-- Platform : ModelSim (simulation), Synopsys (synthesis)
-- Standard : VHDL'87
-------------------------------------------------------------------------------
-- Description: Top module around SHA256 to provide a clean interface to the
-- outside world
-------------------------------------------------------------------------------
-- Copyright (c) 2011 Integrated Systems Laboratory, ETH Zurich
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2011-01-13 1.0 sem10h7 Created
-- 2011-08-25 1.1 kgf Changed entity name
-- 2011-09-10 1.2 kgf Changed the Reset name frm RSTxRBI to RstxRBI
-- our compile script depends on this name.
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.shapkg.all;
entity ethz_sha2 is
port (
ClkxCI : in std_logic;
RstxRBI : in std_logic;
FinBlockxSI : in std_logic;
InWrEnxSI : in std_logic;
PenUltCyclexSO : out std_logic;
-- ReadyxSO : out std_logic; -- is 1, when we are ready for a next message
OutWrEnxSO : out std_logic;
TextInxDI : in std_logic_vector(511 downto 0); -- the message to encrypt, including all padding and stuff
HOutxDO : out std_logic_vector(255 downto 0); -- the Hash output, if TextIn was the last message, or intermediary H values if not the last message
ScanInxTI : in std_logic;
ScanEnxTI : in std_logic;
ScanOutxTO : out std_logic
);
end ethz_sha2;
architecture behavioral of ethz_sha2 is
component SHA256Main
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;
PenUltCyclexSO : out std_logic;
MessageReceivedxSO : out std_logic);
end component;
type state is (Idle, First, Waiting, Running);
-- statemachine
signal StatexDP : state;
signal StatexDN : state;
-- pipelining the inputs
-- signal TextInxDP : std_logic_vector(511 downto 0);
-- signal TextInxDN : std_logic_vector(511 downto 0);
signal HxDP : std_logic_vector(255 downto 0);
signal HxDN : std_logic_vector(255 downto 0);
-- pipelining the outputs
-- signal HOutxDP : std_logic_vector(255 downto 0);
-- signal HOutxDN : std_logic_vector(255 downto 0);
-- connect to SHA256Main
signal MessageInxD : expmess_arr;
signal HInxD : h_arr;
signal HOutxD : h_arr;
signal VALIDOUTxS : std_logic;
signal MessageReadyxS : std_logic;
signal MessageReceivedxS : std_logic;
signal FinBlockxSN, FinBlockxSP : std_logic;
signal OutWrEnxSN, OutWrEnxSP : std_logic;
signal FirstBlockxS : std_logic;
signal PenUltCyclexS : std_logic;
signal ReadyxS : std_logic;
begin -- behavioral
SHA256Main_1 : SHA256Main
port map (
MessageInxDI => MessageInxD,
InWrEnxSI => InWrEnxSI,
HInxDI => HInxD,
CLKxCI => CLKxCI,
RSTxRBI => RstxRBI,
VALIDOUTxSO => VALIDOUTxS,
HOutxDO => HOutxD,
MessageReadyxSI => MessageReadyxS,
PenUltCyclexSO => PenUltCyclexS,
MessageReceivedxSO => MessageReceivedxS);
-- wire pipelined inputs
-- MessageInxD TextInxDP(511 downto 480), TextInxDP(479 downto 448), TextInxDP(447 downto 416), TextInxDP(415 downto 384), TextInxDP(383 downto 352), TextInxDP(351 downto 320), TextInxDP(319 downto 288), TextInxDP(287 downto 256), TextInxDP(255 downto 224), TextInxDP(223 downto 192), TextInxDP(191 downto 160), TextInxDP(159 downto 128), TextInxDP(127 downto 96), TextInxDP(95 downto 64), TextInxDP(63 downto 32), TextInxDP(31 downto 0));
HInxD <= (HxDP(255 downto 224), HxDP(223 downto 192), HxDP(191 downto 160), HxDP(159 downto 128), HxDP(127 downto 96), HxDP(95 downto 64), HxDP(63 downto 32), HxDP(31 downto 0));
MessageInxD <= (TextInxDI(511 downto 480), TextInxDI(479 downto 448), TextInxDI(447 downto 416), TextInxDI(415 downto 384), TextInxDI(383 downto 352), TextInxDI(351 downto 320), TextInxDI(319 downto 288), TextInxDI(287 downto 256), TextInxDI(255 downto 224), TextInxDI(223 downto 192), TextInxDI(191 downto 160), TextInxDI(159 downto 128), TextInxDI(127 downto 96), TextInxDI(95 downto 64), TextInxDI(63 downto 32), TextInxDI(31 downto 0));
p_calculate_next_state : process (FinBlockxSP, InWrEnxSI, OutWrEnxSP,
PenUltCyclexS, StatexDP, VALIDOUTxS)
begin -- process p_calculate_next_state
MessageReadyxS <= '0';
ReadyxS <= '0';
OutWrEnxSN <= (VALIDOUTxS and FinBlockxSP);
OutWrEnxSO <= OutWrEnxSP;
FirstBlockxS <= '0';
-- PenUltCyclexSO PenUltCyclexS xor ReadyxS;
PenUltCyclexSO <= PenUltCyclexS;
case StatexDP is
when Idle =>
-- we remain idle until someone tells us to start
FirstBlockxS <= '1';
ReadyxS <= '1';
if InWrEnxSI = '1' then
StatexDN <= First;
MessageReadyxS <= '1';
else
StatexDN <= Idle;
end if;
when First =>
FirstBlockxS <= '0';
if VALIDOUTxS = '1' then
if FinBlockxSP = '1' then
if InWrEnxSI = '1' then
StatexDN <= First;
MessageReadyxS <= '1';
FirstBlockxS <= '1';
else
StatexDN <= Idle;
end if;
else
if InWrEnxSI = '1' then
StatexDN <= Running;
MessageReadyxS <= '1';
else
StatexDN <= Waiting;
end if;
end if;
ReadyxS <= '1';
else
StatexDN <= First;
end if;
when Waiting =>
ReadyxS <= '1';
if InWrEnxSI = '1' then
StatexDN <= Running;
MessageReadyxS <= '1';
else
StatexDN <= Waiting;
end if;
when Running =>
-- output is valid when it says so
if VALIDOUTxS = '1' then
if FinBlockxSP = '1' then
if InWrEnxSI = '1' then
StatexDN <= First;
MessageReadyxS <= '1';
FirstBlockxS <= '1';
else
StatexDN <= Idle;
end if;
else
if InWrEnxSI = '1' then
StatexDN <= Running;
MessageReadyxS <= '1';
else
StatexDN <= Waiting;
end if;
end if;
ReadyxS <= '1';
else
StatexDN <= Running;
end if;
when others => null;
end case;
end process p_calculate_next_state;
p_calculate_next_inputs : process (FinBlockxSI, FinBlockxSP, FirstBlockxS,
HOutxD, HxDP, InWrEnxSI, VALIDOUTxS)
begin -- process p_calculate_next_inputs
-- if (StatexDP = Idle or StatexDP = Waiting) and InWrEnxSI = '1' then
HxDN <= HxDP;
if FirstBlockxS = '1' then
if InWrEnxSI = '1' then
HxDN <= SHA_IV;
end if;
else
if VALIDOUTxS = '1' then
HxDN <= (HOutxD(0) & HOutxD(1) & HOutxD(2) & HOutxD(3) & HOutxD(4) & HOutxD(5) & HOutxD(6) & HOutxD(7));
end if;
end if;
if InWrEnxSI = '1' then
-- we are ready for new stuff, and are adviced to start now
-- TextInxDN TextInxDI;
FinBlockxSN <= FinBlockxSI;
-- if FirstBlockxS = '1' then
-- HInxDN <= SHA_IV;
-- else
---- HInxDN HOutxDP;
-- HInxDN HOutxD(0) & HOutxD(1) & HOutxD(2) & HOutxD(3) & HOutxD(4) & HOutxD(5) & HOutxD(6) & HOutxD(7));
-- end if;
else
-- not ready, or no new inputs: just leave it as it is
-- TextInxDN TextInxDP;
-- HInxDN HInxDP;
FinBlockxSN <= FinBlockxSP;
end if;
end process p_calculate_next_inputs;
p_update_inputs : process (CLKxCI, RstxRBI)
begin -- process p_update_inputs
if RstxRBI = '0' then -- asynchronous reset (active low)
-- TextInxDP others => '0');
HxDP <= (others => '0');
FinBlockxSP <= '0';
OutWrEnxSP <= '0';
elsif CLKxCI'event and CLKxCI = '1' then -- rising clock edge
-- TextInxDP TextInxDN;
HxDP <= HxDN;
FinBlockxSP <= FinBlockxSN;
OutWrEnxSP <= OutWrEnxSN;
end if;
end process p_update_inputs;
-- p_calculate_next_outputs : process (HOutxD, HOutxDP, VALIDOUTxS)
-- begin -- process p_calculate_next_outputs
---- HOutxDO HOutxDP;
---- if VALIDOUTxS = '1' then
---- -- if SHA gives a valid output, the output can go to the outside world
---- HOutxDN HOutxD(0) & HOutxD(1) & HOutxD(2) & HOutxD(3) & HOutxD(4) & HOutxD(5) & HOutxD(6) & HOutxD(7));
---- else
---- -- else, keep thelast previous valid value
---- HOutxDN HOutxDP;
-- end if;
-- end process p_calculate_next_outputs;
-- p_update_outputs : process (CLKxCI, RSTxRBI)
-- begin -- process p_update_outputs
-- if RSTxRBI = '0' then -- asynchronous reset (active low)
-- HOutxDP others => '0');
-- elsif CLKxCI'event and CLKxCI = '1' then -- rising clock edge
-- HOutxDP HOutxDN;
-- end if;
-- end process p_update_outputs;
p_update_state : process (CLKxCI, RstxRBI)
begin -- process p_update_state
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;
HOutxDO <= HxDP;
end behavioral;