------------------------------------------------------------
-- Copyright: 2010 Integrated Sytems Laboratory, ETH Zurich
-- http://www.iis.ee.ethz.ch/~sha3
------------------------------------------------------------
library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
use work.shavitepkg.all;
entity shavite is
port (
ClkxCI : in std_logic;
RstxRBI : in std_logic;
InputEnxEI : in std_logic;
OutputEnxEO : out std_logic;
DxDI : in std_logic_vector(511 downto 0);
HashxDO : out std_logic_vector(255 downto 0));
end shavite;
architecture rtl of shavite is
component c256
port (
ClkxCI : in std_logic;
RstxRBI : in std_logic;
DataBlkxDI : in wordmat512;
BitCntxDI : in wordmat64;
InputEnxEI : in std_logic;
LxDI : in wordmat128;
RxDI : in wordmat128;
LxDO : out wordmat128;
RxDO : out wordmat128);
end component;
signal ConvertedInxD : wordmat512; -- Input in matrix format
signal BitCntxDN, BitCntxDP, BitCntIncxD : wordmat64; -- Bit counter
signal LxDP, LxDN, RxDP, RxDN : wordmat128; -- State of SHAvite
-- (changing once per
-- data block)
signal LResxD, RResxD : wordmat128; -- Output of C256
-- signal OutLxD, OutRxD : wordmat128; -- Hash output, but
-- in matrix format
signal StatexDN, StatexDP : unsigned(5 downto 0);
begin -- rtl
u_c256 : c256
port map (
ClkxCI => ClkxCI,
RstxRBI => RstxRBI,
DataBlkxDI => ConvertedInxD,
BitCntxDI => BitCntxDP,
InputEnxEI => InputEnxEI,
LxDI => LxDP,
RxDI => RxDP,
LxDO => LResxD,
RxDO => RResxD);
-- purpose: Calculates the auxiliary signal BitCntInxcD used to increment the
-- bit counter in the FSM
-- type : combinational
-- inputs : BitCntxDP
-- outputs: BitCntIncxD
p_bitcnt : process (BitCntxDP)
begin -- process p_bitcnt
if BitCntxDP(0) = X"FFFFFE00" then
BitCntIncxD(0) <= (others => '0');
BitCntIncxD(1) <= std_logic_vector(unsigned(BitCntxDP(1))+1);
else
BitCntIncxD(0) <= std_logic_vector(unsigned(BitCntxDP(0))+512);
BitCntIncxD(1) <= BitCntxDP(1);
end if;
end process p_bitcnt;
-- purpose: Controls the data flow
-- type : combinational
-- inputs : InputEnxEI, StatexDP, LxDP, RxDP, LResxD, RResxD, BitCntxDP, BitCntIncxD
-- outputs: StatexDN, LxDN, RxDN, OutputEnxEO, BitCntxDN, --OutLxD, OutRxD
p_fsm : process (BitCntIncxD, BitCntxDP, InputEnxEI, LResxD, LxDP, RResxD,
RxDP, StatexDP)
begin -- process p_fsm
LxDN <= LxDP;
RxDN <= RxDP;
BitCntxDN <= BitCntxDP;
OutputEnxEO <= '0';
StatexDN <= StatexDP+1;
-- OutLxD others => (others => '0'));
-- OutRxD others => (others => '0'));
case to_integer(StatexDP) is
when 0 =>
if InputEnxEI = '0' then -- idle: stay in state 0 / output the hash if necessary
StatexDN <= StatexDP;
LxDN <= IVLEFT;
RxDN <= IVRIGHT;
BitCntxDN <= IVBITCNT;
if BitCntxDP /= IVBITCNT then --processed at least one message block
-- => output the hash value
OutputEnxEO <= '1';
end if;
end if;
when 35 => -- return hash value (if finished) / do feedforward
for i in 3 downto 0 loop
-- OutLxD(i) LxDP(i) xor LResxD(i);
-- OutRxD(i) RxDP(i) xor RResxD(i);
LxDN(i) <= LxDP(i) xor LResxD(i);
RxDN(i) <= RxDP(i) xor RResxD(i);
end loop;
BitCntxDN <= BitCntIncxD;
StatexDN <= (others => '0');
when others => null;
end case;
end process p_fsm;
-- Memory
-----------------------------------------------------------------------------
p_mem : process (ClkxCI, RstxRBI)
begin -- process p_mem
if RstxRBI = '0' then -- asynchronous reset (active low)
StatexDP <= (others => '0');
BitCntxDP <= IVBITCNT;--(others => (others => '0'));
LxDP <= (others => (others => '0'));
RxDP <= (others => (others => '0'));
elsif ClkxCI'event and ClkxCI = '1' then -- rising clock edge
StatexDP <= StatexDN;
BitCntxDP <= BitCntxDN;
LxDP <= LxDN;
RxDP <= RxDN;
end if;
end process p_mem;
-- INPUT CONVERSION
-- the order of the bytes is reversed
input : for i in 15 downto 0 generate
input2 : for j in 3 downto 0 generate
-- the bits remain in normal order
input3 : for k in 7 downto 0 generate
ConvertedInxD(i)(j*8+k) <= DxDI(480-i*32+24-j*8+k);
end generate input3;
end generate input2;
end generate input;
-- OUTPUT CONVERSION
-- Return the hash in reversed order of words
output : for i in 3 downto 0 generate
i*32) <= RxDP(i); --OutRxD(i);
i*32+128) <= LxDP(i); --OutLxD(i);
end generate output;
end rtl;