对于64位寄存器,布斯乘法器将高32位置1

时间:2017-03-06 15:58:20

标签: vhdl modelsim

我使用booth乘数算法分别将寄存器A和B中包含的以下数字相乘:308和165.结果存储在zlo和zhi中,其中zlo是低32位,zhi是高32位。这是VHDL代码:

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

ModelSim中波形的结果如下所示。如您所见,308被加载到总线上,然后是165.结果,50820然后存储在总线(zlo)上,然后将1存储在总线(zhi)上。为什么有1? 50820不会进入高32位。

enter image description here

1 个答案:

答案 0 :(得分:1)

嗯,当我复制你的代码时,它对我来说也不起作用。所以我清理了很多,现在它可以工作......但我不知道我改变了什么让它发挥作用。也许别人可以帮忙?这可能与算术有关。

图书馆; 使用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;

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