我正在实现Booth的算法,用于在VHDL中将两个数字(无符号2的补码形式)相乘。不幸的是,我在VHDL上很穷,无法弄清楚我哪里出错了。
问题:在逐步完成模拟时,我注意到当我为y分配了值“1011”时,信号mult得到了“0UUU”。我不明白为什么会这样。这是我的代码:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-- x, y are the n bit numbers to be multiplied.
-- The Algorithm :
-- U = 0, prev_bit = 0;
-- for i = 1 to n do
-- if start of a string of 1's in Y then U = U - X
-- if end of a string of 1's in Y then U = U + X
-- Arithmetic right shift UV
-- Circular right shift Y and copy Y(0) to prev_bit
entity booth is
generic(N : natural := 4);
port(
x, y : in std_logic_vector(N-1 downto 0);
result : out std_logic_vector(2*N-1 downto 0);
clk : in std_logic
);
end booth;
architecture booth_arch of booth is
--temp is equivalent to UV where UV is the result.
signal temp : std_logic_vector(2*N-1 downto 0) := (others => '0');
--prev_bit to compare for starting and ending of strings of 1's.
signal prev_bit : std_logic := '0';
signal mult : std_logic_vector(N-1 downto 0);
begin
process(x, y)
begin
mult <= y;
prev_bit <= '0';
for i in 0 to N-1 loop
if(mult(0) = '1' and prev_bit = '0') then --start of a string of 1's
temp(2*N-1 downto N) <= std_logic_vector(unsigned(temp(2*N-1 downto N)) + unsigned(not(x)) + 1);
elsif(mult(0) = '0' and prev_bit = '1') then --end of a string of 1's
temp(2*N-1 downto N) <= std_logic_vector(unsigned(temp(2*N-1 downto N)) + unsigned(x));
end if;
prev_bit <= mult(0);
mult(N-2 downto 0) <= mult(N-1 downto 1); --circular right shift y.
mult(N-1) <= prev_bit;
temp(2*N-2 downto 0) <= temp(2*N-1 downto 1); --arithmetic right shift temp.
end loop;
result <= temp;
end process;
end booth_arch;
P.S:clk信号在这里是多余的。我还没用过它。
答案 0 :(得分:1)
如果您的端口和内部信号是无符号的,请将它们声明为unsigned
,以便开始。至少你使用的是正确的numeric_std库。使用强类型系统而不是反对它!
然后,您可能需要在每次乘法开始时初始化Temp
(正如您已经为Mult, Prev_Bit
所做的那样),而不是在模拟开始时初始化Temp
。目前,UUUU
似乎可以包含先前乘法中的陈旧值(例如UUUU
* Y
)。
第三,您告诉我们您已分配给X
的内容,但我们还不知道您分配给UUUU
的内容,对于我所知道的内容,我仍然可以{{1}}。< / p>
编写一个最小的VHDL测试平台并将其添加到问题中将是获得进一步帮助的好方法 - 或者更可能的是,自己发现问题的真正原因!
答案 1 :(得分:1)
除了Brian的评论之外:您正在同一个组合过程中阅读和编写信号mult。除非你的真的知道你在做什么,否则你不应该这样做。合成之后,你会得到与你的模拟器不相符的东西。
此外,您应该知道,在进程完成并开始新的迭代之后,您分配给mult
的值(在进程的第一行)将不可见。在VHDL -speak中,我们说新值在一个 delta周期之后可用。