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 位而导致精度下降,或者我的代码很糟糕。

您的代码有一些问题:

  1. next_statestate 不属于敏感列表
  2. 写法CLK'event and CLK = '1'应该换成rising_edge(CLK)
  3. state <= state; 没有效果,并导致一些工具(如 ISE)误读模式。删除它。
  4. 在运算符周围放置空格没有坏处,但会提高可读性。
  5. 为什么你期望 a * b 的结果在 30 到 61 位而不是 0 到 31 位?
  6. statenext_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 移位。如果是这种情况,请在评论中写下,我会解释该怎么做。