【问题标题】:Calculating the Overflow Flag in an ALU计算 ALU 中的溢出标志
【发布时间】:2015-12-30 17:34:39
【问题描述】:

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

输入

  • AB:两个 8 位操作数
  • Ci:单位进位
  • Op:多路复用器的 4 位操作码

输出

  • :8位输出操作数
  • Co:单比特执行
  • V:溢出标志(有溢出为1,否则为0)
  • Z:零标志(如果为零,则为 1,否则为 0)
  • S:符号标志(如果 -ve 则为 1,如果 +ve 则为 0)

ALU 执行下表中详述的操作:

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

我的问题是:

如何计算溢出标志的值,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)的第8位 ABY

  • 在进位/借位的情况下,当且仅当最高有效位的进位和进位不同时才会发生溢出。

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

【问题讨论】:

标签: logic vhdl cpu


【解决方案1】:

您发布的解决方案

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

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

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

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 来缩短关键路径。)

如果您想通过对最高有效位的进位和进位进行异或来实现它,那么您必须首先计算最低 7 位的部分和。这使您可以访问第 6 位的进位,即第 7 位的进位。然后只需附加一个全加器即可获得第 7 位和进位。代码如下:

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;

【讨论】:

  • 看起来很棒!我的逻辑是 - 我不确定它是否与你的一致 - 我认为 V = 0 iff S = Co。否则,V = 1。是对的吗? (S 是 Y 的 MSB,Co 是进位)。
  • @LukeCollins 否。如果将“11111111”添加到“00000000”,则 S=1,V=0,Co = 0。
  • 啊...我明白了。谢谢回复。我似乎不明白你为什么使用 XOR - 你能澄清一下吗?
  • @LukeCollins 我的代码中有很多 XOR。你指的是哪一个?
  • 最后一行V的定义
【解决方案2】:

您的解决方案

(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)。

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

好消息是,对符号位进行异或运算,符号位的进位始终有效 - 对于加法和减法,无论是否有进位或借位,它都是正确的,所以你可以使用 Martin 的代码。

如果您要进行大量算术运算,您应该获得一份 Henry Warren 的Hacker's Delight。他涵盖了所有这些,甚至更多。

【讨论】:

    【解决方案3】:

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

    编辑:这只适用于没有进位的情况。在进行进位时,我也需要帮助。

    【讨论】:

    • 你会看到我已经在我的问题中包含了这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-18
    • 1970-01-01
    • 1970-01-01
    • 2016-02-05
    相关资源
    最近更新 更多