I have two 8-bit unsigned vectors named a and b, and 16-bit unsigned vector called result. I want to compute a * b * 4 and assign it to result. I do not care about overflow because I know that it will not happen for some reason, it is not important. Is the following way correct?
result <= a * b;
result <= result(13 downto 0) & "00";
(Assume these two lines are in a clocked process.)
No, this will not work. It will just assign to result
its previous value left-shifted by 2 positions. This is due to the simulation semantics. To make it short, if you assign several times the same signal in a process, during the same simulation step, the last assignment overrides the others, just like if they did not exist. In your case you can delete the result <= a * b;
line, it will behave the same. And of course, synthesizers implement something that has the same behaviour.
Use an intermediate variable, maybe:
process(...)
variable tmp: unsigned(15 downto 0);
begin
...
tmp := a * b;
result <= tmp(13 downto 0) & "00";
...
end process;
Variant:
process(...)
variable tmp: unsigned(17 downto 0);
begin
...
tmp := (a & '0') * (b & '0');
result <= tmp(15 downto 0);
...
end process;
And I recommend finding and reading a good book about VHDL that explains the semantics of the language, especially the difference between variables and signals, the delayed assignment of signals... Note that understanding this will also be very helpful to program with other HDLs like SystemVerilog or SystemC.