我无法理解为什么我的波形会以这种方式出现

时间:2016-02-19 08:36:51

标签: vhdl

我是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;

我得到的波形:

waveform

1 个答案:

答案 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_0in_1cinAddOrSub的所有可能的16个输入组合。

另一个测试用例是添加上述两个操作数,其中cin为'1'。 (EDIT2结束。)

ov在这种情况下也是正确的,但并非在所有情况下

编辑:您将溢出ov与结转cout混为一谈。溢出标志表示有符号数字空间中的溢出。另外,当且仅当:

时,溢出标志为'1'
  • 添加两个正数会产生负数,或
  • 添加两个负数会产生正数。

对于减法,它是相反的。

因为这是一个家庭作业问题,我不会完全解决。但是我会给你一个测试用例,当前逻辑失败:如果你加1(“000001”)加-1(“111111”),那么总和必须为零,溢出'0'和进位' 1。 (编辑结束。)

cout为'U',因为您尚未在adder_sub32中将其连接。结转是您的进位链中最重要的位置,因此:

cout <= tmp(BW);

您应该在cout中确定adder_sub32的方向。结转只是该组件的输出。因此,请将其声明为out而不是inout