我是VHDL编码的新手,我一直在尝试调试32位加法器/减法器的代码。 N位加法器/减法器使用generate语句组成多个1位加法器/减法器。我一直在使用模拟对6位输入进行测试。波形不断变化,我尝试改变一切。也许,这是延迟和生成语句没有正确循环的问题。 (我刚开始学习如何在vhdl中编码。)
我的1位加法器/减法器
deployagent/rel/deployagent/log/error.log
N位加法器/减法器:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity addsub_1bit is
Port ( in_0 : in STD_LOGIC;
in_1 : in STD_LOGIC;
cin : in STD_LOGIC;
AddOrSub : in STD_LOGIC;
sum_sub : out STD_LOGIC;
cout_bout : out STD_LOGIC);
end addsub_1bit;
architecture data_flow_addsub_1bit of addsub_1bit is
begin
sum_sub <= (in_1 and (not in_0) and (not cin)) or ((not in_1) and in_0 and (not cin)) or ((not in_1) and (not in_0) and cin) or (in_1 and in_0 and cin) after 19 ns;
cout_bout <= (in_1 and in_0 and (not AddOrSub)) or ((not in_1)and in_1 and cin) or ((not in_1)and cin and AddOrSub) or (in_0 and cin) or (in_1 and cin and AddOrSub) after 19 ns;
end data_flow_addsub_1bit;
我的测试平台:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
ENTITY adder_sub32 is
GENERIC (BW : INTEGER :=32);
PORT ( a_32 : IN STD_LOGIC_VECTOR (BW -1 downto 0);
b_32 : IN STD_LOGIC_VECTOR (BW -1 downto 0);
cin : IN STD_LOGIC;
sub : IN STD_LOGIC;
sum_32 : out STD_LOGIC_VECTOR (BW -1 downto 0);
cout : INOUT STD_LOGIC ;
ov : OUT STD_LOGIC ); -- ov stands for overflow
END adder_sub32 ;
ARCHITECTURE adder_sub32_arch OF adder_sub32 IS
signal tmp : std_logic_vector (BW downto 0);
BEGIN
tmp(0) <= cin;
gen: for i IN 0 TO BW-1 GENERATE
as1: entity work.addsub_1bit
PORT MAP(
in_0 => a_32(i),
in_1 => b_32(i),
cin => tmp(i),
AddOrSub => sub,
sum_sub => sum_32(i),
cout_bout => tmp(i+1));
end GENERATE;
ov <= tmp(BW) after 95 ns;
END ARCHITECTURE;
我得到的波形:
答案 0 :(得分:0)
在这种情况下,最终总和是正确的(“101010”+“110101”=“011111”),但并非在所有情况下都是正确的。
EDIT2 :让我们仔细看看,为什么进位不会像你预期的那样波动。位0(LSB)到5的操作数一起,请求进位从位0传播到位6的进位。操作数的第6位产生进位,这是进位的加法器。当位0的cin
为'0'时,所有中间进位也都为'0',但它应该通过进位链波动。
现在让我们来看看一位加法器。您正在添加两个数字,因此AddOrSub
为'0'。有了这个,cout_bout
的等式可以简化为:
cout_bout <= (in_1 and in_0) or (in_0 and cin);
这个等式肯定是错误的,因为当in_1
='1'和in_0
='0'时,不会传播进位。因此,在19ns之后,一些中间进位将被计算为'0'而不等待波纹进位。相应的和位在38 ns后有效,如波形所示。总和的最终值不受影响,因为这个短暂的进位与预期的波纹进位相同。请在此考虑,所有1位加法器(由generate
语句生成)同时工作。
为了解决这个问题,我建议为1位加法器编写一个测试平台。此测试平台必须检查in_0
,in_1
,cin
和AddOrSub
的所有可能的16个输入组合。
另一个测试用例是添加上述两个操作数,其中cin
为'1'。
(EDIT2结束。)
ov
在这种情况下也是正确的,但并非在所有情况下。
编辑:您将溢出ov
与结转cout
混为一谈。溢出标志表示有符号数字空间中的溢出。另外,当且仅当:
对于减法,它是相反的。
因为这是一个家庭作业问题,我不会完全解决。但是我会给你一个测试用例,当前逻辑失败:如果你加1(“000001”)加-1(“111111”),那么总和必须为零,溢出'0'和进位' 1。 (编辑结束。)
cout
为'U',因为您尚未在adder_sub32
中将其连接。结转是您的进位链中最重要的位置,因此:
cout <= tmp(BW);
您应该在cout
中确定adder_sub32
的方向。结转只是该组件的输出。因此,请将其声明为out
而不是inout
。