------------------------------------------------------------
-- 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 c256 is
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 c256;
architecture rtl of c256 is
component expansion
port (
ClkxCI : in std_logic;
RstxRBI : in std_logic;
InputEnxEI : in std_logic;
DataBlkxDI : in wordmat512;
BitCntxDI : in wordmat64;
SubKeyxDO : out wordmat128);
end component;
component f3
port (
ClkxCI : in std_logic;
RstxRBI : in std_logic;
InputEnxEI : in std_logic;
DataxDI : in wordmat128;
SubKeyxDI : in wordmat128;
OutxDO : out wordmat128);
end component;
signal SubKeyxD : wordmat128;
signal F3inxD, F3outxD : wordmat128;
signal LxDP, LxDN, RxDP, RxDN : wordmat128;
signal RoundxDN, RoundxDP : unsigned(5 downto 0);
begin -- rtl
u_expansion : expansion
port map (
ClkxCI => ClkxCI,
RstxRBI => RstxRBI,
InputEnxEI => InputEnxEI,
DataBlkxDI => DataBlkxDI,
BitCntxDI => BitCntxDI,
SubKeyxDO => SubKeyxD);
u_f3 : f3
port map (
ClkxCI => ClkxCI,
RstxRBI => RstxRBI,
InputEnxEI => InputEnxEI,
DataxDI => F3inxD,
SubKeyxDI => SubKeyxD,
OutxDO => F3outxD);
LxDO <= LxDN;
RxDO <= RxDN;
-- purpose: Controls the data flow to calculate 12 rounds of F3
-- type : combinational
-- inputs : LxDP, RxDP, LxDI, RxDI, F3outxD, RoundxDP, InputEnxEI
-- outputs: LxDN, RxDN, F3inxD, RoundxDN
p_fsm : process (LxDP, RxDP, LxDI, RxDI, F3outxD, RoundxDP, InputEnxEI)
begin -- process p_fsm
RoundxDN <= RoundxDP+1;
if to_integer(RoundxDP) = 35 or (InputEnxEI = '0' and to_integer(RoundxDP) = 0) then
RoundxDN <= (others => '0');
end if;
if to_integer(RoundxDP) = 0 then -- start of initial F3 round
F3inxD <= RxDI;
LxDN <= LxDI;
RxDN <= RxDI;
elsif to_integer(RoundxDP) mod 3 = 2 then -- cycles 2, 5, 8, ...: end of F3 round
for i in 3 downto 0 loop
RxDN(i) <= F3outxD(i) xor LxDP(i);
end loop; -- i
F3inxD <= RxDP;
LxDN <= RxDP;
else
-- wait
F3inxD <= RxDP; -- cycles 3, 6, 9, ...: start of F3 round
LxDN <= LxDP;
RxDN <= RxDP;
end if;
end process p_fsm;
p_mem : process (ClkxCI, RstxRBI)
begin -- process p_mem
if RstxRBI = '0' then -- asynchronous reset (active low)
LxDP <= (others => (others => '0'));
RxDP <= (others => (others => '0'));
RoundxDP <= (others => '0');
elsif ClkxCI'event and ClkxCI = '1' then -- rising clock edge
LxDP <= LxDN;
RxDP <= RxDN;
RoundxDP <= RoundxDN;
end if;
end process p_mem;
end rtl;