Vhdl 乘法单元在加法过程中跳过溢出位

Vhdl 乘法单元在加法过程中跳过溢出位,vhdl,multiplication,waveform,Vhdl,Multiplication,Waveform,我根据“左移,加法”原理制作了一个简单的乘法单元(16位操作数,32位结果),当需要考虑溢出位时,它在加法器部分不能正常工作 我知道应该做什么(做一个17位的求和向量,并在乘积中添加一个溢出位),但我不知道如何实现它。在下面,您可以找到波形文件,其中显示了错误位置和MPU.vhd文件。屏幕截图没有显示最终结果,但很明显,它是错误的。如何让它与大16位数字一起工作 MPU.vhd library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeri

我根据“左移,加法”原理制作了一个简单的乘法单元(16位操作数,32位结果),当需要考虑溢出位时,它在加法器部分不能正常工作

我知道应该做什么(做一个17位的求和向量,并在乘积中添加一个溢出位),但我不知道如何实现它。在下面,您可以找到波形文件,其中显示了错误位置和MPU.vhd文件。屏幕截图没有显示最终结果,但很明显,它是错误的。如何让它与大16位数字一起工作

MPU.vhd

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all; 

entity MPU_OP is
    port (C: in std_logic;    -- Clock
    RST : in std_logic;       -- Reset
    LAB : in std_logic;       -- Load A and B, P <= 0
    SHIFT : in std_logic;     -- Shift B and P
    OUTHL : in std_logic;     -- Output most(0) or least(1) significant word P
    DA : in std_logic_vector(15 downto 0);   -- Data A
    DB : in std_logic_vector(15 downto 0);   -- Data B
    DP : out std_logic_vector(15 downto 0)); -- Word result P
end entity;

architecture BEH of MPU_OP is
signal A, B : std_logic_vector(15 downto 0); -- A, B
signal Pi, Ai, Si : integer;
signal S : signed(15 downto 0); -- Sum 
signal S2 : signed(16 downto 0);
signal P : signed(31 downto 0); -- Product

