------------------------------------------------------------
-- Copyright: 2011 Integrated Sytems Laboratory, ETH Zurich
--            http://www.iis.ee.ethz.ch/~sha3
------------------------------------------------------------
-------------------------------------------------------------------------------
-- Title      : Keccak
-- Project    : 
-------------------------------------------------------------------------------
-- File       : keccak.vhd
-- Author     : Frank K. Guerkaynak  
-- Company    : Integrated Systems Laboratory, ETH Zurich
-- Created    : 2011-08-10
-- Last update: 2011-08-24
-- Platform   : ModelSim (simulation), Synopsys (synthesis)
-- Standard   : VHDL'87
-------------------------------------------------------------------------------
-- Description: Main Keccak block original by Pietro Gendotti and Luca Henzen
-------------------------------------------------------------------------------
-- Copyright (c) 2011 Integrated Systems Laboratory, ETH Zurich
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author  Description
-- 2011-08-10  1.0      kgf	Added the PenUltCyclexSO signal that comes from
--                              the controller
-- 2011-08-19  1.1      kgf     Adapted the interface signal names
-- 2011-08-24  1.2      kgf     Added the scan signals
-------------------------------------------------------------------------------

library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
use work.keccakpkg.all;


entity ethz_keccak is
  
  port (
    ClkxCI         : in  std_logic;
    RstxRBI        : in  std_logic;
    ScanInxTI      : in  std_logic;
    ScanOutxTO     : out std_logic;
    ScanEnxTI      : in  std_logic;
    FinBlockxSI    : in  std_logic;
    InWrEnxSI      : in  std_logic;
    OutWrEnxSO     : out std_logic;
    PenUltCyclexSO : out std_logic;     -- The penultimate cycle of 
                                        -- computations
    DxDI           : in  std_logic_vector(1087 downto 0);
    DxDO           : out std_logic_vector(HWIDTH-1 downto 0));

end ethz_keccak;


architecture rtl of ethz_keccak is
  
  component keccak_controller
    port (
      ClkxCI         : in  std_logic;
      RstxRBI        : in  std_logic;
      FinBlockxSI    : in  std_logic;
      INENxEI        : in  std_logic;
      OUTENxEO       : out std_logic;
      StateSelxSO    : out std_logic;
      PenUltCyclexSO : out std_logic;
      RcntxDO        : out unsigned(4 downto 0));
  end component;

  signal ThetaInxD, ThetaOutxD, PiInxD, PiOutxD, RhoInxD, RhoOutxD, ChiInxD, ChiOutxD,
         IotaInxD , IotaOutxD, IotaOutTempxD, StateTempxD : state;
  signal CxD: sheet;
  signal DxD : sheet;
--  signal ZerosxD : std_logic_vector(63 downto 0) := (others=>'0');
  signal DInxD : state;
  signal StateSelxS : std_logic;
  signal RcntxD : unsigned(4 downto 0);
  signal StatexDP, StatexDN : state;
  signal StateInxD : state;
  
begin
  
  u_controller : keccak_controller
    port map (
      ClkxCI         => ClkxCI,
      RstxRBI        => RstxRBI,
      FinBlockxSI    => FinBlockxSI,
      INENxEI        => InWrEnxSI,
      OUTENxEO       => OutWrEnxSO,
      StateSelxSO    => StateSelxS,
      PenUltCyclexSO => PenUltCyclexSO,
      RcntxDO        => RcntxD);

  din01: for y in 0 to 2 generate
    din02: for x in 0 to 4 generate
      DInxD(x,y) <= DxDI(((3-y)*5-x+2)*64-1 downto ((3-y)*5-x+1)*64);
    end generate din02;
  end generate din01;

  DInxD(0,3) <= DxDI(127 downto 64);
  DInxD(1,3) <= DxDI(63 downto 0);
  DInxD(0,4) <= (others=>'0');
  DInxD(1,4) <= (others=>'0');

  din03: for y in 3 to 4 generate
    din04: for x in 2 to 4 generate
      DInxD(x,y) <= (others => '0');
    end generate din04;
  end generate din03;


  -- Connections
  ------------------------------------------------------------------------------- 
  ThetaInxD   <= StatexDP;
  RhoInxD     <= ThetaOutxD;
  PiInxD      <= RhoOutxD;
  ChiInxD     <= PiOutxD;
  IotaInxD    <= ChiOutxD;
 

  -- Theta
  -------------------------------------------------------------------------------
