------------------------------------------------------------
-- 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;

Generated on Fri Sep 24 10:39:12 CEST 2010
Home