【发布时间】: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 <= b(3) when sel = '1' else not b(3);。您可以将其显示为单独的多路复用器(选择器)或使用 XOR 将其折叠为术语(b(3) xor not sel)。折叠原始溢出选择器也会得到localflow <= a(3) xor b(3) xor not sel xor localsum(3);不需要括号,XOR 是可交换的。而不是更高的优先级。 -
您好,您的建议奏效了 - 我保留了相同的程序,但多了一个多路复用器。非常感谢!