I am multiplying the following numbers contained in registers A and B respectively using the booth multiplier algorithm: 308 and 165. The result is stored into zlo and zhi, where zlo is the lower 32 bits and zhi is the upper 32 bits. Here is the VHDL code:
variable M : std_logic_vector(64 downto 0);
variable S : std_logic_vector(64 downto 0);
variable P : std_logic_vector(64 downto 0);
-- Input A is in most significant bits of M
M(64 downto 33) := A(31 downto 0);
M(32 downto 0) := B"00000000_00000000_00000000_00000000_0";
-- -Input A is in most significant bits of S
S(64 downto 33) := std_logic_vector(NOT signed(A) + 1);
S(32 downto 0) := B"00000000_00000000_00000000_00000000_0";
-- P contains the product
P(64 downto 33) := B"00000000_00000000_00000000_00000000";
P(32 downto 1) := B(31 downto 0);
P(0) := '0';
-- check the last two bits and perform appropriate operation and shift
for i in 0 to 31 loop
if P(1 downto 0) = "01" then
P(64 downto 0) := std_logic_vector(signed(P) + signed(M));
elsif P(1 downto 0) = "10" then
P(64 downto 0) := std_logic_vector(signed(P) + signed(S));
end if;
P := std_logic_vector(signed(P) srl 1);
end loop;
zhi <= P(64 downto 33);
zlo <= P(32 downto 1);
The result of the waveform in ModelSim is shown below. As you can see 308 is loaded onto the bus, followed by 165. The result, 50820 is then stored on the bus (zlo), and then a 1 is stored on the bus (zhi). Why is there a 1? 50820 doesn't go into the upper 32 bits.
Hmmm, When I copied you code, it also did not work for me. So I cleaned it up a lot, and now it works... But I don't know what I changed which made it to work. Maybe someone else can help? It's probably has to do with the arithmetic.
library ieee; use ieee.std_logic_1164.all;
entity booth_mult is
generic(
nr_of_bits : positive := 32
);
port(
clk : in std_logic;
A : in integer;
B : in integer;
zhi : out std_logic_vector(nr_of_bits-1 downto 0);
zlo : out std_logic_vector(nr_of_bits-1 downto 0)
);
end entity booth_mult;
library ieee;
use ieee.numeric_std.all;
architecture behavior of booth_mult is
signal M : signed((2*nr_of_bits) downto 0) := (others => '0');
signal S : signed((2*nr_of_bits) downto 0) := (others => '0');
signal P : signed((2*nr_of_bits) downto 0) := (others => '0');
signal index : natural := 0;
begin
-- check the last two bits and perform appropriate operation and shift
clk_booth : process(clk)
variable P_temp : signed(P'range);
begin
if rising_edge(clk) then
if index = 0 then
M((2*nr_of_bits) downto nr_of_bits+1) <= to_signed(A, nr_of_bits);
S((2*nr_of_bits) downto nr_of_bits+1) <= to_signed(-A, nr_of_bits);
P(nr_of_bits downto 1) <= to_signed(B, nr_of_bits);
elsif index < (nr_of_bits+1) then
P_temp := P;
if P(1 downto 0) = "01" then
P_temp := P + M;
elsif P(1 downto 0) = "10" then
P_temp := P + S;
end if;
P <= shift_right(P_temp, 1);
end if;
index <= index + 1;
end if;
end process;
zhi <= std_logic_vector(P((2*nr_of_bits) downto nr_of_bits+1));
zlo <= std_logic_vector(P(nr_of_bits downto 1));
end architecture;
and testbench
entity booth_mult_tb is
end entity booth_mult_tb;
library ieee;
use ieee.std_logic_1164.all;
architecture behavior of booth_mult_tb is
signal clk : std_logic := '0';
constant nr_of_bits : positive := 32;
constant A : integer := 308;
constant B : integer := 165;
signal zhi : std_logic_vector(nr_of_bits-1 downto 0);
signal zlo : std_logic_vector(nr_of_bits-1 downto 0);
begin
dut : entity work.booth_mult
generic map(
nr_of_bits => nr_of_bits
)
port map(
clk => clk,
A => A,
B => B,
zhi => zhi,
zlo => zlo
);
clk_proc : process
begin
loop
clk <= '0', '1' after 1 ns;
wait for 2 ns;
end loop;
end process;
end architecture;