Booth乘法算法

时间:2015-06-16 14:23:08

标签: algorithm vhdl multiplication

我是VHDL的新手,正在尝试编写Booth的乘法算法。我正在使用XILINX,当我合成代码时,我最终会收到很多警告:

  • Upper已分配,但从未使用过,
  • Product已使用,但从未分配过,
  • LowerPrevLSB已分配,但从未使用过,
  • Lower已分配,但从未使用过,
  • A_2sComp已分配,但从未使用过,
  • Z的常量值为0,
  • Product的常量值为0.

我以为我分配并正确编写了代码,但显然我不是。任何建议和帮助将不胜感激。

library IEEE;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_arith.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

-- X * Y = Z
entity BoothMultiplier is
    generic
    (
        numBits_X : integer := 8;
        numBits_Y : integer := 8
    );
    port
    (
        CLK : in std_logic;
        X : in std_logic_vector((numBits_X - 1) downto 0);
        Y : in std_logic_vector((numBits_Y - 1) downto 0);
        Z : out std_logic_vector((numBits_X + numBits_Y - 1) downto 0)  
    );

end BoothMultiplier;

architecture Behavioral of BoothMultiplier is

    -- Two's Complement Function
    function TwosComplement(inputNum : std_logic_vector) return std_logic_vector;

    function TwosComplement(inputNum : std_logic_vector) return std_logic_vector is
        variable temp : std_logic_vector(inputNum'range);
        begin
            temp := (not inputNum) + 1;
            return temp;
    end TwosComplement;
    -- End Two's Complement Function

    -- MIN Function
    function MIN(Left, Right : integer) return integer;

    function MIN(Left, Right : integer) return integer is
    begin
        if Left < Right then return Left;
        else return Right;
        end if;
    end Min;
    -- End MIN Function

    -- MAX Function
    function MAX(Left, Right : integer) return integer;

    function MAX(Left, Right : integer) return integer is
    begin
        if Left > Right then return Left;
        else return Right;
        end if;
    end MAX;
    -- End MAX Function

    -- Signals
    signal Upper : std_logic_vector(MAX(numBits_X, numBits_Y) - 1 downto 0)
                    := (others => '0');
    signal Lower : std_logic_vector(MIN(numBits_X, numBits_Y) - 1 downto 0)
                    := (others => '0');
    signal LowerPrevLSB : std_logic := '0';
    signal Product : std_logic_vector(numBits_X + numBits_Y - 1 downto 0)
                        := (others => '0');
    signal A, A_2sComp : std_logic_vector(MAX(numBits_X, numBits_y) - 1 downto 0)
                := (others => '0');
    signal counter : integer := 0;
    -- End Signals

begin

    assert Z'length = (X'length + Y'length) report "Bad Product Length" severity failure;

    Lower <= X when (numBits_X <= numBits_Y) else Y;
    A <= X when (numBits_X > numBits_Y) else Y;
    A_2sComp <= TwosComplement(A);

    process(CLK)
    begin
        if rising_edge(CLK) then
            if (Lower(0) = '0' and LowerPrevLSB = '1') then
                Upper <= Upper + A;
            elsif (Lower(0) = '1' and LowerPrevLSB = '0') then
                Upper <= Upper + A_2sComp;
            end if;
            LowerPrevLSB <= Lower(0);
            Product <= Upper & Lower;
            for i in 0 to Product'length - 2 loop
                Product(i) <= Product(i+1);
            end loop;
            Product(Product'length-1) <= Product(Product'length-1);
            Upper <= Product(Product'length - 1 downto MIN(numBits_X, numBits_Y));
            Lower <= Product(MIN(numBits_X, numBits_Y) - 1 downto 0);
            counter <= counter + 1;
            if (counter = MIN(numBits_X, numBits_Y)) then
                Z <= Product;
            end if;
        end if;
    end process;

end Behavioral;

1 个答案:

答案 0 :(得分:2)

在VHDL中,对流程中相同信号的连续分配会覆盖先前的分配,因此:

if (Lower(0) = '0' and LowerPrevLSB = '1') then
    Upper <= Upper + A;
elsif (Lower(0) = '1' and LowerPrevLSB = '0') then
    Upper <= Upper + A_2sComp;
end if;
...
Upper <= Product(Product'length - 1 downto MIN(numBits_X, numBits_Y));

if块中的第一个分配完全被忽略。如果您查看代码,则会覆盖ProductUpperLower的分配。

我建议您在使用Xilinx合成设计之前模拟您的设计。它将更容易测试和调试。例如,您的counter信号永远不会被重置,并且将计数到2 ^ 31-1,然后换行到-2 ^ 31。在这些情况下,您的设计会发生什么?模拟会很容易地指出这些错误,为以后留下合成!