【问题标题】:Implementing Overflow Checking in 4-bit Adder/Subtractor (VHDL)在 4 位加法器/减法器 (VHDL) 中实现溢出检查
【发布时间】:2017-02-21 21:37:41
【问题描述】:

我对 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 给 sel 相加,1 相减。 A=6,B=2,工作原理大致相同。

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

我的老师建议我们根据 sel 的值更改 B 的符号 - 我尝试了类似这样的方法,例如根据 sel 使 b

【问题讨论】:

  • 在硬件减法中添加 b 的补码(不是 b + 1),+ 1 使用进位。减法时,您应该使用实际 b 加法器操作数的符号进行溢出,即opb_sign &lt;= b(3) when sel = '1' else not b(3);。您可以将其显示为单独的多路复用器(选择器)或使用 XOR 将其折叠为术语 (b(3) xor not sel)。折叠原始溢出选择器也会得到localflow &lt;= a(3) xor b(3) xor not sel xor localsum(3); 不需要括号,XOR 是可交换的。而不是更高的优先级。
  • 您好,您的建议奏效了 - 我保留了相同的程序,但多了一个多路复用器。非常感谢!

标签: vhdl fpga


【解决方案1】:

首先:

use IEEE.STD_LOGIC_UNSIGNED.ALL;

不要那样做。特别是如果您希望对数字进行签名。正常使用是:

use IEEE.numeric_std.all;

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

其次,不要使用inout。 VHDL 在双向分配方面不太好。使用inout

所以结合以上,你可以做到(n.b.不是最好的代码):

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;

【讨论】:

    猜你喜欢
    • 2013-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多