diff options
Diffstat (limited to 'testsuite/synth/issue1390/aes_enc.vhdl')
-rw-r--r-- | testsuite/synth/issue1390/aes_enc.vhdl | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/testsuite/synth/issue1390/aes_enc.vhdl b/testsuite/synth/issue1390/aes_enc.vhdl new file mode 100644 index 000000000..ee51ae29c --- /dev/null +++ b/testsuite/synth/issue1390/aes_enc.vhdl @@ -0,0 +1,170 @@ +-- ====================================================================== +-- AES encryption/decryption +-- Copyright (C) 2019 Torsten Meissner +------------------------------------------------------------------------- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. + +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. + +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +-- ====================================================================== + + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.aes_pkg.all; + + + +entity aes_enc is + generic ( + design_type : string := "ITER" + ); + port ( + reset_i : in std_logic; -- async reset + clk_i : in std_logic; -- clock + key_i : in std_logic_vector(0 to 127); -- key input + data_i : in std_logic_vector(0 to 127); -- data input + valid_i : in std_logic; -- input key/data valid flag + accept_o : out std_logic; + data_o : out std_logic_vector(0 to 127); -- data output + valid_o : out std_logic; -- output data valid flag + accept_i : in std_logic + ); +end entity aes_enc; + + + +architecture rtl of aes_enc is + + +begin + + + IterG : if design_type = "ITER" generate + + + signal s_round : t_enc_rounds; + + + begin + + + CryptP : process (reset_i, clk_i) is + variable v_state : t_datatable2d; + variable v_key : t_key; + begin + if (reset_i = '0') then + v_state := (others => (others => (others => '0'))); + v_key := (others => (others => '0')); + s_round <= 0; + accept_o <= '0'; + data_o <= (others => '0'); + valid_o <= '0'; + elsif (rising_edge(clk_i)) then + case s_round is + + when 0 => + accept_o <= '1'; + if (accept_o = '1' and valid_i = '1') then + accept_o <= '0'; + v_state := set_state(data_i); + v_key := set_key(key_i); + s_round <= s_round + 1; + end if; + + when 1 => + v_state := addroundkey(v_state, v_key); + v_key := key_round(v_key, s_round-1); + s_round <= s_round + 1; + + when t_enc_rounds'high-1 => + v_state := subbytes(v_state); + v_state := shiftrow(v_state); + v_state := addroundkey(v_state, v_key); + s_round <= s_round + 1; + -- set data & valid to save one cycle + valid_o <= '1'; + data_o <= get_state(v_state); + + when t_enc_rounds'high => + if (valid_o = '1' and accept_i = '1') then + valid_o <= '0'; + data_o <= (others => '0'); + s_round <= 0; + -- Set accept to save one cycle + accept_o <= '1'; + end if; + + when others => + v_state := subbytes(v_state); + v_state := shiftrow(v_state); + v_state := mixcolumns(v_state); + v_state := addroundkey(v_state, v_key); + v_key := key_round(v_key, s_round-1); + s_round <= s_round + 1; + + end case; + end if; + end process CryptP; + + + psl : block is + + signal s_key , s_din, s_dout : std_logic_vector(0 to 127) := (others => '0'); + + begin + + process (clk_i) is + begin + if (rising_edge(clk_i)) then + s_key <= key_i; + s_din <= data_i; + s_dout <= data_o; + end if; + end process; + + default clock is rising_edge(clk_i); + + -- initial reset + restrict {not reset_i; reset_i[+]}[*1]; + + -- constraints + assume always (valid_i and not accept_o -> next valid_i); + assume always (valid_i and not accept_o -> next key_i = s_key); + assume always (valid_i and not accept_o -> next data_i = s_din); + + ACCEPTO_c : cover {accept_o}; + ACCEPT_IN_ROUND_0_ONLY_a : assert always (accept_o -> s_round = 0); + + VALIDI_AND_ACCEPTO_c : cover {valid_i and accept_o}; + ACCEPT_OFF_WHEN_VALID_a : assert always (valid_i and accept_o -> next not accept_o); + + VALIDO_c : cover {valid_o}; + VALID_IN_LAST_ROUND_ONLY_a : assert always (valid_o -> s_round = t_enc_rounds'high); + + VALIDO_AND_ACCEPTI_c : cover {valid_o and accept_i}; + VALID_OFF_WHEN_ACCEPTED_a : assert always (valid_o and accept_i -> next not valid_o); + + VALIDO_AND_NOT_ACCEPTI_c : cover {valid_o and not accept_i}; + VALID_STABLE_WHEN_NOT_ACCEPTED_a : assert always (valid_o and not accept_i -> next valid_o); + DATA_STABLE_WHEN_NOT_ACCEPTED_a : assert always (valid_o and not accept_i -> next data_o = s_dout); + + end block psl; + + + end generate IterG; + + + +end architecture rtl; |