VHDL 乘法器,其输出与其输入具有相同的一侧
VHDL multiplier which output has the same side of it's inputs
我正在使用 VHDL 来描述一个 32 位乘法器,对于要在 Xilinx FPGA 上实现的系统,我在网上发现经验法则是,如果你有 N 位大小的输入,输出必须有 (2*N) 位的大小。我将它用于反馈系统,是否可以有一个输出与输入大小相同的乘法器?
我发誓,一旦我发现了一个 fpga 应用程序,它的 vhdl 代码有加法器和乘法器块,这些块与相同大小的信号相连。编写代码的人告诉我,您只需将乘积的结果放在 64 位信号上,然后输出必须获得结果的最高 32 位(不一定是最高 32 位) 64 位信号)。
当时我使用下一个代码构建了一个系统(显然有效):
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Multiplier32Bits is
port(
CLK: in std_logic;
A,B: in std_logic_vector(31 downto 0);
R: out std_logic_vector(31 downto 0)
);
end Multiplier32Bits;
architecture Behavioral of Multiplier32Bits is
signal next_state: std_logic_vector(63 downto 0);
signal state: std_logic_vector(31 downto 0);
begin
Sequential: process(CLK,state,next_state)
begin
if CLK'event and CLK = '1' then
state <= next_state(61 downto 30);
else
state <= state;
end if;
end process Sequential;
--Combinational part
next_state <= std_logic_vector(signed(A)*signed(B));
--Output assigment
R <= state;
end Behavioral;
虽然它在工作,因为当时我使用 Active-HDL FPGA 模拟器模拟了块,但我知道我正在使用 Xilinx ISE 设计套件中的 iSim 模拟整个 32 位系统。我发现我的输出与 A 和 B 输入的实际乘积有很大差异,我不知道这是否只是由于跳过 32 位而导致精度下降,或者我的代码很糟糕。
您的代码有一些问题:
next_state
和 state
不属于敏感列表
- 写法
CLK'event and CLK = '1'
应该换成rising_edge(CLK)
state <= state;
没有效果,并导致一些工具(如 ISE)误读模式。删除它。
- 在运算符周围放置空格没有坏处,但会提高可读性。
- 为什么你期望 a * b 的结果在 30 到 61 位而不是 0 到 31 位?
state
和 next_state
不代表状态机的状态。这只是一个寄存器。
改进代码:
architecture Behavioral of Multiplier32Bits is
signal next_state: std_logic_vector(63 downto 0);
signal state: std_logic_vector(31 downto 0);
begin
Sequential: process(CLK)
begin
if rising_edge(CLK) then
state <= next_state(31 downto 0);
end if;
end process Sequential;
--Combinational part
next_state <= std_logic_vector(signed(A) * signed(B));
--Output assigment
R <= state;
end architecture Behavioral;
我完全同意 Paebbels 写的所有内容。但我会向您解释有关结果中位数的事情。
因此,我将通过以 10 为基数的示例进行解释。
9 * 9 = 81 (two 1 digit numbers gives maximum of 2 digits)
99 * 99 = 9801 (two 2 digit numbers gives maximum of 4 digits)
999 * 999 = 998001 (two 3 digit numbers gives maximum of 6 digits)
9999 * 9999 = 99980001 (4 digits -> 8 digits)
以此类推...二进制完全一样。这就是为什么输出是输入大小的 (2*N) 位。
但是,如果您的数字较小,则结果将适合相同数量的数字,作为因数:
3 * 3 = 9
10 * 9 = 90
100 * 99 = 990
等等。所以如果你的数字足够小,那么结果将是 32 位。当然,正如 Paebbels 已经写的那样,结果将至少是信号的重要部分。
正如 J.H.Bonarius 已经指出的那样,如果您的输入不是整数,而是定点数,那么您将不得不进行 post 移位。如果是这种情况,请在评论中写下,我会解释该怎么做。
我正在使用 VHDL 来描述一个 32 位乘法器,对于要在 Xilinx FPGA 上实现的系统,我在网上发现经验法则是,如果你有 N 位大小的输入,输出必须有 (2*N) 位的大小。我将它用于反馈系统,是否可以有一个输出与输入大小相同的乘法器?
我发誓,一旦我发现了一个 fpga 应用程序,它的 vhdl 代码有加法器和乘法器块,这些块与相同大小的信号相连。编写代码的人告诉我,您只需将乘积的结果放在 64 位信号上,然后输出必须获得结果的最高 32 位(不一定是最高 32 位) 64 位信号)。
当时我使用下一个代码构建了一个系统(显然有效):
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Multiplier32Bits is
port(
CLK: in std_logic;
A,B: in std_logic_vector(31 downto 0);
R: out std_logic_vector(31 downto 0)
);
end Multiplier32Bits;
architecture Behavioral of Multiplier32Bits is
signal next_state: std_logic_vector(63 downto 0);
signal state: std_logic_vector(31 downto 0);
begin
Sequential: process(CLK,state,next_state)
begin
if CLK'event and CLK = '1' then
state <= next_state(61 downto 30);
else
state <= state;
end if;
end process Sequential;
--Combinational part
next_state <= std_logic_vector(signed(A)*signed(B));
--Output assigment
R <= state;
end Behavioral;
虽然它在工作,因为当时我使用 Active-HDL FPGA 模拟器模拟了块,但我知道我正在使用 Xilinx ISE 设计套件中的 iSim 模拟整个 32 位系统。我发现我的输出与 A 和 B 输入的实际乘积有很大差异,我不知道这是否只是由于跳过 32 位而导致精度下降,或者我的代码很糟糕。
您的代码有一些问题:
next_state
和state
不属于敏感列表- 写法
CLK'event and CLK = '1'
应该换成rising_edge(CLK)
state <= state;
没有效果,并导致一些工具(如 ISE)误读模式。删除它。- 在运算符周围放置空格没有坏处,但会提高可读性。
- 为什么你期望 a * b 的结果在 30 到 61 位而不是 0 到 31 位?
state
和next_state
不代表状态机的状态。这只是一个寄存器。
改进代码:
architecture Behavioral of Multiplier32Bits is
signal next_state: std_logic_vector(63 downto 0);
signal state: std_logic_vector(31 downto 0);
begin
Sequential: process(CLK)
begin
if rising_edge(CLK) then
state <= next_state(31 downto 0);
end if;
end process Sequential;
--Combinational part
next_state <= std_logic_vector(signed(A) * signed(B));
--Output assigment
R <= state;
end architecture Behavioral;
我完全同意 Paebbels 写的所有内容。但我会向您解释有关结果中位数的事情。 因此,我将通过以 10 为基数的示例进行解释。
9 * 9 = 81 (two 1 digit numbers gives maximum of 2 digits)
99 * 99 = 9801 (two 2 digit numbers gives maximum of 4 digits)
999 * 999 = 998001 (two 3 digit numbers gives maximum of 6 digits)
9999 * 9999 = 99980001 (4 digits -> 8 digits)
以此类推...二进制完全一样。这就是为什么输出是输入大小的 (2*N) 位。
但是,如果您的数字较小,则结果将适合相同数量的数字,作为因数:
3 * 3 = 9
10 * 9 = 90
100 * 99 = 990
等等。所以如果你的数字足够小,那么结果将是 32 位。当然,正如 Paebbels 已经写的那样,结果将至少是信号的重要部分。
正如 J.H.Bonarius 已经指出的那样,如果您的输入不是整数,而是定点数,那么您将不得不进行 post 移位。如果是这种情况,请在评论中写下,我会解释该怎么做。