我不明白为什么我的波形会这样

I can't understand why my waveform is coming out this way

我对 VHDL 编码还很陌生,我一直在尝试为 32 位 adder/subtractor 调试我的代码。 N 位 adder/subtractor 由多个 1 位 adder/subtractor 使用 generate 语句组合而成。我一直在使用模拟测试它的 6 位输入。波形总是不正确,我已经尝试改变几乎所有的东西。也许,这是延迟和生成语句没有正确循环的问题。 (我刚刚开始学习如何用 vhdl 编码。)

我的1位adder/subtractor

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;

N位adder/subtractor:

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;

我的测试平台:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

ENTITY adder_sub32_TB_SHan_53967364 IS
END adder_sub32_TB_SHan_53967364;


ARCHITECTURE behavior OF adder_sub32_TB_SHan_53967364 IS 

-- Component Declaration for the Unit Under Test (UUT)

    COMPONENT 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 COMPONENT;


signal a : std_logic_vector(5 downto 0); --:= (others => '0');
signal b : std_logic_vector(5 downto 0); --:= (others => '0');
signal cin  : std_logic;
signal sub  : std_logic;
signal cout : std_logic;
signal sum_32 : std_logic_vector(5 downto 0);
signal ov : std_logic;


BEGIN


test1: adder_sub32
    GENERIC MAP (6)
    PORT MAP (a_32 => a,b_32 => b,cin => cin,sub => sub,sum_32 => sum_32,cout => cout,ov => ov);

sub <= '0';
cin <= '0';
a <= "101010";
b <= "110101";
END;

我得到的波形:

在这种情况下,最终总和是正确的(“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' 时进位不传播。因此,一些中间进位将在 19 ns 之后被计算为“0”,而无需等待波动进位。如波形所示,相应的总和位将在 38 ns 后有效。总和的最终值不受影响,因为这个简化的进位与预期的波动进位相同。请在这里考虑,所有 1 位加法器(由 generate 语句生成)同时工作。

为了解决方程式,我建议为 1 位加法器编写一个测试平台。该测试平台必须检查 in_0in_1cinAddOrSub 的所有可能的 16 种输入组合。

另一个测试用例是将上述两个操作数与 cin 为“1”相加。 (EDIT2 结束。)


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

编辑:您混淆了溢出 ov 和进位 cout。溢出标志指示有符号数 space 中的溢出。对于加法,溢出标志为“1”当且仅当:

  • 两个正数相加得到负数,或者
  • 两个负数相加得到正数。

减法则相反。

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


cout 是 'U' 因为你没有在 adder_sub32 中连接它。进位输出是进位链中的最高位,因此:

cout <= tmp(BW);

并且你应该在adder_sub32中固定cout的方向。进位输出只是该组件的输出。所以将其声明为 out 而不是 inout.