我不明白为什么我的波形会这样
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_0
、in_1
、cin
和 AddOrSub
的所有可能的 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
.
我对 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_0
、in_1
、cin
和 AddOrSub
的所有可能的 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
.