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

时间:2017-02-12 16:05:10

标签: 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);
              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;

现在,测试用例如下: A = 5,B = -3,给予0加上它们,1减去。 A = 6,B = 2,工作方式大致相同。

现在,鉴于数字已签名,当然,它们是两个补码,结果也是如此。但是,我只能在添加6(0110)和2(0010)的情况下检测溢出,给出-8(1000),这显然是4位的溢出情况。但是,当做5 - ( - 3)时,结果大致相同,1000,但由于我给出了两个不同符号的数字,我无法使用我的方法检测溢出。

我的老师建议我们根据sel的值改变B的符号 - 我试过像b&lt; = b +&#34; 1000&#34;基于此,但没有帮助,我不知道其他方式,对语言不熟悉。我该怎么做才能获得合适的节目?谢谢。

1 个答案:

答案 0 :(得分:0)

首先:

use IEEE.numeric_std.all;

不要那样做。特别是如果你想要签名的数字。正常使用是:

std_logic_vector

之后,您应该将inout转换为所需的数据类型,例如'签名',用于正确的算术。

其次,请勿使用in。双向分配VHDL不太好。使用outlibrary 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;

所以结合上面的内容,你可以做(​​n.b。不是最好的代码):

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;

您可以使用测试平台测试:

{{1}}