--  theta01: for x in 0 to 4 generate
--    CxD(x) ThetaInxD(x,0) xor ThetaInxD(x,1) xor ThetaInxD(x,2) xor
--              ThetaInxD(x,3) xor ThetaInxD(x,4);
--    DxD(x) CxD(x)(63-1 downto 0) & '0') xor (ZerosxD(62 downto 0) & CxD(x)(63));

--  end generate theta01;

  CxD(0) <= ThetaInxD(0,0) xor ThetaInxD(0,1) xor ThetaInxD(0,2) xor ThetaInxD(0,3) xor ThetaInxD(0,4);
  CxD(1) <= ThetaInxD(1,0) xor ThetaInxD(1,1) xor ThetaInxD(1,2) xor ThetaInxD(1,3) xor ThetaInxD(1,4);
  CxD(2) <= ThetaInxD(2,0) xor ThetaInxD(2,1) xor ThetaInxD(2,2) xor ThetaInxD(2,3) xor ThetaInxD(2,4);
  CxD(3) <= ThetaInxD(3,0) xor ThetaInxD(3,1) xor ThetaInxD(3,2) xor ThetaInxD(3,3) xor ThetaInxD(3,4);
  CxD(4) <= ThetaInxD(4,0) xor ThetaInxD(4,1) xor ThetaInxD(4,2) xor ThetaInxD(4,3) xor ThetaInxD(4,4);

  DxD(0) <= CxD(0)(63-1 downto 0) & CxD(0)(63);
  DxD(1) <= CxD(1)(63-1 downto 0) & CxD(1)(63);
  DxD(2) <= CxD(2)(63-1 downto 0) & CxD(2)(63);
  DxD(3) <= CxD(3)(63-1 downto 0) & CxD(3)(63);
  DxD(4) <= CxD(4)(63-1 downto 0) & CxD(4)(63);


--  theta02: for x in 0 to 4 generate
--    theta03: for y in 0 to 4 generate
--      ThetaOutxD(x,y) ThetaInxD(x,y) xor DxD((x+1) mod 5) xor CxD((x+4) mod 5);
		
--    end generate theta03;
--  end generate theta02;

  theta00: for y in 0 to 4 generate
      ThetaOutxD(0,y) <= ThetaInxD(0,y) xor DxD(1) xor CxD(4);
  end generate theta00;

  theta01: for y in 0 to 4 generate
      ThetaOutxD(1,y) <= ThetaInxD(1,y) xor DxD(2) xor CxD(0);
  end generate theta01;

  theta02: for y in 0 to 4 generate
      ThetaOutxD(2,y) <= ThetaInxD(2,y) xor DxD(3) xor CxD(1);
  end generate theta02;

  theta03: for y in 0 to 4 generate
      ThetaOutxD(3,y) <= ThetaInxD(3,y) xor DxD(4) xor CxD(2);
  end generate theta03;

  theta04: for y in 0 to 4 generate
      ThetaOutxD(4,y) <= ThetaInxD(4,y) xor DxD(0) xor CxD(3);
  end generate theta04;

  

  -- Rho
  -------------------------------------------------------------------------------
  -------------------------------------------------------------------------------
  RhoOutxD(0,0) <=  RhoInxD(0,0);