begin 
    RG_A : process(C, RST) -- Register for A
    begin
        if (RST = '1') then
            A <= X"0000";
        elsif rising_edge(C) then                                        `-- Reg_A`
            if LAB = '1' then
                A <= DA;
            end if;
        end if;
    end process;
    
    RG_B : process(C, RST) -- Register for B
    begin
        if (RST = '1') then
            B <= X"0000";
        elsif rising_edge(C) then
            if LAB = '1' then
                B <= DB;
            elsif (SHIFT = '1') then
                B <= std_logic_vector(shift_left(unsigned(B), 1));       `-- Reg_B`
            end if;
        end if;
    end process;    
    
    Adder : process (C)
    begin
        Pi <= to_integer(unsigned(std_logic_vector(P(15 downto 0))));
        Ai <= to_integer(unsigned(A));

        if B(15) = '1' then
            S <= P(15 downto 0) + signed(A);                             -- Adder
            Si <= Pi + Ai;
        else
            S <= P(15 downto 0);    
            Si <= Pi;
        S2 <= to_signed(Si, S2'length); 
        end if;
    end process;

    
    RG_P : process (C, RST, P) -- Register for P   
    begin
        if RST = '1' then 
            P <= X"00000000";
        elsif rising_edge(C) then
            if LAB = '1' then
                P <= X"00000000";
            elsif SHIFT = '1' then
                if B /= "1000000000000000" then
                    P <= P(30 downto 16) & S & '0'; -- Shift LEFT        `-- Reg_Product`
                else
                    P <= P(31 downto 16) & S;
                end if;
            end if;
        end if;
    end process;
    
    MUX_P : DP <= std_logic_vector(P(15 downto 0)) when OUTHL = '1' else
        std_logic_vector(P(31 downto 16));
    
end architecture;
        
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all; 

entity MPU_TEST is
    port (C: in std_logic;
    LAB : in std_logic;
    SHIFT : in std_logic;
    DA : in std_logic_vector(15 downto 0);
    DB : in std_logic_vector(15 downto 0);
    DP : out std_logic_vector(31 downto 0));
end entity;

architecture BEH of MPU_TEST is
signal A, B : std_logic_vector(15 downto 0);
signal S : signed(15 downto 0);
signal P : signed(31 downto 0); 

begin 
    RG_A : process(C)
    begin
        if rising_edge(C) then
            if LAB = '1' then
                A <= DA;
            end if;
        end if;
    end process;
    
    RG_B : process(C) 
    begin 
        if rising_edge(C) then
            if LAB = '1' then
                B <= DB;
            elsif (SHIFT = '1') then
                B <= std_logic_vector(shift_left(unsigned(B), 1));
            end if;
        end if;
    end process;    
    
    Adder : process (C)
    begin
        if B(15) = '1' then
            S <= P(15 downto 0) + signed(A);
        else
            S <= P(15 downto 0);    
        end if;
    end process;

    
    RG_P : process (C, P) 
    begin 
        if rising_edge(C) then
            if LAB = '1' then
                P <= X"00000000";
            elsif SHIFT = '1' then
                if B /= "1000000000000000" then
                    P <= P(30 downto 16) & S & '0';
                else
                    P <= P(31 downto 16) & S;
                end if;
            end if;
        end if;
    end process;
    
    DP <= std_logic_vector(P);
end architecture;
            
library ieee;
use ieee.NUMERIC_STD.all;
use ieee.std_logic_1164.all;

entity mpu_test_tb is
end mpu_test_tb;

architecture TB_ARCHITECTURE of mpu_test_tb is
    component mpu_test
    port(
        C : in STD_LOGIC;
        LAB : in STD_LOGIC;
        SHIFT : in STD_LOGIC;
        DA : in STD_LOGIC_VECTOR(15 downto 0);
        DB : in STD_LOGIC_VECTOR(15 downto 0);
        DP : out STD_LOGIC_VECTOR(31 downto 0) );
    end component;


    signal C : STD_LOGIC;
    signal LAB : STD_LOGIC;
    signal SHIFT : STD_LOGIC;
    signal DA : STD_LOGIC_VECTOR(15 downto 0);
    signal DB : STD_LOGIC_VECTOR(15 downto 0);

    signal DP : STD_LOGIC_VECTOR(31 downto 0);


begin


    UUT : mpu_test
        port map (
            C => C,
            LAB => LAB,
            SHIFT => SHIFT,
            DA => DA,
            DB => DB,
            DP => DP
        );

    process
    begin 
        C <= '0';
        wait for 5 ns;
        C <= '1';
        wait for 5 ns;
    end process;
    
    LAB <= '1', '0' after 10 ns;
    SHIFT <= '0', '1' after 10 ns, '0' after 170 ns;
    DA <= X"1234";
    DB <= X"F234";
    
end TB_ARCHITECTURE;
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all; 

entity MPU_TEST is
    port (C: in std_logic;
    LAB : in std_logic;
    SHIFT : in std_logic;
    DA : in std_logic_vector(15 downto 0);
    DB : in std_logic_vector(15 downto 0);
    DP : out std_logic_vector(31 downto 0));
end entity;

architecture BEH of MPU_TEST is
signal A, B : std_logic_vector(15 downto 0);
signal S : signed(16 downto 0);
signal P : signed(31 downto 0); 

begin 
    RG_A : process(C)
    begin
        if rising_edge(C) then
            if LAB = '1' then
                A <= DA;
            end if;
        end if;
    end process;
    
    RG_B : process(C) 
    begin 
        if rising_edge(C) then
            if LAB = '1' then
                B <= DB;
            elsif (SHIFT = '1') then
                B <= std_logic_vector(shift_left(unsigned(B), 1));
            end if;
        end if;
    end process;    
    
    Adder : process (C)
    begin
        if B(15) = '1' then
            S <= P(16 downto 0) + signed(A);
        else
            S <= P(16 downto 0);    
        end if;
    end process;

    
    RG_P : process (C, P) 
    begin 
        if rising_edge(C) then
            if LAB = '1' then
                P <= X"00000000";
            elsif SHIFT = '1' then
                if B /= "1000000000000000" then
                    P <= P(30 downto 17) & S & '0';
                else
                    P <= P(31 downto 17) & S;
                end if;
            end if;
        end if;
    end process;
    
    DP <= std_logic_vector(P);
end architecture;
    
IEEE库;
使用IEEE.std_logic_1164.all;
使用IEEE.numeric_std.all;
实体MPU_OP是
端口(C:标准_逻辑中;--时钟
RST:在标准逻辑中;--复位

实验室:在std_logic;--Load A和B中,P

我成功地使其工作。我在移动乘积时显式地添加了“0”,并在S中添加了第17位以保留溢出位。此外,信号范围也已更改,应存储在乘积和求和中。结果是下面的代码

MPU.vhd

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all; 

entity MPU_OP is
    port (C: in std_logic;    -- Clock
    RST : in std_logic;       -- Reset
    LAB : in std_logic;       -- Load A and B, P <= 0
    SHIFT : in std_logic;     -- Shift B and P
    OUTHL : in std_logic;     -- Output most(0) or least(1) significant word P
    DA : in std_logic_vector(15 downto 0);   -- Data A
    DB : in std_logic_vector(15 downto 0);   -- Data B
    DP : out std_logic_vector(15 downto 0)); -- Word result P
end entity;

architecture BEH of MPU_OP is
signal A, B : std_logic_vector(15 downto 0); -- A, B
signal Pi, Ai, Si : integer;
signal S : signed(15 downto 0); -- Sum 
signal S2 : signed(16 downto 0);
signal P : signed(31 downto 0); -- Product

begin 
    RG_A : process(C, RST) -- Register for A
    begin
        if (RST = '1') then
            A <= X"0000";
        elsif rising_edge(C) then                                        `-- Reg_A`
            if LAB = '1' then
                A <= DA;
            end if;
        end if;
    end process;
    
    RG_B : process(C, RST) -- Register for B
    begin
        if (RST = '1') then
            B <= X"0000";
        elsif rising_edge(C) then
            if LAB = '1' then
                B <= DB;
            elsif (SHIFT = '1') then
                B <= std_logic_vector(shift_left(unsigned(B), 1));       `-- Reg_B`
            end if;
        end if;
    end process;    
    
    Adder : process (C)
    begin
        Pi <= to_integer(unsigned(std_logic_vector(P(15 downto 0))));
        Ai <= to_integer(unsigned(A));

        if B(15) = '1' then
            S <= P(15 downto 0) + signed(A);                             -- Adder
            Si <= Pi + Ai;
        else
            S <= P(15 downto 0);    
            Si <= Pi;
        S2 <= to_signed(Si, S2'length); 
        end if;
    end process;

    
    RG_P : process (C, RST, P) -- Register for P   
    begin
        if RST = '1' then 
            P <= X"00000000";
        elsif rising_edge(C) then
            if LAB = '1' then
                P <= X"00000000";
            elsif SHIFT = '1' then
                if B /= "1000000000000000" then
                    P <= P(30 downto 16) & S & '0'; -- Shift LEFT        `-- Reg_Product`
                else
                    P <= P(31 downto 16) & S;
                end if;
            end if;
        end if;
    end process;
    
    MUX_P : DP <= std_logic_vector(P(15 downto 0)) when OUTHL = '1' else
        std_logic_vector(P(31 downto 16));
    
end architecture;
        
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all; 

entity MPU_TEST is
    port (C: in std_logic;
    LAB : in std_logic;
    SHIFT : in std_logic;
    DA : in std_logic_vector(15 downto 0);
    DB : in std_logic_vector(15 downto 0);
    DP : out std_logic_vector(31 downto 0));
end entity;

architecture BEH of MPU_TEST is
signal A, B : std_logic_vector(15 downto 0);
signal S : signed(15 downto 0);
signal P : signed(31 downto 0); 

begin 
    RG_A : process(C)
    begin
        if rising_edge(C) then
            if LAB = '1' then
                A <= DA;
            end if;
        end if;
    end process;
    
    RG_B : process(C) 
    begin 
        if rising_edge(C) then
            if LAB = '1' then
                B <= DB;
            elsif (SHIFT = '1') then
                B <= std_logic_vector(shift_left(unsigned(B), 1));
            end if;
        end if;
    end process;    
    
    Adder : process (C)
    begin
        if B(15) = '1' then
            S <= P(15 downto 0) + signed(A);
        else
            S <= P(15 downto 0);    
        end if;
    end process;

    
    RG_P : process (C, P) 
    begin 
        if rising_edge(C) then
            if LAB = '1' then
                P <= X"00000000";
            elsif SHIFT = '1' then
                if B /= "1000000000000000" then
                    P <= P(30 downto 16) & S & '0';
                else
                    P <= P(31 downto 16) & S;
                end if;
            end if;
        end if;
    end process;
    
    DP <= std_logic_vector(P);
end architecture;
            
library ieee;
use ieee.NUMERIC_STD.all;
use ieee.std_logic_1164.all;

entity mpu_test_tb is
end mpu_test_tb;

architecture TB_ARCHITECTURE of mpu_test_tb is
    component mpu_test
    port(
        C : in STD_LOGIC;
        LAB : in STD_LOGIC;
        SHIFT : in STD_LOGIC;
        DA : in STD_LOGIC_VECTOR(15 downto 0);
        DB : in STD_LOGIC_VECTOR(15 downto 0);
        DP : out STD_LOGIC_VECTOR(31 downto 0) );
    end component;


    signal C : STD_LOGIC;
    signal LAB : STD_LOGIC;
    signal SHIFT : STD_LOGIC;
    signal DA : STD_LOGIC_VECTOR(15 downto 0);
    signal DB : STD_LOGIC_VECTOR(15 downto 0);

    signal DP : STD_LOGIC_VECTOR(31 downto 0);


begin


    UUT : mpu_test
        port map (
            C => C,
            LAB => LAB,
            SHIFT => SHIFT,
            DA => DA,
            DB => DB,
            DP => DP
        );

    process
    begin 
        C <= '0';
        wait for 5 ns;
        C <= '1';
        wait for 5 ns;
    end process;
    
    LAB <= '1', '0' after 10 ns;
    SHIFT <= '0', '1' after 10 ns, '0' after 170 ns;
    DA <= X"1234";
    DB <= X"F234";
    
end TB_ARCHITECTURE;
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all; 

entity MPU_TEST is
    port (C: in std_logic;
    LAB : in std_logic;
    SHIFT : in std_logic;
    DA : in std_logic_vector(15 downto 0);
    DB : in std_logic_vector(15 downto 0);
    DP : out std_logic_vector(31 downto 0));
end entity;

architecture BEH of MPU_TEST is
signal A, B : std_logic_vector(15 downto 0);
signal S : signed(16 downto 0);
signal P : signed(31 downto 0); 

begin 
    RG_A : process(C)
    begin
        if rising_edge(C) then
            if LAB = '1' then
                A <= DA;
            end if;
        end if;
    end process;
    
    RG_B : process(C) 
    begin 
        if rising_edge(C) then
            if LAB = '1' then
                B <= DB;
            elsif (SHIFT = '1') then
                B <= std_logic_vector(shift_left(unsigned(B), 1));
            end if;
        end if;
    end process;    
    
    Adder : process (C)
    begin
        if B(15) = '1' then
            S <= P(16 downto 0) + signed(A);
        else
            S <= P(16 downto 0);    
        end if;
    end process;

    
    RG_P : process (C, P) 
    begin 
        if rising_edge(C) then
            if LAB = '1' then
                P <= X"00000000";
            elsif SHIFT = '1' then
                if B /= "1000000000000000" then
                    P <= P(30 downto 17) & S & '0';
                else
                    P <= P(31 downto 17) & S;
                end if;
            end if;
        end if;
    end process;
    
    DP <= std_logic_vector(P);
end architecture;
    
IEEE库;
使用IEEE.std_logic_1164.all;
使用IEEE.numeric_std.all;
实体MPU_测试为
端口(C:std_逻辑中;
实验室:标准逻辑;
移位:在标准逻辑中;
DA:标准逻辑向量(15到0);
DB:标准逻辑向量(15到0);
DP:out标准逻辑向量(31向下到0);
终端实体;
MPU_测试的架构BEH是
信号A、B:标准逻辑向量(15到0);
信号S:有符号(16至0);
信号P:已签名(31向下至0);
开始
RG_A:过程(C)
开始
如果上升沿(C),则
如果LAB='1',则

A提供A。你的读者可以复制波形吗?请注意,你的一些过程敏感度列表不完整。你的代码没有进行分析。你不能用严重的重音来括起注释。你真的想用C作为锁存启用而不是时钟吗?@user1155120我已经更新了代码,使其更简洁。我不熟悉VHDL,所以没有这是一个无符号乘数还是有符号乘数?