计算 ALU 中的溢出标志

Calculating the Overflow Flag in an ALU

首先,如果这不是 post 这个问题的正确位置,请原谅我,但我不确定应该去哪里。我目前正在使用 VHDL 在 Xilinx 中模拟 ALU。 ALU 具有以下输入和输出:

输入

产出

ALU 执行下面 table 中详述的操作:

我已经使用多路复用器和加法器实现了它,如下图所示:

我的问题是:

How do I calculate the value of the overflow flag, V?

我知道:

(not A(7) and not B(7) and Y(7)) or (A(7) and B(7) and not Y(7))

其中 A(7)B(7)Y(7)ABY.

但是我不知道如何在 VHDL 代码中逻辑地实现这一点——尤其是在进位的情况下。

如果两个正数相加得到负数,两个负数相加得到正数,就会发生溢出。也就是说,您需要比较操作数的 MSB 和答案。如果操作数的符号和答案的符号不匹配,则打开溢出标志。

编辑:这只适用于没有进位的情况。关于进位的添加,我也需要帮助。

您发布的解决方案

v <= (not A(7) and not B(7) and Y(7)) or (A(7) and B(7) and not Y(7))

对于有符号操作数的加法是正确的并且与进位无关。

EDIT 要将其也用于减法,您必须改用实际的加法器输入,即:

v <= (not add_A(7) and not add_B(7) and Y(7)) or (add_A(7) and add_B(7) and not Y(7))

以上将适用于加法和减法,独立于进位或借位。 (顺便说一下,对于真正的实现,你应该使用 add_Y 而不是 Y 来缩短关键路径。)

如果要对most-signifcant和位的carry-in和carry-out进行异或来实现,则必须计算最低7位的部分和第一的。这使您可以访问第 6 位的 carry-out,这是第 7 位的 carry-in。然后只需附加一个 full-adder 即可获得第 7 位和 carry-out。这是代码:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity adder_overflow is
  port (
    a  : in  unsigned(7 downto 0);
    b  : in  unsigned(7 downto 0);
    y  : out unsigned(7 downto 0);
    v  : out std_logic;
    co : out std_logic);
end;

architecture rtl of adder_overflow is
  signal psum   : unsigned(7 downto 0); -- partial sum
  signal c7_in  : std_logic;
  signal c7_out : std_logic;
begin

  -- add lowest 7 bits together
  psum <= ("0" & a(6 downto 0)) + b(6 downto 0);

  -- psum(7) is the carry-out of bit 6 and will be the carry-in of bit 7
  c7_in         <= psum(7);
  y(6 downto 0) <= psum(6 downto 0);

  -- add most-signifcant operand bits and carry-in from above together using a full-adder
  y(7)   <= a(7) xor b(7) xor c7_in;
  c7_out <= ((a(7) xor b(7)) and c7_in) or a(7);

  -- carry and overflow
  co <= c7_out;
  v  <= c7_in xor c7_out;
end rtl;

你的解决方案

(not A(7) and not B(7) and Y(7)) or (A(7) and B(7) and not Y(7))

及其下方的文字仅适用于有符号加法;减法是不正确的。两条规则是:

  1. 表达式 x+y+c 的有符号整数溢出(其中 c 为 0 或 1) 当且仅当 xy 具有相同符号且结果为符号与操作数相反(这是你的等式),并且
  2. 表达式 x-y-c 的有符号整数溢出(其中 c 再次为 0 或 1) 当且仅当 xy 具有相反的符号,并且符号结果的结果与 x 相反(或者等价地,与 y 相同)。

请注意,无论 carry/borrow 的值如何,这些都是正确的。您可以看到第一条规则不适用于简单的 4 位示例的减法:例如,4 减 (-4) 必须溢出,因为答案应该是 +8,这不能用 4 位表示。在二进制中,这是 0100 - 1100 = 1000。这是根据 (2) 而不是 (1) 的溢出。

好消息是 xor-ing 符号位的进位和符号位的进位始终有效 - 加法和减法都是正确的,无论是否有进位或 borrow-in, 所以你可以使用 Martin 的代码。

如果你要做很多算术,你应该得到亨利·沃伦 Hacker's Delight 的副本。他涵盖了所有这些,甚至更多。