--  rho00: for y in 1 to 4 generate
--    RhoOutxD(0,y) RhoInxD(0,y)(63-RhoOffsets(5*y) downto 0) & ZerosxD(RhoOffsets(5*y)-1 downto 0)) xor
--                        (ZerosxD((63-RhoOffsets(5*y)) downto 0) & RhoInxD(0,y)(63 downto (63-RhoOffsets(5*y)+1)));
--  end generate rho00;

  rho00: for y in 1 to 4 generate
    RhoOutxD(0,y) <=  RhoInxD(0,y)(63-RHOOFFSETS(5*y) downto 0) & RhoInxD(0,y)(63 downto (63-RHOOFFSETS(5*y)+1));
  end generate rho00;

--  rho01: for x in 1 to 4 generate
--    rho02: for y in 0 to 4 generate
--      RhoOutxD(x,y) RhoInxD(x,y)(63-RhoOffsets(x+5*y) downto 0) & ZerosxD(RhoOffsets(x+5*y)-1 downto 0)) xor
--                        (ZerosxD((63-RhoOffsets(x+5*y)) downto 0) & RhoInxD(x,y)(63 downto (63-RhoOffsets(x+5*y)+1)));
--    end generate rho02;
--  end generate rho01;
  
  rho01: for x in 1 to 4 generate
    rho02: for y in 0 to 4 generate
      RhoOutxD(x,y) <=  RhoInxD(x,y)(63-RHOOFFSETS(x+5*y) downto 0) & RhoInxD(x,y)(63 downto (63-RHOOFFSETS(x+5*y)+1));
    end generate rho02;
  end generate rho01;       
     

  -- Pi
  -------------------------------------------------------------------------------     
--  pi01: for x in 0 to 4 generate
--    pi02: for y in 0 to 4 generate
--      PiOutxD(y, (2*x+3*y) mod 5) PiInxD(x,y);
		
--    end generate pi02;
--  end generate pi01;

  PiOutxD(0, 0) <= PiInxD(0, 0);
  PiOutxD(1, 3) <= PiInxD(0, 1);
  PiOutxD(2, 1) <= PiInxD(0, 2);
  PiOutxD(3, 4) <= PiInxD(0, 3);
  PiOutxD(4, 2) <= PiInxD(0, 4);
  PiOutxD(0, 2) <= PiInxD(1, 0);
  PiOutxD(1, 0) <= PiInxD(1, 1);
  PiOutxD(2, 3) <= PiInxD(1, 2);
  PiOutxD(3, 1) <= PiInxD(1, 3);
  PiOutxD(4, 4) <= PiInxD(1, 4);
  PiOutxD(0, 4) <= PiInxD(2, 0);
  PiOutxD(1, 2) <= PiInxD(2, 1);
  PiOutxD(2, 0) <= PiInxD(2, 2);
  PiOutxD(3, 3) <= PiInxD(2, 3);
  PiOutxD(4, 1) <= PiInxD(2, 4);
  PiOutxD(0, 1) <= PiInxD(3, 0);
  PiOutxD(1, 4) <= PiInxD(3, 1);
  PiOutxD(2, 2) <= PiInxD(3, 2);
  PiOutxD(3, 0) <= PiInxD(3, 3);
  PiOutxD(4, 3) <= PiInxD(3, 4);
  PiOutxD(0, 3) <= PiInxD(4, 0);
  PiOutxD(1, 1) <= PiInxD(4, 1);
  PiOutxD(2, 4) <= PiInxD(4, 2);
  PiOutxD(3, 2) <= PiInxD(4, 3);
  PiOutxD(4, 0) <= PiInxD(4, 4);

  -- Chi
  -------------------------------------------------------------------------------
--  chi01: for y in 0 to 4 generate
--    chi02: for x in 0 to 4 generate
--      ChiOutxD(x,y) ChiInxD(x,y) xor (not(ChiInxD((x+1)mod 5,y)) and ChiInxD((x+2)mod 5,y));
					
