------------------------------------------------------------
-- Copyright: 2011 George Mason University, Virginia USA
-- http://www.iis.ee.ethz.ch/~sha3
------------------------------------------------------------
-- =====================================================================
-- Copyright © 2010-2011 by Cryptographic Engineering Research Group (CERG),
-- ECE Department, George Mason University
-- Fairfax, VA, U.S.A.
-- =====================================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
use work.sha3_pkg.all;
use work.keccak_pkg.all;
-- Possible generics values:
-- hs = {HASH_SIZE_256, HASH_SIZE_512}
-- b = {KECCAK256_CAPACITY, KECCAK512_CAPACITY}
-- possible combinaations of (hs, b) = {(HASH_SIZE_256, KECCAK256_CAPACITY), (HASH_SIZE_512, KECCAK512_CAPACITY)}
entity gmu_keccak_datapath is
generic (b : integer := KECCAK256_CAPACITY; hs: integer := HASH_SIZE_256);
port (
clk :in std_logic;
rst :in std_logic;
din :in std_logic_vector(b-1 downto 0);
dout :out std_logic_vector(hs-1 downto 0);
-- process
sel_xor :in std_logic;
sel_final :in std_logic;
wr_state :in std_logic;
rd_ctr :in std_logic_vector(4 downto 0)
);
end gmu_keccak_datapath;
architecture struct of gmu_keccak_datapath is
signal from_din :std_logic_vector(b-1 downto 0);
signal from_concat, to_xor, from_round, from_xor, to_register, to_round : std_logic_vector(KECCAK_STATE-1 downto 0);
signal rc : std_logic_vector(w-1 downto 0);
constant zeros: std_logic_vector (KECCAK_STATE-1-b downto 0) := (others => '0');
constant state_zero : std_logic_vector (KECCAK_STATE-1 downto 0):=(others => '0');
type res_type is array (0 to hs/64-1) of std_logic_vector(w-1 downto 0);
signal se_result : res_type;
type din_array is array (0 to b/64-1) of std_logic_vector(31 downto 0);
signal din_a, din_b : din_array;
-- kgf - 2011-09-28 - old school
component keccak_round
port (
rin : in std_logic_vector(KECCAK_STATE-1 downto 0);
rc : in std_logic_vector(63 downto 0);
rout : out std_logic_vector(KECCAK_STATE-1 downto 0));
end component;
-- debugging signals
-- signal aa, bb, cc : state_table;
begin
-- aa <= str2table( to_round );
-- bb <= str2table( from_round );
-- cc <= str2table( from_concat );
-- serial input parallel output
-- din_a downto 0);
-- din_b downto 32);
-- swap_din <= switch_endian_byte(din_a,32,32) & switch_endian_byte(din_b,32,32);
swapGen: for i in b/64-1 downto 0 generate
din_a(i) <= din(i*64+31 downto i*64);
din_b(i) <= din(i*64+63 downto i*64+32);
from_din(i*64+63 downto i*64) <= switch_endian_byte(din_a(i),32,32) & switch_endian_byte(din_b(i),32,32);
end generate;
from_concat <= from_din & zeros;
to_xor <= state_zero when sel_xor='1' else from_round;
from_xor <= from_concat xor to_xor;
to_register <= from_xor when sel_final='1' else from_round;
-- register for intermediate values
stateRegInst : regna
generic map (N => KECCAK_STATE, init=>state_zero)
port map ( clk =>clk, rst=>rst, en =>wr_state, input=>to_register, output=>to_round);
-- asynchronous memory for Keccak constants
rd_cons : entity work.keccak_cons(keccak_cons) port map (addr=>rd_ctr, rc=>rc);
-- Keccak round function with architecture based on Marcin Rogawski implementation
-- rd : entity work.keccak_round(mrogawski_round)port map (rc=>rc, rin=>to_round, rout=>from_round);
-- Keccak round function with architecture based on Guido Bertoni implementation
--rd : entity work.keccak_round(gbertoni_round)port map (rc=>rc, rin=>to_round, rout=>from_round);
-- include either the rogawski or the bertoni round in the source list
i_rd: keccak_round
port map (
rin => to_round,
rc => rc,
rout => from_round);
-- piso endianess fixing function
out_gen: for i in 0 to hs/w-1 generate
se_result(i) <= to_round(KECCAK_STATE-i*w-1 downto KECCAK_STATE-(i+1)*w);
dout(hs-i*w-1 downto hs-(i+1)*w) <= switch_endian_word(x=>se_result(i), width=>w, w=>8);
end generate;
end struct;