⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aes.vhd

📁 VHDL实现128bitAES加密算法 LOW AREA节约成本的实现 DATA FLOW为8bits
💻 VHD
字号:
-------------------------------------------------------------------------------
-- Title      : A compact 8bit AES encryption core
-------------------------------------------------------------------------------
-- File       : aes.vhd
-- Author     : Timo Alho  <timo.a.alho@tut.fi>
-- Date       : 27.2.2006
-------------------------------------------------------------------------------
-- Description: The top level and main control logic.
-------------------------------------------------------------------------------
-- Disclaimer: The AES encryption core provided here is distributed AS
-- IS without any warranty of any kind either expressed or implied,
-- including, without limitation, warranties of merchantability,
-- fitness for a particular purpose or non infringement of
-- intellectual property rights.
-------------------------------------------------------------------------------

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

entity aes is
  
  port (
    clk   : in std_logic;
    rst_n : in std_logic;

    data_in  : in  std_logic_vector(7 downto 0);
    data_out : out std_logic_vector(7 downto 0);
    key_in   : in  std_logic_vector(7 downto 0);

    load_in    : in  std_logic;
    unload_in  : in  std_logic;
    start_in   : in  std_logic;
    inverse_in : in  std_logic;
    busy_out   : out std_logic);

end entity aes;

architecture rtl of aes is
  
  component subbytes is
    generic (
      pipeline_length_g : integer);
    port (
      clk        : in  std_logic;
      inverse_in : in  std_logic;
      data_in    : in  std_logic_vector (7 downto 0);
      data_out   : out std_logic_vector (7 downto 0));
  end component subbytes;

  component fwd_subbytes is
    generic (
      pipeline_length_g : integer);
    port (
      clk      : in  std_logic;
      data_in  : in  std_logic_vector (7 downto 0);
      data_out : out std_logic_vector (7 downto 0));
  end component fwd_subbytes;

  component bytepermutation is
    port (
      clk        : in  std_logic;
      data_in    : in  std_logic_vector (7 downto 0);
      data_out   : out std_logic_vector (7 downto 0);
      inverse_in : in  std_logic;
      seq_in     : in  std_logic_vector(3 downto 0);
      shift_in   : in  std_logic;
      load_in    : in  std_logic);
  end component bytepermutation;

  component keyexpansion is
    port (
      clk               : in  std_logic;
      key_in            : in  std_logic_vector (7 downto 0);
      key_out           : out std_logic_vector (7 downto 0);
      key_d4_out        : out std_logic_vector (7 downto 0);
      data_to_sbox_out  : out std_logic_vector (7 downto 0);
      data_from_sbox_in : in  std_logic_vector (7 downto 0);
      load_in           : in  std_logic;
      shift_in          : in  std_logic;
      inverse_in        : in  std_logic;
      seq_in            : in  std_logic_vector(3 downto 0);
      round_in          : in  std_logic_vector (3 downto 0));
  end component keyexpansion;

  component mixcolumns is
    port (
      clk        : in  std_logic;
      start_in   : in  std_logic;
      inverse_in : in  std_logic;
      data_in    : in  std_logic_vector (7 downto 0);
      data0_out  : out std_logic_vector (7 downto 0);
      data1_out  : out std_logic_vector (7 downto 0);
      data2_out  : out std_logic_vector (7 downto 0);
      data3_out  : out std_logic_vector (7 downto 0));
  end component mixcolumns;

  component par2ser is
    port (
      clk               : in  std_logic;
      load_par_in       : in  std_logic;
      load_ser_in       : in  std_logic;
      shift_in          : in  std_logic;
      data_serial_in    : in  std_logic_vector(7 downto 0);
      data_serial_out   : out std_logic_vector(7 downto 0);
      data_parallel0_in : in  std_logic_vector(7 downto 0);
      data_parallel1_in : in  std_logic_vector(7 downto 0);
      data_parallel2_in : in  std_logic_vector(7 downto 0);
      data_parallel3_in : in  std_logic_vector(7 downto 0));
  end component par2ser;

  signal data_ser_to_p2s   : std_logic_vector(7 downto 0);
  signal data_sbox2_to_keu : std_logic_vector(7 downto 0);
  signal data_to_mixc      : std_logic_vector(7 downto 0);
  signal data_to_bpu       : std_logic_vector(7 downto 0);

  signal data_from_sbox1 : std_logic_vector(7 downto 0);

  -- mixcolumns unit control signal
  signal start_mixc        : std_logic;
  -- output signals from mixcolumns unit
  signal data0_mixc_to_p2s : std_logic_vector(7 downto 0);
  signal data1_mixc_to_p2s : std_logic_vector(7 downto 0);
  signal data2_mixc_to_p2s : std_logic_vector(7 downto 0);
  signal data3_mixc_to_p2s : std_logic_vector(7 downto 0);

  -- byte permutation unit control signals
  signal shift_bpu         : std_logic;
  signal load_bpu          : std_logic;
  -- output signals from byte permutation unit
  signal data_bpu_to_sbox1 : std_logic_vector(7 downto 0);

  -- key expansion unit control signals
  signal load_keu, shift_keu : std_logic;
  -- output signals from key expansion unit
  signal key_from_keu        : std_logic_vector(7 downto 0);
  signal key_d4_from_keu     : std_logic_vector(7 downto 0);
  signal data_keu_to_sbox2   : std_logic_vector(7 downto 0);

  -- parallel to serial unit control signals
  signal load_par_p2s      : std_logic;
  signal load_ser_p2s      : std_logic;
  signal shift_p2s         : std_logic;
  -- output signals from paralle to serial unit
  signal data_ser_from_p2s : std_logic_vector(7 downto 0);


  signal round_r    : unsigned(3 downto 0);
  signal round      : std_logic_vector(3 downto 0);
  signal sequence_r : unsigned(3 downto 0);
  signal sequence   : std_logic_vector(3 downto 0);

  -- main control state machine states and signals
  type   control_state_t is (load, start, active);
  signal current_state_r : control_state_t;
  signal next_state      : control_state_t;

  -- intermediate signal that combines 'load_in' & 'unload_in'
  signal ext_control : std_logic_vector(1 downto 0);

  signal final_result : std_logic_vector(7 downto 0);
  signal output_r     : std_logic_vector(7 downto 0);