--    end generate chi02;
--  end generate chi01;

  chi00: for y in 0 to 4 generate
    ChiOutxD(0,y) <= ChiInxD(0,y) xor (not(ChiInxD(1,y)) and ChiInxD(2,y));
  end generate chi00;

  chi01: for y in 0 to 4 generate
    ChiOutxD(1,y) <= ChiInxD(1,y) xor (not(ChiInxD(2,y)) and ChiInxD(3,y));
  end generate chi01;

  chi02: for y in 0 to 4 generate
    ChiOutxD(2,y) <= ChiInxD(2,y) xor (not(ChiInxD(3,y)) and ChiInxD(4,y));
  end generate chi02;

  chi03: for y in 0 to 4 generate
    ChiOutxD(3,y) <= ChiInxD(3,y) xor (not(ChiInxD(4,y)) and ChiInxD(0,y));
  end generate chi03;

  chi04: for y in 0 to 4 generate
    ChiOutxD(4,y) <= ChiInxD(4,y) xor (not(ChiInxD(0,y)) and ChiInxD(1,y));
  end generate chi04; 

        
  -- Iota
  -------------------------------------------------------------------------------     
  iota01: for x in 1 to 4 generate
    iota02: for y in 0 to 4 generate
      IotaOutTempxD(x,y) <=  IotaInxD(x,y);
    end generate iota02;
  end generate iota01;
  
  IotaOutTempxD(0,0) <= IotaInxD(0,0) xor ROUNDCONSTANCES(to_integer(RcntxD));
  
  iota03: for y in 1 to 4 generate
      IotaOutTempxD(0,y) <=  IotaInxD(0,y);
  end generate iota03;

  -- Reverse after Iota
  -----------------------------------------------------------------------------
  rev01: for x in 0 to 4 generate
    rev02: for y in 0 to 4 generate
      rev03: for i in 0 to 7 generate
        IotaOutxD(x,y)(8*(i+1)-1 downto 8*i) <= IotaOutTempxD(x,y)(8*(8-i)-1 downto 8*(8-i-1));
      end generate rev03;
    end generate rev02;
  end generate rev01;

  
  -- State select
  -----------------------------------------------------------------------------
  StateInxD <= (others => (others => (others => '0'))) when StateSelxS = '0' else IotaOutxD;

    
  -- New State Input
  -------------------------------------------------------------------------------
  statedn: process (DInxD, InWrEnxSI, StateInxD)
  begin
    for x in 0 to 4 loop
      for y in 0 to 4 loop
        if InWrEnxSI = '1' then
           StateTempxD(x,y) <= StateInxD(x,y) xor DInxD(x,y);
        else
          StateTempxD(x,y) <= StateInxD(x,y);
        end if;
--        for i in 0 to 7 loop
--           StatexDN(x,y)(8*(i+1)-1 downto 8*i) StateTempxD(x,y)(8*(8-i)-1 downto 8*(8-i-1));
--        end loop;  -- i
      end loop;  -- y
    end loop;  -- x
  end process statedn;
  
  statedn01: for x in 0 to 4 generate
    statedn02: for y in 0 to 4 generate
      statednrev01: for i in 0 to 7 generate
        StatexDN(x,y)(8*(i+1)-1 downto 8*i) <= StateTempxD(x,y)(8*(8-i)-1 downto 8*(8-i-1));
      end generate statednrev01; 
    end generate statedn02;
  end generate statedn01;
         

  -- Output Unform
  -----------------------------------------------------------------------------
  dout: for i in 0 to 3 generate
    DxDO(HWIDTH-(i*64)-1 downto HWIDTH-(i+1)*64) <= IotaOutxD(i,0);
  
  end generate dout;
 

  -- Memory
  -----------------------------------------------------------------------------
  p_mem: process (ClkxCI, RstxRBI)
  begin  -- process p_mem
    if RstxRBI = '0' then               -- asynchronous reset (active low)
      StatexDP <= (others => (others => (others => '0')));
            
    elsif ClkxCI'event and ClkxCI = '1' then  -- rising clock edge
      StatexDP <= StatexDN;
          
    end if;
  end process p_mem;
 
end rtl;

Generated on Tue Nov 22 15:16:34 CET 2011
Home