在 VHDL 中将结果相乘并移位
Multiply and shift the result in VHDL
我有两个名为 a 和 b 的 8 位无符号向量,以及一个名为 result 的 16 位无符号向量。我想计算 a * b * 4 并将其分配给结果。我不关心溢出,因为我知道它不会因为某种原因发生,这并不重要。下面的方法对吗?
result <= a * b;
result <= result(13 downto 0) & "00";
(假设这两行在一个时钟进程中。)
不,这行不通。它只会分配给 result
其先前的值左移 2 个位置。这是由于模拟语义。简而言之,如果您在一个过程中多次分配相同的信号,在同一个模拟步骤中,最后一次分配会覆盖其他分配,就像它们不存在一样。在您的情况下,您可以删除 result <= a * b;
行,它的行为相同。当然,合成器实现了具有相同行为的东西。
使用中间变量,也许:
process(...)
variable tmp: unsigned(15 downto 0);
begin
...
tmp := a * b;
result <= tmp(13 downto 0) & "00";
...
end process;
变体:
process(...)
variable tmp: unsigned(17 downto 0);
begin
...
tmp := (a & '0') * (b & '0');
result <= tmp(15 downto 0);
...
end process;
而且我推荐找一本关于VHDL的好书,里面解释了语言的语义,特别是变量和信号的区别,信号的延迟赋值...注意,理解这个对以后也很有帮助使用 SystemVerilog 或 SystemC 等其他 HDL 进行编程。
我有两个名为 a 和 b 的 8 位无符号向量,以及一个名为 result 的 16 位无符号向量。我想计算 a * b * 4 并将其分配给结果。我不关心溢出,因为我知道它不会因为某种原因发生,这并不重要。下面的方法对吗?
result <= a * b;
result <= result(13 downto 0) & "00";
(假设这两行在一个时钟进程中。)
不,这行不通。它只会分配给 result
其先前的值左移 2 个位置。这是由于模拟语义。简而言之,如果您在一个过程中多次分配相同的信号,在同一个模拟步骤中,最后一次分配会覆盖其他分配,就像它们不存在一样。在您的情况下,您可以删除 result <= a * b;
行,它的行为相同。当然,合成器实现了具有相同行为的东西。
使用中间变量,也许:
process(...)
variable tmp: unsigned(15 downto 0);
begin
...
tmp := a * b;
result <= tmp(13 downto 0) & "00";
...
end process;
变体:
process(...)
variable tmp: unsigned(17 downto 0);
begin
...
tmp := (a & '0') * (b & '0');
result <= tmp(15 downto 0);
...
end process;
而且我推荐找一本关于VHDL的好书,里面解释了语言的语义,特别是变量和信号的区别,信号的延迟赋值...注意,理解这个对以后也很有帮助使用 SystemVerilog 或 SystemC 等其他 HDL 进行编程。