begin  -- architecture rtl

  data_ser_to_p2s <= data_in;           -- external input

  -- key addition (rounds 0..9)
  data_to_bpu  <= data_ser_from_p2s xor key_d4_from_keu;
  -- key addition (last round)
  final_result <= data_from_sbox1 xor key_from_keu;

  data_to_mixc <= data_from_sbox1;
  data_out     <= output_r;

  ext_control(0) <= unload_in;
  ext_control(1) <= load_in;

  round <= std_logic_vector(round_r);

  sequence <= std_logic_vector(sequence_r);

  control_clocked : process (clk, rst_n) is
  begin  -- process control
    if (rst_n = '0') then
      current_state_r <= load;
      sequence_r      <= (others => '0');
      round_r <= (others => '0');
      
    elsif rising_edge(clk) then         -- rising clock edge
      current_state_r <= next_state;    -- state transition

      case current_state_r is
        when load =>
          if (start_in = '1' or (load_in = '1' and unload_in = '0')) then
            sequence_r <= (others => '0');
          elsif (unload_in = '1') then
            if (sequence_r /= 15) then
              sequence_r <= sequence_r + 1;
            end if;
          end if;

          round_r <= (others => '0');
          
        when start =>
          sequence_r <= to_unsigned(1, sequence_r'length);
          round_r    <= (others => '0');
          
        when others =>                  -- when active
          sequence_r <= sequence_r + 1;
          if (sequence_r = 15) then     -- sequence_r wraps around
            round_r <= round_r + 1;
          end if;
      end case;

    end if;
  end process control_clocked;

  registers : process (clk) is
  begin  -- process registers
    if rising_edge(clk) then            -- rising clock edge
      if (shift_bpu = '1') then
        --output register is loaded whenver there is activity in the unit
        output_r <= final_result;
      end if;
    end if;
  end process registers;
  
  control_comb : process (current_state_r, ext_control, round_r, sequence_r,
                          start_in) is
  begin  -- process control_comb
    busy_out <= '0';

    shift_p2s    <= '0';
    shift_keu    <= '0';
    shift_bpu    <= '0';
    load_bpu     <= '0';
    load_keu     <= '0';
    load_ser_p2s <= '0';
    start_mixc   <= '0';
    load_par_p2s <= '0';

    case current_state_r is
      when load =>
        case ext_control is
          when "00" =>
          when "01" =>                  -- unload
            shift_p2s <= '1';
            shift_keu <= '1';
            shift_bpu <= '1';
            
          when "10" =>                  -- load
            load_bpu     <= '1';
            load_keu     <= '1';
            load_ser_p2s <= '1';

          when others =>                -- load & unload
            shift_keu    <= '1';
            shift_bpu    <= '1';
            load_bpu     <= '1';
            load_keu     <= '1';
            load_ser_p2s <= '1';
        end case;

        if (start_in = '1') then
          next_state <= start;
        else
          next_state <= load;
        end if;

      when start =>
        next_state <= active;
        if (sequence_r(1 downto 0) = "00") then
          -- start mixc when seq = 0, 4, 8, 12
          start_mixc <= '1';
        else
          start_mixc <= '0';
        end if;

        load_par_p2s <= '0';            -- do not load p2s on startup

        shift_bpu <= '1';
        shift_keu <= '1';
        shift_p2s <= '1';
        busy_out  <= '1';
        
      when others =>                    -- when active =>
        if (sequence_r(1 downto 0) = "00") then
          -- start mixc when seq = 0, 4, 8, 12
          -- load p2s when seq = 0, 4, 8, 12
          start_mixc   <= '1';
          load_par_p2s <= '1';
        else
          start_mixc   <= '0';
          load_par_p2s <= '0';
        end if;


        shift_bpu <= '1';
        shift_keu <= '1';
        shift_p2s <= '1';
        busy_out  <= '1';

        if (round_r = 9 and sequence_r = 0) then
          next_state <= load;
        else
          next_state <= active;
        end if;

    end case;
  end process control_comb;


  sbox1 : fwd_subbytes
    generic map (
      pipeline_length_g => 0)
    port map (
      clk      => clk,
      data_in  => data_bpu_to_sbox1,
      data_out => data_from_sbox1);

  sbox2 : fwd_subbytes
    generic map (
      pipeline_length_g => 0)
    port map (
      clk      => clk,
      data_in  => data_keu_to_sbox2,
      data_out => data_sbox2_to_keu);

  bpu : bytepermutation
    port map (
      clk        => clk,
      data_in    => data_to_bpu,
      data_out   => data_bpu_to_sbox1,
      inverse_in => inverse_in,
      seq_in     => sequence,
      shift_in   => shift_bpu,
      load_in    => load_bpu);

  keu : keyexpansion
    port map (
      clk               => clk,
      key_in            => key_in,      -- external input
      key_out           => key_from_keu,
      key_d4_out        => key_d4_from_keu,
      data_to_sbox_out  => data_keu_to_sbox2,
      data_from_sbox_in => data_sbox2_to_keu,
      load_in           => load_keu,
      shift_in          => shift_keu,
      inverse_in        => inverse_in,
      seq_in            => sequence,
      round_in          => round);

  mixc : mixcolumns
    port map (
      clk        => clk,
      start_in   => start_mixc,
      inverse_in => inverse_in,
      data_in    => data_to_mixc,
      data0_out  => data0_mixc_to_p2s,
      data1_out  => data1_mixc_to_p2s,
      data2_out  => data2_mixc_to_p2s,
      data3_out  => data3_mixc_to_p2s);

  p2s : par2ser
    port map (
      clk               => clk,
      load_par_in       => load_par_p2s,
      load_ser_in       => load_ser_p2s,
      shift_in          => shift_p2s,
      data_serial_in    => data_ser_to_p2s,
      data_serial_out   => data_ser_from_p2s,
      data_parallel0_in => data0_mixc_to_p2s,
      data_parallel1_in => data1_mixc_to_p2s,
      data_parallel2_in => data2_mixc_to_p2s,
      data_parallel3_in => data3_mixc_to_p2s);

end architecture rtl;

-------------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -