Vhdl 乘法单元在加法过程中跳过溢出位
我根据“左移,加法”原理制作了一个简单的乘法单元(16位操作数,32位结果),当需要考虑溢出位时,它在加法器部分不能正常工作 我知道应该做什么(做一个17位的求和向量,并在乘积中添加一个溢出位),但我不知道如何实现它。在下面,您可以找到波形文件,其中显示了错误位置和MPU.vhd文件。屏幕截图没有显示最终结果,但很明显,它是错误的。如何让它与大16位数字一起工作 MPU.vhdVhdl 乘法单元在加法过程中跳过溢出位,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
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,所以没有这是一个无符号乘数还是有符号乘数?