I am currently trying to optimize a 4-bit finite field multiplication modulo X^4 + X^3 + 1 that I've made in VHDL. I did a 16x16 array containing all the results of the multiplications, and when I want to multiply to numbers, for example 8 and 15, i just write byte_out <= mult_array(8,15).

Would you have any advice on how to optimize the calculation ?

PS : here is the entity I made :

library IEEE;

entity GF_Mult is
port (gf_in_1  : in  std_logic_vector(3 downto 0);
      gf_in_2  : in  std_logic_vector(3 downto 0);
      gf_out   : out std_logic_vector(3 downto 0));
end GF_Mult;

architecture arch of GF_Mult is

type gfarray is array(0 to 15, 0 to 15) of std_logic_vector(3 downto 0);

constant GF_MULT_ARRAY : gfarray := 
((x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0"),
(x"0", x"1", x"2", x"3", x"4", x"5", x"6", x"7", x"8", x"9", x"a", x"b", x"c", x"d", x"e", x"f"),
(x"0", x"2", x"4", x"6", x"8", x"a", x"c", x"e", x"9", x"b", x"d", x"f", x"1", x"3", x"5", x"7"),
(x"0", x"3", x"6", x"5", x"c", x"f", x"a", x"9", x"1", x"2", x"7", x"4", x"d", x"e", x"b", x"8"),
(x"0", x"4", x"8", x"c", x"9", x"d", x"1", x"5", x"b", x"f", x"3", x"7", x"2", x"6", x"a", x"e"),
(x"0", x"5", x"a", x"f", x"d", x"8", x"7", x"2", x"3", x"6", x"9", x"c", x"e", x"b", x"4", x"1"),
(x"0", x"6", x"c", x"a", x"1", x"7", x"d", x"b", x"2", x"4", x"e", x"8", x"3", x"5", x"f", x"9"),
(x"0", x"7", x"e", x"9", x"5", x"2", x"b", x"c", x"a", x"d", x"4", x"3", x"f", x"8", x"1", x"6"),
(x"0", x"8", x"9", x"1", x"b", x"3", x"2", x"a", x"f", x"7", x"6", x"e", x"4", x"c", x"d", x"5"),
(x"0", x"9", x"b", x"2", x"f", x"6", x"4", x"d", x"7", x"e", x"c", x"5", x"8", x"1", x"3", x"a"),
(x"0", x"a", x"d", x"7", x"3", x"9", x"e", x"4", x"6", x"c", x"b", x"1", x"5", x"f", x"8", x"2"),
(x"0", x"b", x"f", x"4", x"7", x"c", x"8", x"3", x"e", x"5", x"1", x"a", x"9", x"2", x"6", x"d"),
(x"0", x"c", x"1", x"d", x"2", x"e", x"3", x"f", x"4", x"8", x"5", x"9", x"6", x"a", x"7", x"b"),
(x"0", x"d", x"3", x"e", x"6", x"b", x"5", x"8", x"c", x"1", x"f", x"2", x"a", x"7", x"9", x"4"),
(x"0", x"e", x"5", x"b", x"a", x"4", x"f", x"1", x"d", x"3", x"8", x"6", x"7", x"9", x"2", x"c"),
(x"0", x"f", x"7", x"8", x"e", x"1", x"9", x"6", x"5", x"a", x"2", x"d", x"b", x"4", x"c", x"3"));


process(gf_in_1, gf_in_2)
    gf_out <= GF_MULT_ARRAY(to_integer(unsigned(gf_in_1)), to_integer(unsigned(gf_in_2)));
end process;

end arch;

"optimise" ? no : improve, yes`.

I would do two things :

  1. If you can cleanly express the formula in a VHDL function, I would initialise the gfarray from that function. It'll be easier to maintain and less error-prone than manually transcribing every value. As it's a constant, the function won't be executed at runtime.
  2. Minor : I'd declare the input ports as natural range 0 to 15 and clean up a lot of unnecessary type conversions - if permitted.
  • \$\begingroup\$ 1. Actually i don't know the formula, and I wanted to know if someone knew it ! 2. If i declare my input as a natural I will have to do a conversion before, so I do not think it could improve the overall design. \$\endgroup\$ – Cedric Jul 4 '18 at 12:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.