8位阵列乘法器VHDL(输出错误)

8 bits Array Multiplier VHDL (output wrong)

我正在尝试在 VHDL 中制作一个 8 位数组乘法器,我正在使用数组乘法器的标准架构来执行此操作,我有一个 BDF 文件接收 A(被乘数)和 B(乘数),在这个 BDF 文件中有一个名为 "adder" 的块,它从 A 和 B 的乘积中求和。我在求和输出方面遇到问题,它显示的数字与正确值相比要低得多。

上图是我的主要BDF

上图显示了从 and_arrays 到加法器的去连接。

加法器代码:

LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
use IEEE.std_logic_arith.ALL;
use IEEE.numeric_std.ALL;

ENTITY adder IS
  PORT (i_IN0   : IN  STD_LOGIC_VECTOR(7 downto 0);-- data input
        i_IN1   : IN  STD_LOGIC_VECTOR(7 downto 0);-- data input
        i_IN2   : IN  STD_LOGIC_VECTOR(7 downto 0);-- data input
        i_IN3   : IN  STD_LOGIC_VECTOR(7 downto 0);-- data input
        i_IN4   : IN  STD_LOGIC_VECTOR(7 downto 0);-- data input
        i_IN5   : IN  STD_LOGIC_VECTOR(7 downto 0);-- data input
        i_IN6   : IN  STD_LOGIC_VECTOR(7 downto 0);-- data input
        i_IN7   : IN  STD_LOGIC_VECTOR(7 downto 0);-- data input
        o_Q     : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
        o_COUT  : OUT STD_LOGIC);-- data output  
END adder;

architecture arch1 of adder is 
begin 
    process(i_IN0, i_IN1, i_IN2, i_IN3, i_IN4, i_IN5, i_IN6, i_IN7)
      variable soma:std_logic_vector(14 downto 0);
      variable aux0:std_logic_vector(14 downto 0);
      variable aux1:std_logic_vector(14 downto 0);
      variable aux2:std_logic_vector(14 downto 0);
      variable aux3:std_logic_vector(14 downto 0);
      variable aux4:std_logic_vector(14 downto 0);
      variable aux5:std_logic_vector(14 downto 0);
      variable aux6:std_logic_vector(14 downto 0);
      variable aux7:std_logic_vector(14 downto 0);
      variable c:std_logic; -- carry in
      BEGIN
         aux0(7 downto 0) := i_IN0; aux0(14 downto 8) := "0000000"; -- here i'm trying to shift the 8 nbit input value
         aux1(0) := '0'; aux1(8 downto 1) := i_IN1; aux1(14 downto 9) := "000000"; -- to a 15 bit value to the sums
         aux2(1 downto 0) := "00";aux2(9 downto 2) := i_IN2; aux2(14 downto 10) := "00000"; -- looking to the array multiplier
         aux3(2 downto 0) := "000";aux3(10 downto 3) := i_IN3; aux3(14 downto 11) := "0000"; -- architecture, it seem to be
         aux4(3 downto 0) := "0000";aux4(11 downto 4) := i_IN4; aux4(14 downto 12) := "000"; -- correct
         aux5(4 downto 0) := "00000";aux5(12 downto 5) := i_IN5; aux5(14 downto 13) := "00";
         aux6(5 downto 0) := "000000"; aux6(13 downto 6) := i_IN6; aux6(14) := '0';
         aux7(6 downto 0) := "0000000"; aux7(14 downto 7) := i_IN7;
    -- below the loop that make the sums bit-in-bit, i've addapted this code from a 8 bit adder
         c := '0';
            for i in 0 to 14 loop
                soma(i) := aux0(1) xor aux1(i) xor aux2(i) xor aux3(i) xor aux4(i) xor aux5(i) xor aux6(i) xor aux7(i) xor c;
                c := (aux0(i) and aux1(i) and aux2(i) and aux3(i) and aux4(i) and aux5(i) and aux6(i) and aux7(i)) or ((aux0(i) xor aux1(i) xor aux2(i) xor aux3(i) xor aux4(i) xor aux5(i) xor aux6(i) xor aux7(i)) and c);
            end loop;
            o_COUT <= c; 
            o_Q(15) <= c; -- carry out atribuition to the last bit of the vector
            o_Q(14 downto 0) <= soma;
    end process;
