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; state_signal : out std_logic_vector (2 downto 0); ip_plaintext_signal : out std_logic_vector (63 downto 0); ip_ciphertext_buffer : out std_logic_vector (31 downto 0); counter_signal : out natural; ip_key_signal : out std_logic_vector (127 downto 0); ip_key_buffer : out std_logic_vector (31 downto 0); ip_ciphertext_signal : out std_logic_vector (63 downto 0) ); 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 5) 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 ;--:= (others => ( others => '0')) ; signal ciphertext_buf : text_buffer;--:= (others => ( others => '0')); signal key_buf : key_buffer ;--:= (others => ( others => '0')); 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, stabilize_read,active, write_ciphertext); signal state : state_type; signal done : boolean := false ; 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_BRESP <= "00"; S_AXI_RRESP <= "00"; ip_plaintext_signal <= ip_plaintext; ip_ciphertext_buffer <= ciphertext_buf(0); ip_key_signal <= ip_key; ip_key_buffer <= key_buf(1); counter_signal <= counter; ip_ciphertext_signal <= ip_ciphertext; 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 => S_AXI_RDATA <= (others => '0'); S_AXI_RVALID <= '0'; S_AXI_ARREADY <= '0'; S_AXI_BVALID <= '0'; S_AXI_WREADY <= '0'; S_AXI_AWREADY <= '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 S_AXI_BVALID <= '1'; S_AXI_WREADY <= '1'; S_AXI_AWREADY <= '1' ; plaintext_buf(counter) <= S_AXI_WDATA; state <= stabilize; end if; when read_key => if S_AXI_AWVALID = '1' and S_AXI_WVALID = '1' then key_buf(counter-plaintext_reads-1) <= S_AXI_WDATA; S_AXI_BVALID <= '1'; S_AXI_WREADY <= '1'; S_AXI_AWREADY <= '1' ; state <= stabilize; end if; when stabilize => counter <= counter +1; S_AXI_BVALID <= '0'; S_AXI_WREADY <= '0'; S_AXI_AWREADY <= '0'; case counter is when 0 to 1 => state <= read_plaintext ; when 2 to 5 => state <= read_key ; when others => state <= active; counter <= 0 ; end case; when stabilize_read => counter <= counter +1 ; S_AXI_RVALID <= '0'; S_AXI_ARREADY <= '0'; state <= write_ciphertext; if counter = ciphertext_writes-1 then state <= idle ; end if; when active => if counter = active_cycles - 1 then state <= write_ciphertext; counter <= 0; else counter <= counter + 1; end if; when write_ciphertext => --if S_AXI_ARVALID = '1' and S_AXI_RREADY = '1' then S_AXI_RDATA <= ciphertext_buf(counter); S_AXI_RVALID <= '1'; S_AXI_ARREADY <= '1'; state <= stabilize_read; --end if ; end case; end if; end if; end process; process (state) begin case state is when idle => state_signal <= "000"; when read_plaintext => state_signal <= "001"; when read_key => state_signal <= "010"; when stabilize => state_signal <= "011"; when active => state_signal <= "100"; when write_ciphertext => state_signal <= "101"; when stabilize_read => state_signal <= "110"; when others => state_signal <= "XXX"; end case; end process; end architecture;