Commit 83dd7785 authored by tebina nasreddine's avatar tebina nasreddine
Browse files

added files

parent babc108b
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
entity axi_present_tb is
end axi_present_tb;
architecture Behavioral of axi_present_tb is
component axi_present is
generic (
ADRWIDTH : integer := 8;
DATAWIDTH : integer := 32
);
port (
-- AXI SLAVE INTERFACE ----------------------------
-- Clock and Reset
S_AXI_ACLK : in std_logic;
S_AXI_ARESETN : in std_logic;
-- Write Address Channel
S_AXI_AWADDR : in std_logic_vector(ADRWIDTH - 1 downto 0);
S_AXI_AWVALID : in std_logic;
S_AXI_AWREADY : out std_logic;
S_AXI_AWPROT : in std_logic_vector(2 downto 0); --addr write protection
-- Write Data Channel
S_AXI_WDATA : in std_logic_vector(DATAWIDTH - 1 downto 0);
S_AXI_WSTRB : in std_logic_vector(3 downto 0);
S_AXI_WVALID : in std_logic;
S_AXI_WREADY : out std_logic;
-- Read Address Channel
S_AXI_ARADDR : in std_logic_vector(ADRWIDTH - 1 downto 0);
S_AXI_ARVALID : in std_logic;
S_AXI_ARREADY : out std_logic;
S_AXI_ARPROT : in std_logic_vector(2 downto 0); --addr read protection
-- Read Data Channel
S_AXI_RDATA : out std_logic_vector(DATAWIDTH - 1 downto 0);
S_AXI_RRESP : out std_logic_vector(1 downto 0);
S_AXI_RVALID : out std_logic;
S_AXI_RREADY : in std_logic;
-- Write Response Channel
S_AXI_BRESP : out std_logic_vector(1 downto 0);
S_AXI_BVALID : out std_logic;
S_AXI_BREADY : in std_logic
);
end component;
constant ADRWIDTH : integer := 8;
constant DATAWIDTH : integer := 32;
constant clk_period : time := 1 ns;
signal S_AXI_ACLK : std_logic := '0';
signal S_AXI_ARESETN : std_logic := '0';
-- Write Address Channel signals
signal S_AXI_AWADDR : std_logic_vector(ADRWIDTH - 1 downto 0) := (others => '0');
signal S_AXI_AWVALID : std_logic := '0';
signal S_AXI_AWREADY : std_logic := '1';
-- Write Data Channel signals
signal S_AXI_WDATA : std_logic_vector(31 downto 0) := (others => '0');
signal S_AXI_WSTRB : std_logic_vector(3 downto 0) := (others => '0');
signal S_AXI_WVALID : std_logic := '0';
signal S_AXI_WREADY : std_logic;
-- Read Address Channel signals
signal S_AXI_ARADDR : std_logic_vector(ADRWIDTH - 1 downto 0) := (others => '0');
signal S_AXI_ARVALID : std_logic := '0';
signal S_AXI_ARREADY : std_logic := '1';
-- Read Data Channel signals
signal S_AXI_RRESP : std_logic_vector(1 downto 0);
signal S_AXI_RVALID : std_logic;
signal S_AXI_RREADY : std_logic := '0';
-- Write Response Channel signals
signal S_AXI_BRESP : std_logic_vector(1 downto 0);
signal S_AXI_BVALID : std_logic;
signal S_AXI_BREADY : std_logic := '0';
signal S_AXI_AWPROT : std_logic_vector (2 downto 0) := "010";
signal S_AXI_ARPROT : std_logic_vector (2 downto 0) := "010";
signal S_AXI_RDATA : std_logic_vector(31 downto 0) := (others => '0');
--------------------------------------------------------
constant ClockPeriod : time := 5 ns;
constant ClockPeriod2 : time := 10 ns;
shared variable ClockCount : integer range 0 to 50_000 := 10;
signal sendIt : std_logic := '0';
signal readIt : std_logic := '0';
begin
UUT : axi_present
port map(
S_AXI_ACLK => S_AXI_ACLK,
S_AXI_ARESETN => S_AXI_ARESETN,
S_AXI_AWADDR => S_AXI_AWADDR,
S_AXI_AWVALID => S_AXI_AWVALID,
S_AXI_AWREADY => S_AXI_AWREADY,
S_AXI_AWPROT => S_AXI_AWPROT,
S_AXI_WDATA => S_AXI_WDATA,
S_AXI_WSTRB => S_AXI_WSTRB,
S_AXI_WVALID => S_AXI_WVALID,
S_AXI_WREADY => S_AXI_WREADY,
S_AXI_BRESP => S_AXI_BRESP,
S_AXI_BVALID => S_AXI_BVALID,
S_AXI_BREADY => S_AXI_BREADY,
S_AXI_ARADDR => S_AXI_ARADDR,
S_AXI_ARVALID => S_AXI_ARVALID,
S_AXI_ARREADY => S_AXI_ARREADY,
S_AXI_ARPROT => S_AXI_ARPROT,
S_AXI_RRESP => S_AXI_RRESP,
S_AXI_RVALID => S_AXI_RVALID,
S_AXI_RREADY => S_AXI_RREADY,
S_AXI_RDATA => S_AXI_RDATA
--------------------------------------------------------
);
--stimulus :process
--begin
--S_AXI_ARESETN <= '1';
--wait for 200 ns;
--S_AXI_ARESETN <= '0';
----write Address
--S_AXI_AWADDR <= "000000000000010";
--S_AXI_AWVALID <= '1';
--S_AXI_WDATA <= (others => '1');
--S_AXI_WSTRB <= "1111";
--S_AXI_WVALID <= '1';
--S_AXI_ARADDR <= "000000000000000";
--wait for 250 ns;
--S_AXI_ARVALID <= '1';
--S_AXI_RREADY <= '1';
--S_AXI_BREADY <= '1';
--wait for 500 ns;
--end process;
-- Generate S_AXI_ACLK signal
GENERATE_REFCLOCK : process
begin
wait for (ClockPeriod / 2);
ClockCount := ClockCount + 1;
S_AXI_ACLK <= '1';
wait for (ClockPeriod / 2);
S_AXI_ACLK <= '0';
end process;
send : process
begin
S_AXI_AWVALID <= '0';
S_AXI_WVALID <= '0';
S_AXI_BREADY <= '0';
loop
wait until sendIt = '1';
wait until S_AXI_ACLK = '0';
S_AXI_AWVALID <= '1';
S_AXI_WVALID <= '1';
wait until (S_AXI_AWREADY and S_AXI_WREADY) = '1'; --Client ready to read address/data
S_AXI_BREADY <= '1';
wait until S_AXI_BVALID = '1'; -- Write result valid
assert S_AXI_BRESP = "00" report "AXI data NOT written" severity failure;
S_AXI_AWVALID <= '0';
S_AXI_WVALID <= '0';
S_AXI_BREADY <= '1';
wait until S_AXI_BVALID = '0'; -- All finished
S_AXI_BREADY <= '0';
end loop;
end process send;
read : process
begin
S_AXI_ARVALID <= '0';
S_AXI_RREADY <= '0';
loop
wait until readIt = '1';
wait until S_AXI_ACLK = '0';
S_AXI_ARVALID <= '1';
S_AXI_RREADY <= '1';
wait until (S_AXI_RVALID and S_AXI_ARREADY) = '1'; --Client provided data
assert S_AXI_RRESP = "00" report "AXI data NOT written" severity failure;
S_AXI_ARVALID <= '0';
S_AXI_RREADY <= '0';
end loop;
end process read;
--
tb : process
begin
S_AXI_ARESETN <= '0';
sendIt <= '0';
wait for 15 ns;
S_AXI_ARESETN <= '1';
S_AXI_AWADDR <= x"01";
S_AXI_WDATA <= x"00000000";
S_AXI_WSTRB <= b"1111";
sendIt <= '1'; --Start AXI Write to Slave
wait for 1 ns;
sendIt <= '0'; --Clear Start Send Flag
wait until S_AXI_BVALID = '1';
wait until S_AXI_BVALID = '0'; --AXI Write finished
S_AXI_WSTRB <= b"0000";
S_AXI_AWADDR <= x"01";
S_AXI_WDATA <= x"00000001";
S_AXI_WSTRB <= b"1111";
sendIt <= '1'; --Start AXI Write to Slave
wait for 1 ns;
sendIt <= '0'; --Clear Start Send Flag
wait until S_AXI_BVALID = '1';
wait until S_AXI_BVALID = '0'; --AXI Write finished
S_AXI_WSTRB <= b"0000";
S_AXI_AWADDR <= x"01";
S_AXI_WDATA <= x"00000002";
S_AXI_WSTRB <= b"1111";
sendIt <= '1'; --Start AXI Write to Slave
wait for 1 ns;
sendIt <= '0'; --Clear Start Send Flag
wait until S_AXI_BVALID = '1';
wait until S_AXI_BVALID = '0'; --AXI Write finished
S_AXI_WSTRB <= b"0000";
S_AXI_AWADDR <= x"04";
S_AXI_WDATA <= x"A5A5A5A5";
S_AXI_WSTRB <= b"1111";
sendIt <= '1'; --Start AXI Write to Slave
wait for 1 ns;
sendIt <= '0'; --Clear Start Send Flag
wait until S_AXI_BVALID = '1';
wait until S_AXI_BVALID = '0'; --AXI Write finished
S_AXI_WSTRB <= b"0000";
S_AXI_AWADDR <= x"04";
S_AXI_WDATA <= x"A5A5A5A5";
S_AXI_WSTRB <= b"1111";
sendIt <= '1'; --Start AXI Write to Slave
wait for 1 ns;
sendIt <= '0'; --Clear Start Send Flag
wait until S_AXI_BVALID = '1';
wait until S_AXI_BVALID = '0'; --AXI Write finished
S_AXI_WSTRB <= b"0000";
S_AXI_ARADDR <= "00000000";
readIt <= '1'; --Start AXI Read from Slave
wait for 1 ns;
readIt <= '0'; --Clear "Start Read" Flag
wait until S_AXI_RVALID = '1';
wait until S_AXI_RVALID = '0';
S_AXI_ARADDR <= "00000010";
readIt <= '1'; --Start AXI Read from Slave
wait for 1 ns;
readIt <= '0'; --Clear "Start Read" Flag
wait until S_AXI_RVALID = '1';
wait until S_AXI_RVALID = '0';
wait; -- will wait forever
end process tb;
end Behavioral;
library ieee;
use ieee.std_logic_1164.all;
use work.util.all;
entity axi_present is
generic (
ADRWIDTH : integer := 8;
DATAWIDTH : integer := 32
);
port (
-- AXI SLAVE INTERFACE ----------------------------
-- Clock and Reset
S_AXI_ACLK : in std_logic;
S_AXI_ARESETN : in std_logic;
-- Write Address Channel
S_AXI_AWADDR : in std_logic_vector(ADRWIDTH - 1 downto 0);
S_AXI_AWVALID : in std_logic;
S_AXI_AWREADY : out std_logic;
S_AXI_AWPROT : in std_logic_vector(2 downto 0); --addr write protection
-- Write Data Channel
S_AXI_WDATA : in std_logic_vector(DATAWIDTH - 1 downto 0);
S_AXI_WSTRB : in std_logic_vector(3 downto 0);
S_AXI_WVALID : in std_logic;
S_AXI_WREADY : out std_logic;
-- Read Address Channel
S_AXI_ARADDR : in std_logic_vector(ADRWIDTH - 1 downto 0);
S_AXI_ARVALID : in std_logic;
S_AXI_ARREADY : out std_logic;
S_AXI_ARPROT : in std_logic_vector(2 downto 0); --addr read protection
-- Read Data Channel
S_AXI_RDATA : out std_logic_vector(DATAWIDTH - 1 downto 0);
S_AXI_RRESP : out std_logic_vector(1 downto 0);
S_AXI_RVALID : out std_logic;
S_AXI_RREADY : in std_logic;
-- Write Response Channel
S_AXI_BRESP : out std_logic_vector(1 downto 0);
S_AXI_BVALID : out std_logic;
S_AXI_BREADY : in std_logic
);
end entity;
architecture behavioral of axi_present is
component present_top is
generic (k : key_enum);
port (
plaintext : in std_logic_vector(63 downto 0);
key : in std_logic_vector(key_bits(k) - 1 downto 0);
clk : in std_logic;
reset : in std_logic;
ciphertext : out std_logic_vector(63 downto 0)
);
end component;
type text_buffer is array (0 to 1) of std_logic_vector(DATAWIDTH - 1 downto 0);
type key_buffer is array (0 to 3) of std_logic_vector(DATAWIDTH - 1 downto 0);
signal plaintext_buf : text_buffer;
signal ciphertext_buf : text_buffer;
signal key_buf : key_buffer;
constant plaintext_reads : natural := 2;
constant key_reads : natural := 4;
constant active_cycles : natural := 33;
constant ciphertext_writes : natural := 2;
signal counter : natural range 0 to 32;
signal ip_plaintext : std_logic_vector(63 downto 0);
signal ip_key : std_logic_vector(127 downto 0);
signal ip_reset : std_logic;
signal ip_ciphertext : std_logic_vector(63 downto 0);
type state_type is (idle, read_plaintext, read_key, stabilize, active, write_ciphertext);
signal state : state_type;
begin
BLOCK_CIPHER : present_top
generic map(
k => K_128
)
port map(
plaintext => ip_plaintext,
key => ip_key,
clk => S_AXI_ACLK,
reset => ip_reset,
ciphertext => ip_ciphertext
);
ip_plaintext <= plaintext_buf(0) & plaintext_buf(1);
ciphertext_buf (0) <= ip_ciphertext (31 downto 0);
ciphertext_buf (1) <= ip_ciphertext (63 downto 32);
ip_key <= key_buf(0) & key_buf(1) & key_buf(2) & key_buf(3);
ip_reset <= '0' when state = active else '1';
S_AXI_WREADY <= '1' when (state = read_plaintext or state = read_key) else '0';
S_AXI_AWREADY <= '1' when (state = read_plaintext or state = read_key) else '0';
S_AXI_RVALID <= '1' when state = write_ciphertext else '0';
S_AXI_ARREADY <= '1' when state = write_ciphertext else '0';
state_machine : process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
state <= idle;
counter <= 0;
else
case state is
when idle =>
ciphertext_buf(0) <= (others => '0');
ciphertext_buf(1) <= (others => '0');
S_AXI_RDATA <= (others => '0');
if S_AXI_WVALID = '1' then
state <= read_plaintext;
counter <= 0;
end if;
when read_plaintext =>
if S_AXI_AWVALID = '1' and S_AXI_WVALID = '1' then
plaintext_buf(counter) <= S_AXI_WDATA;
if counter = plaintext_reads - 1 then
state <= read_key;
counter <= 0;
else
counter <= counter + 1;
end if;
end if;
when read_key =>
if S_AXI_AWVALID = '1' and S_AXI_WVALID = '1' then
key_buf(counter) <= S_AXI_WDATA;
if counter = key_reads - 1 then
state <= stabilize;
counter <= 0;
else
counter <= counter + 1;
end if;
end if;
when stabilize =>
state <= active;
when active =>
if counter = active_cycles - 1 then
ciphertext_buf(0) <= ip_ciphertext(63 downto 32);
ciphertext_buf(1) <= ip_ciphertext(31 downto 0);
state <= write_ciphertext;
counter <= 0;
else
counter <= counter + 1;
end if;
when write_ciphertext =>
S_AXI_RDATA <= ciphertext_buf (counter);
if S_AXI_RREADY = '1' then
if counter = ciphertext_writes - 1 then
state <= idle;
counter <= 0;
else
counter <= counter + 1;
end if;
end if;
end case;
end if;
end if;
end process;
process (S_AXI_ACLK)
begin
if S_AXI_ARESETN = '0' then
S_AXI_BVALID <= '0';
else
S_AXI_BVALID <= '1';
S_AXI_BRESP <= "00";
S_AXI_RRESP <= "00";
end if;
end process;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.util.all;
entity key_schedule is
generic(k: key_enum);
port(data_in: in std_logic_vector(key_bits(k)-1 downto 0);
round_counter: in std_logic_vector(4 downto 0);
data_out: out std_logic_vector(key_bits(k)-1 downto 0)
);
end key_schedule;
architecture structural of key_schedule is
signal shifted: std_logic_vector(key_bits(k)-1 downto 0);
component sbox
port(data_in: in std_logic_vector(3 downto 0);
data_out: out std_logic_vector(3 downto 0)
);
end component;
begin
SCHEDULE_80: if k = K_80 generate
shifted <= data_in(18 downto 0) & data_in(79 downto 19);
SB: sbox port map(
data_in => shifted(79 downto 76),
data_out => data_out(79 downto 76)
);
data_out(75 downto 20) <= shifted(75 downto 20);
data_out(19 downto 15) <= shifted(19 downto 15) xor round_counter;
data_out(14 downto 0) <= shifted(14 downto 0);
end generate;
SCHEDULE_128: if k = K_128 generate
shifted <= data_in(66 downto 0) & data_in(127 downto 67);
SB1: sbox port map(
data_in => shifted(127 downto 124),
data_out => data_out(127 downto 124)
);
SB2: sbox port map(
data_in => shifted(123 downto 120),
data_out => data_out(123 downto 120)
);
data_out(119 downto 67) <= shifted(119 downto 67);
data_out(66 downto 62) <= shifted(66 downto 62) xor round_counter;
data_out(61 downto 0) <= shifted(61 downto 0);
end generate;
end structural;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity perm_layer is
port(data_in: in std_logic_vector(63 downto 0);
data_out: out std_logic_vector(63 downto 0)
);
end perm_layer;
architecture structural of perm_layer is
begin
PERM: for i in 63 downto 0 generate
data_out((i mod 4) * 16 + (i / 4)) <= data_in(i);
end generate;
end structural;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.util.all;
entity present_top is
generic(k: key_enum);
port(plaintext: in std_logic_vector(63 downto 0);
key: in std_logic_vector(key_bits(k)-1 downto 0);
clk: in std_logic;
reset: in std_logic;
ciphertext: out std_logic_vector(63 downto 0)
);
end present_top;
architecture behavioral of present_top is
signal data_state,
data_key_added,
data_substituted,
data_permuted: std_logic_vector(63 downto 0);
signal key_state,
key_updated: std_logic_vector(key_bits(k)-1 downto 0);
signal round_counter: std_logic_vector(4 downto 0);
component sub_layer
port(data_in: in std_logic_vector(63 downto 0);
data_out: out std_logic_vector(63 downto 0)
);
end component;
component perm_layer
port(data_in: in std_logic_vector(63 downto 0);
data_out: out std_logic_vector(63 downto 0)
);
end component;
component key_schedule
generic(k: key_enum);
port(data_in: in std_logic_vector(key_bits(k)-1 downto 0);
round_counter: in std_logic_vector(4 downto 0);
data_out: out std_logic_vector(key_bits(k)-1 downto 0)
);
end component;
begin
SL: sub_layer port map(
data_in => data_key_added,
data_out => data_substituted
);
PL: perm_layer port map(
data_in => data_substituted,
data_out => data_permuted
);
KS: key_schedule generic map(
k => k
) port map(
data_in => key_state,
round_counter => round_counter,
data_out => key_updated
);
data_key_added <= data_state xor key_state(key_bits(k)-1 downto key_bits(k)-64);
process(clk)
begin
if rising_edge(clk) then
if reset = '1' then
data_state <= plaintext;
key_state <= key;
round_counter <= "00001";
ciphertext <= (others => '0');
else
data_state <= data_permuted;
key_state <= key_updated;
round_counter <= std_logic_vector(unsigned(round_counter) + 1);
-- when we are "past" the final round, i.e. the 31st round was finished,
-- the round counter addition overflows back to zero. Now set the output
-- signal to the ciphertext.
case round_counter is
when "00000" => ciphertext <= data_key_added;
when others => ciphertext <= (others => '0');
end case;
--if round_counter = "00000" then
-- ciphertext <= data_key_added;
--end if;
end if;
end if;
end process;
end behavioral;
library ieee;
use ieee.std_logic_1164.all;
entity sbox is
port(data_in: in std_logic_vector(3 downto 0);
data_out: out std_logic_vector(3 downto 0)
);
end sbox;
architecture behavioral of sbox is
begin
process(data_in)
begin
case data_in is
when x"0" => data_out <= x"C";
when x"1" => data_out <= x"5";
when x"2" => data_out <= x"6";
when x"3" => data_out <= x"B";
when x"4" => data_out <= x"9";
when x"5" => data_out <= x"0";
when x"6" => data_out <= x"A";
when x"7" => data_out <= x"D";