end arch1;

和数组代码:

LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;
use IEEE.std_logic_arith.ALL;

ENTITY and_array IS
  PORT (i_MULTIPLICANDO   : IN  STD_LOGIC_VECTOR(7 downto 0);-- data input
        i_MULTIPLICADOR   : IN  STD_LOGIC;-- data input
        o_Q   : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));-- data output
END and_array;

ARCHITECTURE arch_1 OF and_array IS
    BEGIN
        GEN_REG: 
        FOR i IN 0 TO 7 GENERATE
            o_Q(i) <= i_MULTIPLICADOR and i_MULTIPLICANDO(i); 
        END GENERATE GEN_REG;
END arch_1;

我已经对这两个块进行了仿真,和数组块工作得很好,但是错误出现在加法器仿真中,在仿真图像下方:

我正在模拟以下输入:

        Multiplicand = 1 1 1 1 0 1 0 1 (245 dec)
        Multiplier   = 1 0 1 0 1 1 1 1 (175 dec)

这个产品的正确值是42785,在我的模拟中出现24899

我在加法器中使用以下逻辑求和:

                   1 1 1 1 0 1 0 1
                   1 0 1 0 1 1 1 1
                   -----------------
      x x x x x x x 1 1 1 1 0 1 0 1     p1
      x x x x x x 1 1 1 1 0 1 0 1 x     p2
      x x x x x 1 1 1 1 0 1 0 1 x x     p3
      x x x x 1 1 1 1 0 1 0 1 x x x     p4 
      x x x 0 0 0 0 0 0 0 0 x x x x     p5
      x x 1 1 1 1 0 1 0 1 x x x x x     p6
      x 0 0 0 0 0 0 0 0 x x x x x x     p7
      1 0 1 0 1 1 1 1 x x x x x x x     p8
_________________________________________

在加法器块中,我已经将 0 的所有 "X's" 更改为总和(如移位)。在加法器块的循环中,p1 到 p8 的总和是逐位计算的。可能是这个循环或进位的错误,但我尝试从多种形式来做,但总是出错。

有人知道如何解决这个问题吗?

下面是主电路抽象图:

这个问题的解决方案是使用半加器和全加器代替问题中上面显示的加法器。

使用了以下逻辑:

总共使用了:

64 个与门; 8 个半加器; 48 个全加器。

我认为主要问题在于用于求和的按位代码:

        for i in 0 to 14 loop
            soma(i) := aux0(1) xor aux1(i) xor aux2(i) xor aux3(i) xor aux4(i) xor aux5(i) xor aux6(i) xor aux7(i) xor c;
            c := (aux0(i) and aux1(i) and aux2(i) and aux3(i) and aux4(i) and aux5(i) and aux6(i) and aux7(i)) or ((aux0(i) xor aux1(i) xor aux2(i) xor aux3(i) xor aux4(i) xor aux5(i) xor aux6(i) xor aux7(i)) and c);
        end loop;

c 这里只有一位,作为九项的进位(八位辅助位和进位,所以当我们充分扩展进位时,这会反馈产生更多的项)是相当不足的。如果我们假设这九位就足够了,您仍然会得到最多 9 的值,这需要四位二进制,因此至少需要三个进位。一旦您拥有三个以上的任期,就会发生这种情况;全加器使用其输出的所有值从 1+1+1 到 2+1(一位具有更高的权重)求和。由于这是一种缩减,它们可以分层链接,但更大的加法器必须使用更多的输出位(例如,一个 5 输入加法器可以产生 2+2+1,一个 7 位加法器可以产生 4+2+1 );如果我们计算阵列乘法器示意图中列之间的进位线,我们就会看到这一点。中间列的进位数与因子中的位数一样多。