--

-- ****************************************************************************
--                                                                           --
--     Copyright @ 1999                                                      --
--                                                                           --
--     Tetraedre SARL,  chenes 19,   2072 Saint-Blaise,  Switzerland         --
--                                                                           --
-- ****************************************************************************
--                                                                           --
-- Filename  : tctf64.vhd                                                    --
--                                                                           --
-- ****************************************************************************
--                                                                           --
-- WARNING: This file is the property of Tetraedre SARL, Switzerland. This   --
-- file is protected by a copyright. The reading, copying, compilation,      --
-- synthesis and other use of this file is forbidden without a written       --
-- agreement signed by Tetraedre SARL, Switzerland.                          --
--                                                                           --
-- IN NO EVENT SHALL TETRAEDRE SARL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER--
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING   --
-- FROM, OUT OF OR IN CONNECTION WITH THIS DESCRIPTION OR THE USE OF IT.     --
--                                                                           --
-- ****************************************************************************





-----------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity tctf64 is
    port (
        iv      : in  std_logic_vector(63 downto 0);
        key1    : in  std_logic_vector(63 downto 0);
        key2    : in  std_logic_vector(63 downto 0);
        key3    : in  std_logic_vector(63 downto 0);
        first   : in  std_logic;
        do_next : in  std_logic;
        crypt   : in  std_logic;
        clk     : in  std_logic;
        nreset  : in  std_logic;
        d       : in  std_logic_vector(63 downto 0);
        q       : out std_logic_vector(63 downto 0);
        done    : out std_logic
    );
end;


---------- Architecture tcfb64 ---------- 
library ieee, work;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

architecture simple of tctf64 is

    component tcdg 
    port (
         key   : in  std_logic_vector(63 downto 0);
         d     : in  std_logic_vector(63 downto 0);
         start : in  std_logic;
         crypt : in  std_logic;
         clk   : in  std_logic;
         nreset: in  std_logic;
         q     : out std_logic_vector(63 downto 0);
         done  : out std_logic
    );
    end component;


    signal des_key        : std_logic_vector(63 downto 0);
    signal des_d          : std_logic_vector(63 downto 0);
    signal des_start      : std_logic;
    signal des_crypt      : std_logic;
    signal des_q          : std_logic_vector(63 downto 0);
    signal des_done       : std_logic;
    signal next_dreg      : std_logic_vector(63 downto 0);
    signal dreg           : std_logic_vector(63 downto 0);
    signal dreg2          : std_logic_vector(63 downto 0);
    signal int_q          : std_logic_vector(63 downto 0);
    signal ivsel          : std_logic_vector(63 downto 0);
    signal next_state     : std_logic_vector( 1 downto 0);
    signal state          : std_logic_vector( 1 downto 0);
    signal ff_des_done    : std_logic;
    signal int_done       : std_logic;
    signal ff_crypt       : std_logic;
    signal next_int_done  : std_logic;

begin


    i_des : tcdg
    port map (
        key   => des_key,
        d     => des_d,
        start => des_start,
        crypt => des_crypt,
        clk   => clk,
        nreset=> nreset,
        q     => des_q,
        done  => des_done
    );

        -- -------------------------------------------------------------
    
    ivsel      <= iv    when (first='1' and do_next='1') else dreg2;
    des_d      <= ivsel when (next_state="00")           else des_q;
    next_dreg  <= d     when (do_next='1')               else dreg;
    des_key    <= key1  when (state="00")                else
                  key2  when (state="01")                else
                  key3;
    des_crypt  <= '0'   when (next_state="01")           else '1';
    dreg2      <= int_q when (ff_crypt='1')              else dreg; 
    int_q      <= des_q xor  dreg;
    q          <= int_q;
    done       <= int_done;

    -- ------------------------------------------------------------


    P3 : process(state,do_next,des_done,ff_des_done, int_done)
    begin
        if (do_next='1') then 
            next_int_done  <= '0';
        else
            if ((des_done='1') AND (ff_des_done='0')) then 
                if ((state="10") OR (state="11")) then 
                    next_int_done  <= '1';
                else
                    next_int_done  <= '0';
                end if;
            else
                next_int_done  <= int_done;
            end if;
        end if;
    end process;


    P4 : process(state,do_next,des_done,ff_des_done)
    begin
        if (do_next='1') then 
            next_state     <= "00";
            des_start      <= '1';
        else
            if ((des_done='1') AND (ff_des_done='0')) then 
                if ((state="10") OR (state="11")) then 
                    next_state     <= state;
                    des_start      <= '0';
                else
                    next_state     <= state + "1";
                    des_start      <= '1';
                end if;
            else
                next_state     <= state;
                des_start      <= '0';
            end if;
        end if;
    end process;

       
        ------------------------------------------------------------- 
        ---------------------------  REGISTERS   -------------------- 
        ------------------------------------------------------------- 
    P40 : process(clk, nreset)
    begin
        if (nreset='0') then
            dreg        <= (others => '0');
            state       <= (others => '0');
            ff_des_done <= '0';
            int_done    <= '0';
            ff_crypt    <= '0';
        else
            if (clk='1' and clk'event) then
                dreg        <= next_dreg;
                state       <= next_state;
                ff_crypt    <= crypt;
                ff_des_done <= des_done;
                int_done    <= next_int_done;
            end if;
        end if;
    end process;


end simple;


