在4位加法器/减法器(VHDL)中实现溢出检查

在4位加法器/减法器(VHDL)中实现溢出检查,vhdl,fpga,Vhdl,Fpga,我是VHDL新手(3周),最近的作业中有一个问题,涉及在一个简单的4位加法器中实现溢出检查: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity add_sub_4bit is Port ( a : in STD_LOGIC_VECTOR(3 downto 0); b : inout STD_LOGIC_VECTOR(3 downto 0)

我是VHDL新手(3周),最近的作业中有一个问题,涉及在一个简单的4位加法器中实现溢出检查:

    library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity add_sub_4bit is
    Port ( a : in  STD_LOGIC_VECTOR(3 downto 0);
           b : inout  STD_LOGIC_VECTOR(3 downto 0);
              sel: in STD_LOGIC );
           --sum : inout  STD_LOGIC_VECTOR(3 downto 0) 
end add_sub_4bit;

architecture Behavioral of add_sub_4bit is
signal localflow : STD_LOGIC;
signal localsum : STD_LOGIC_VECTOR (3 downto 0);

begin
    localsum <= a + b when sel = '1'
    else
    a - b;
process(a,b,localsum) begin
    if a(3) = '0' AND b(3) = '0' AND localsum(3) = '1' then
        localflow <= '1'; 
    elsif  a(3) = '1' AND b(3) = '1' AND localsum(3) = '0' then
        localflow <='1';
    else
        localflow <='0';
    end if;
end process;
end Behavioral;
IEEE库;
使用IEEE.STD_LOGIC_1164.ALL;
使用IEEE.STD_LOGIC_UNSIGNED.ALL;
实体add_sub_4bit为
端口(a:标准逻辑向量(3到0);
b:输入标准逻辑向量(3到0);
sel:标准逻辑中);
--总和:输入标准逻辑向量(3到0)
结束添加子4位;
add_sub_4bit的架构是
信号本地流:标准逻辑;
信号局部和:标准逻辑向量(3到0);
开始
localsum首先:

use IEEE.STD_LOGIC_UNSIGNED.ALL;
不要那样做。特别是如果你想要签名的话。通常使用的是:

use IEEE.numeric_std.all;
之后,您应该将
std_logic_vector
转换为所需的数据类型,例如“signed”,以获得正确的算法

其次,不要使用
inout
。VHDL不太适合双向赋值。使用
输入
输出

因此,结合以上内容,您可以执行以下操作(注意,不是最好的代码):

IEEE库;
使用IEEE.STD_LOGIC_1164.ALL;
使用IEEE.numeric_std.ALL;
实体add_sub_4bit为
港口(
a:标准逻辑向量(3到0);
b:标准逻辑向量(3到0);
sel:标准逻辑中;
求和:输出标准逻辑向量(3到0);
溢出:输出标准逻辑
);
结束添加子4位;
add_sub_4bit的架构是
信号本地流:标准逻辑;
信号locala、localb、localsum:有符号(4到0);--比输入多一点
信号求和:标准逻辑向量(4到0);
开始

HW减法中的locala将二者的补码b(不是b+1)相加,+1使用进位。当进行减法运算时,您应该使用实际b加法器操作数的符号来进行溢出,这将是
opb_sign Hi,您的建议奏效了-我保留了相同的程序,带有一个附加的mux。谢谢!
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;

entity add_sub_4bit is
    Port (
        a : in  STD_LOGIC_VECTOR(3 downto 0);
        b : in  STD_LOGIC_VECTOR(3 downto 0);
        sel: in STD_LOGIC;
        sum : out  STD_LOGIC_VECTOR(3 downto 0);
        overflow : out std_logic
        );
end add_sub_4bit;

architecture Behavioral of add_sub_4bit is
signal localflow : STD_LOGIC;
signal locala, localb, localsum : signed(4 downto 0); -- one bit more then input
signal sumout : std_logic_vector(4 downto 0);

begin
    locala <= resize(signed(a), 5);
    localb <= resize(signed(b), 5);
    localsum <= locala + localb when sel = '1' else locala - localb;
    -- overflow occurs when bit 3 is not equal to the sign bit(4)
    localflow <= '1' when localsum(3) /= localsum(4) else '0';
    -- convert outputs
    sumout <= std_logic_vector(localsum);
    --outputs
    sum <= sumout(4)&sumout(2 downto 0);
    overflow <= localflow;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;

entity add_sub_4bit_tb is
end add_sub_4bit_tb;

architecture Behavioral of add_sub_4bit_tb is
signal sel : std_logic_vector(0 downto 0);
signal a, b, sum : std_logic_vector(3 downto 0);

begin
    uut: entity work.add_sub_4bit
    port map (a, b, sel(0), sum);

    test: process
    begin
        for sel_o in 0 to 1 loop
            sel <= std_logic_vector(to_signed(sel_o, 1));
            for a_o in -8 to 7 loop
                a <= std_logic_vector(to_signed(a_o, 4));
                for b_o in -8 to 7 loop
                    b <= std_logic_vector(to_signed(b_o, 4));
                    wait for 1 ns;
                end loop;
            end loop;
        end loop;
        wait;
    end process;
end Behavioral;