Booth Multiplication Algorithm

1.5k views Asked by At

I'm new to VHDL and am trying to code up Booth's Multiplication Algorithm. I'm using XILINX and when I synthesize my code, I end up with a lot of warnings:

  • Upper is assigned but never used,
  • Product is used but never assigned,
  • LowerPrevLSB is assigned but never used,
  • Lower is assigned but never used,
  • A_2sComp is assigned but never used,
  • Z has a constant value of 0,
  • Product has a constant value of 0.

I thought I assigned and wrote the code correctly, but evidently I am not. Any advice and help would be appreciated.

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

There are 1 answers

0
Jonathan Drolet On BEST ANSWER

In VHDL, successive assignments to the same signal in a process overrides previous assignments, thus:

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));

The first assignments, in the if block, is completely ignored. If you look at your code, assignments to Product, Upper and Lower are overridden.

I suggest you simulate your design before synthesizing your design with Xilinx. It will be much easier to test and debug. For instance, your counter signal is never reset, and will count up to 2^31-1, then wrap to -2^31. What will happen to your design in those cases? Simulation would point out these error easily, leave synthesis for later!