I am implementing a block cipher(SQUARE) which consists of 8 rounds (see below). The cipher must allow two operational modes : encryption and decryption (denoted as mode = 0
or mode = 1
in code).
entity SQUARE is
Port ( mode : in STD_LOGIC;
squarein : in STD_LOGIC_VECTOR (127 downto 0);
key : in STD_LOGIC_VECTOR (127 downto 0);
squareout : out STD_LOGIC_VECTOR (127 downto 0)
);
end SQUARE;
enc : if (mode = '0') generate -- do encryption
s0 : preround port map(squarein, key, con0, key1, rin1);
s1 : round port map(rin1, key1, con1, key2, rin2);
s2 : round port map(rin2, key2, con2, key3, rin3);
s3 : round port map(rin3, key3, con3, key4, rin4);
s4 : round port map(rin4, key4, con4, key5, rin5);
s5 : round port map(rin5, key5, con5, key6, rin6);
s6 : round port map(rin6, key6, con6, key7, rin7);
s7 : round port map(rin7, key7, con7, key8, rin8);
s8 : lastround port map(rin8, key8, squareout);
end generate;
dec : if (mode = '1') generate -- do decryption
i8 : invround port map(squarein, key8, con7, invkey7, invrin7);
i7 : invround port map(invrin7, invkey7, con6, invkey6, invrin6);
i6 : invround port map(invrin6, invkey6, con5, invkey5, invrin5);
i5 : invround port map(invrin5, invkey5, con4, invkey4, invrin4);
i4 : invround port map(invrin4, invkey4, con3, invkey3, invrin3);
i3 : invround port map(invrin3, invkey3, con2, invkey2, invrin2);
i2 : invround port map(invrin2, invkey2, con1, invkey1, invrin1);
i1 : invround port map(invrin1, invkey1, con0, invkey0, invrin0);
i0 : invpreround port map(invrin0, invkey0, squareout);
end generate;
Problem: Compile was successful with warnings (Condition in IF GENERATE must be static). How could I avoid this warning ? Maybe rewriting the code in other fashion ..
As stated by Paebbels, generate
cannot be used dynamically. It needs to be constant at compile/synthesis time. what you could do is use a generic instead (using the VHDL-2008 if-else generate construct):
entity SQUARE is
generic(mode : std_logic);
Port ( squarein : in STD_LOGIC_VECTOR (127 downto 0);
key : in STD_LOGIC_VECTOR (127 downto 0);
squareout : out STD_LOGIC_VECTOR (127 downto 0)
);
end entity;
architecture structural or SQUARE is
begin
enc : if (mode = '0') generate -- do encryption
s0 : entity work.preround port map(squarein, key, con0, key1, rin1);
[...]
else generate
-- decrypt
i8 : entity work.invround port map(squarein, key8, con7, invkey7, invrin7);
[...]
end generate;
end architecture;
If you want to change the mode of operation on the fly, you need to generate all the components, and select an output using muxes:
entity SQUARE is
Port ( mode : in std_logic;
squarein : in STD_LOGIC_VECTOR (127 downto 0);
key : in STD_LOGIC_VECTOR (127 downto 0);
squareout : out STD_LOGIC_VECTOR (127 downto 0)
);
end entity;
architecture structural or SQUARE is
begin
-- encrypt components
s0 : entity work.preround port map(squarein, key, con0, key1, rin1);
[...]
s8 : entity work.lastround port map(rin8, key8, squareout_enc);
-- decrypt components
i8 : entity work.invround port map(squarein, key8, con7, invkey7, invrin7);
[...]
i0 : entity work.invpreround port map(invrin0, invkey0, squareout_dec);
-- connect outputs
squareout <= squareout_enc when mode='0' else squareout_dec;
end architecture;