📄 aes.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 + -