首先,请原谅我,如果这不是发布此问题的正确位置,但我不确定它应该去哪里。我目前正致力于使用VHDL在Xilinx中模拟ALU。 ALU具有以下输入和输出:
输入
输出
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位分别为 , B 和 Y 。
我不知道如何在VHDL代码中逻辑地实现这一点 - 特别是在进位的情况下。
答案 0 :(得分: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;
答案 1 :(得分:1)
您的解决方案
(not A(7) and not B(7) and Y(7)) or (A(7) and B(7) and not Y(7))
以下文字仅适用于签名加成;减法不正确。这两个规则是:
请注意,无论进位/借入的价值如何,这些都是正确的。您可以看到第一个规则不适用于使用简单的4位示例进行减法:例如,4减(-4)必须溢出,因为答案应该是+8,这是不可表示的在4位。在二进制中,这是0100 - 1100 = 1000
。这是根据(2)的溢出,但不是(1)。
好消息是,将进位输入到符号位并执行符号位总是有效 - 它对于加法和减法是正确的,以及是否存在 - 或借入,所以你可以使用马丁的代码。
如果你要做很多算术,你应该得到Henry Warren Hacker's Delight的副本。他涵盖了所有这些,以及更多。
答案 2 :(得分:0)
如果添加两个正数给出负数并且如果添加两个负数给出正数,则会发生溢出。也就是说,您需要比较操作数的MSB和答案。如果操作数的符号与答案的符号不匹配,则打开溢出标志。
编辑:这仅适用于没有携带的情况。当谈到添加随身携带时,我也需要帮助。