添加两个无符号(8 位)并将结果存储在 9 位无符号中时的错误结果
false result when adding two unsigned (8-bit) and storing the result in a 9-bit unsigned
我尝试实现一个带进位的简单 8 位加法器来测试 GHDL 和 gtkwave。
不幸的是,加法以某种方式错误地执行了加法器和 tb 的 VHDL 代码以及附加的控制台输出。
有谁知道为什么会发生该错误?
如果我删除调整大小功能并进位并将“myBuffer”缩小为 8 位,错误仍然发生。
此致
加法器:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity adder is
port(
clk : in std_logic;
opA, opB :in std_logic_vector(7 downto 0);
c :out std_logic;
result :out std_logic_vector(7 downto 0)
);
end entity adder;
architecture rtl of adder is
--signals
signal myBuffer : unsigned(8 downto 0);
begin
add : process(clk, opA, opB)
variable c_buf : std_logic := '0';
begin
--on rising edge
if(clk'event and clk = '1') then
myBuffer <= resize(unsigned(opA) + unsigned(opB), myBuffer'length);
--result <= myBuffer(7 downto 0);
c_buf := myBuffer(8);
assert c_buf = '1' report "carry detected" severity note;
report "opA = "&positive'image(to_integer(unsigned(opA)));
report "opB = "&positive'image(to_integer(unsigned(opB)));
report "expected result = "&positive'image(to_integer(unsigned(opA)+unsigned(opB)));
report "myBuffer = "&positive'image(to_integer(myBuffer));
c <= c_buf;
end if;
end process;
end architecture;
加法器 TB:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
--library adderLib;
entity adder_tb is
end entity;
architecture rtl of adder_tb is
type data is array(3 downto 0) of std_logic_vector(7 downto 0);
--components
component adder is
port(
clk : in std_logic;
opA, opB :in std_logic_vector(7 downto 0);
c :out std_logic;
result :out std_logic_vector(7 downto 0)
);
end component;
--for all: adder use entity adderLib.adder;
signal clk : std_logic := '0';
signal c : std_logic;
signal result : std_logic_vector(7 downto 0);
signal InOpA : std_logic_vector(7 downto 0);
signal InOpB : std_logic_vector(7 downto 0);
constant opA : data :=(0=>x"08",1=>x"09",2=>x"0A",3=>x"0B");
constant opB : data :=(0=>x"FF",1=>x"01",2=>x"02",3=>x"03");
begin
--apply test signals & gen clock
process
variable iteration :integer := 0;
begin
for i in opA'range loop
InOpA <= opA(i);
InOpB <= opB(i);
clk <= not clk;
wait for 5 ns;
clk <= not clk;
wait for 5 ns;
report "iteration";
end loop;
end process;
--connect component
adierer: adder
port map(
clk => clk,
opA => InOpA,
opB => InOpB,
c => c,
result => result
);
end rtl ;
TB 输出:
adder.vhd:26:13:@0ms:(assertion note): carry detected
adder.vhd:27:13:@0ms:(report note): opA = 11
adder.vhd:28:13:@0ms:(report note): opB = 3
adder.vhd:29:13:@0ms:(report note): expected result = 14
../../../src/ieee/numeric_std-body.v93:2098:7:@0ms:(assertion warning): NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0
adder.vhd:30:13:@0ms:(report note): myBuffer = 0
adder_tb.vhd:48:13:@10ns:(report note): iteration
adder.vhd:26:13:@10ns:(assertion note): carry detected
adder.vhd:27:13:@10ns:(report note): opA = 10
adder.vhd:28:13:@10ns:(report note): opB = 2
adder.vhd:29:13:@10ns:(report note): expected result = 12
adder.vhd:30:13:@10ns:(report note): myBuffer = 14
adder_tb.vhd:48:13:@20ns:(report note): iteration
adder.vhd:26:13:@20ns:(assertion note): carry detected
adder.vhd:27:13:@20ns:(report note): opA = 9
adder.vhd:28:13:@20ns:(report note): opB = 1
adder.vhd:29:13:@20ns:(report note): expected result = 10
adder.vhd:30:13:@20ns:(report note): myBuffer = 12
adder_tb.vhd:48:13:@30ns:(report note): iteration
adder.vhd:26:13:@30ns:(assertion note): carry detected
adder.vhd:27:13:@30ns:(report note): opA = 8
adder.vhd:28:13:@30ns:(report note): opB = 255
adder.vhd:29:13:@30ns:(report note): expected result = 7
adder.vhd:30:13:@30ns:(report note): myBuffer = 10
adder_tb.vhd:48:13:@40ns:(report note): iteration
adder.vhd:26:13:@40ns:(assertion note): carry detected
adder.vhd:27:13:@40ns:(report note): opA = 11
adder.vhd:28:13:@40ns:(report note): opB = 3
adder.vhd:29:13:@40ns:(report note): expected result = 14
adder.vhd:30:13:@40ns:(report note): myBuffer = 7
adder_tb.vhd:48:13:@50ns:(report note): iteration
adder.vhd:26:13:@50ns:(assertion note): carry detected
adder.vhd:27:13:@50ns:(report note): opA = 10
adder.vhd:28:13:@50ns:(report note): opB = 2
adder.vhd:29:13:@50ns:(report note): expected result = 12
adder.vhd:30:13:@50ns:(report note): myBuffer = 14
adder_tb.vhd:48:13:@60ns:(report note): iteration
adder.vhd:26:13:@60ns:(assertion note): carry detected
adder.vhd:27:13:@60ns:(report note): opA = 9
adder.vhd:28:13:@60ns:(report note): opB = 1
adder.vhd:29:13:@60ns:(report note): expected result = 10
adder.vhd:30:13:@60ns:(report note): myBuffer = 12
adder_tb.vhd:48:13:@70ns:(report note): iteration
adder.vhd:26:13:@70ns:(assertion note): carry detected
adder.vhd:27:13:@70ns:(report note): opA = 8
adder.vhd:28:13:@70ns:(report note): opB = 255
adder.vhd:29:13:@70ns:(report note): expected result = 7
adder.vhd:30:13:@70ns:(report note): myBuffer = 10
adder_tb.vhd:48:13:@80ns:(report note): iteration
adder.vhd:26:13:@80ns:(assertion note): carry detected
adder.vhd:27:13:@80ns:(report note): opA = 11
adder.vhd:28:13:@80ns:(report note): opB = 3
adder.vhd:29:13:@80ns:(report note): expected result = 14
adder.vhd:30:13:@80ns:(report note): myBuffer = 7
adder_tb.vhd:48:13:@90ns:(report note): iteration
adder.vhd:26:13:@90ns:(assertion note): carry detected
adder.vhd:27:13:@90ns:(report note): opA = 10
adder.vhd:28:13:@90ns:(report note): opB = 2
adder.vhd:29:13:@90ns:(report note): expected result = 12
adder.vhd:30:13:@90ns:(report note): myBuffer = 14
adder_tb.vhd:48:13:@100ns:(report note): iteration
adder.vhd:26:13:@100ns:(assertion note): carry detected
adder.vhd:27:13:@100ns:(report note): opA = 9
adder.vhd:28:13:@100ns:(report note): opB = 1
adder.vhd:29:13:@100ns:(report note): expected result = 10
adder.vhd:30:13:@100ns:(report note): myBuffer = 12
./adder_tb:info: simulation stopped by --stop-time
这里有一些问题
由于信号的分配方式,您看到报告的 mybuffer 计算落后了一次。当您分配信号时,例如:a <= b
;您只是将分配安排在当前增量周期结束时发生。在那之前,所有读取都将 return 信号的当前值,而不是新值。但是,变量会立即更新。如果要在同一个增量循环中检查预期结果,则应改用变量。 (同样理想的是,您将报告测试平台中的实际值和预期值,而不是 DUT)。
您没有进位,因为 8 位 + 8 位无符号 return 是 8 位结果。在你的代码中你已经完成了
myBuffer <= resize(unsigned(opA) + unsigned(opB), myBuffer'length);
这是一个扩展为9位的8位结果,因此MSB将始终为0。要实现进位,您至少需要将一个操作数扩展到结果的长度。 VHDL 中的加法总是将所有操作数扩展到最长的长度。最简单的方法是在一个操作数的前面附加一个“0”,因为这是无符号的:
myBuffer <= unsigned('0' & opA) + unsigned(opB);
- 您使用的是正像。如果结果或任何值为 0,则模拟将抛出错误。请改用整数或自然数。
我尝试实现一个带进位的简单 8 位加法器来测试 GHDL 和 gtkwave。 不幸的是,加法以某种方式错误地执行了加法器和 tb 的 VHDL 代码以及附加的控制台输出。 有谁知道为什么会发生该错误? 如果我删除调整大小功能并进位并将“myBuffer”缩小为 8 位,错误仍然发生。
此致
加法器:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity adder is
port(
clk : in std_logic;
opA, opB :in std_logic_vector(7 downto 0);
c :out std_logic;
result :out std_logic_vector(7 downto 0)
);
end entity adder;
architecture rtl of adder is
--signals
signal myBuffer : unsigned(8 downto 0);
begin
add : process(clk, opA, opB)
variable c_buf : std_logic := '0';
begin
--on rising edge
if(clk'event and clk = '1') then
myBuffer <= resize(unsigned(opA) + unsigned(opB), myBuffer'length);
--result <= myBuffer(7 downto 0);
c_buf := myBuffer(8);
assert c_buf = '1' report "carry detected" severity note;
report "opA = "&positive'image(to_integer(unsigned(opA)));
report "opB = "&positive'image(to_integer(unsigned(opB)));
report "expected result = "&positive'image(to_integer(unsigned(opA)+unsigned(opB)));
report "myBuffer = "&positive'image(to_integer(myBuffer));
c <= c_buf;
end if;
end process;
end architecture;
加法器 TB:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
--library adderLib;
entity adder_tb is
end entity;
architecture rtl of adder_tb is
type data is array(3 downto 0) of std_logic_vector(7 downto 0);
--components
component adder is
port(
clk : in std_logic;
opA, opB :in std_logic_vector(7 downto 0);
c :out std_logic;
result :out std_logic_vector(7 downto 0)
);
end component;
--for all: adder use entity adderLib.adder;
signal clk : std_logic := '0';
signal c : std_logic;
signal result : std_logic_vector(7 downto 0);
signal InOpA : std_logic_vector(7 downto 0);
signal InOpB : std_logic_vector(7 downto 0);
constant opA : data :=(0=>x"08",1=>x"09",2=>x"0A",3=>x"0B");
constant opB : data :=(0=>x"FF",1=>x"01",2=>x"02",3=>x"03");
begin
--apply test signals & gen clock
process
variable iteration :integer := 0;
begin
for i in opA'range loop
InOpA <= opA(i);
InOpB <= opB(i);
clk <= not clk;
wait for 5 ns;
clk <= not clk;
wait for 5 ns;
report "iteration";
end loop;
end process;
--connect component
adierer: adder
port map(
clk => clk,
opA => InOpA,
opB => InOpB,
c => c,
result => result
);
end rtl ;
TB 输出:
adder.vhd:26:13:@0ms:(assertion note): carry detected
adder.vhd:27:13:@0ms:(report note): opA = 11
adder.vhd:28:13:@0ms:(report note): opB = 3
adder.vhd:29:13:@0ms:(report note): expected result = 14
../../../src/ieee/numeric_std-body.v93:2098:7:@0ms:(assertion warning): NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0
adder.vhd:30:13:@0ms:(report note): myBuffer = 0
adder_tb.vhd:48:13:@10ns:(report note): iteration
adder.vhd:26:13:@10ns:(assertion note): carry detected
adder.vhd:27:13:@10ns:(report note): opA = 10
adder.vhd:28:13:@10ns:(report note): opB = 2
adder.vhd:29:13:@10ns:(report note): expected result = 12
adder.vhd:30:13:@10ns:(report note): myBuffer = 14
adder_tb.vhd:48:13:@20ns:(report note): iteration
adder.vhd:26:13:@20ns:(assertion note): carry detected
adder.vhd:27:13:@20ns:(report note): opA = 9
adder.vhd:28:13:@20ns:(report note): opB = 1
adder.vhd:29:13:@20ns:(report note): expected result = 10
adder.vhd:30:13:@20ns:(report note): myBuffer = 12
adder_tb.vhd:48:13:@30ns:(report note): iteration
adder.vhd:26:13:@30ns:(assertion note): carry detected
adder.vhd:27:13:@30ns:(report note): opA = 8
adder.vhd:28:13:@30ns:(report note): opB = 255
adder.vhd:29:13:@30ns:(report note): expected result = 7
adder.vhd:30:13:@30ns:(report note): myBuffer = 10
adder_tb.vhd:48:13:@40ns:(report note): iteration
adder.vhd:26:13:@40ns:(assertion note): carry detected
adder.vhd:27:13:@40ns:(report note): opA = 11
adder.vhd:28:13:@40ns:(report note): opB = 3
adder.vhd:29:13:@40ns:(report note): expected result = 14
adder.vhd:30:13:@40ns:(report note): myBuffer = 7
adder_tb.vhd:48:13:@50ns:(report note): iteration
adder.vhd:26:13:@50ns:(assertion note): carry detected
adder.vhd:27:13:@50ns:(report note): opA = 10
adder.vhd:28:13:@50ns:(report note): opB = 2
adder.vhd:29:13:@50ns:(report note): expected result = 12
adder.vhd:30:13:@50ns:(report note): myBuffer = 14
adder_tb.vhd:48:13:@60ns:(report note): iteration
adder.vhd:26:13:@60ns:(assertion note): carry detected
adder.vhd:27:13:@60ns:(report note): opA = 9
adder.vhd:28:13:@60ns:(report note): opB = 1
adder.vhd:29:13:@60ns:(report note): expected result = 10
adder.vhd:30:13:@60ns:(report note): myBuffer = 12
adder_tb.vhd:48:13:@70ns:(report note): iteration
adder.vhd:26:13:@70ns:(assertion note): carry detected
adder.vhd:27:13:@70ns:(report note): opA = 8
adder.vhd:28:13:@70ns:(report note): opB = 255
adder.vhd:29:13:@70ns:(report note): expected result = 7
adder.vhd:30:13:@70ns:(report note): myBuffer = 10
adder_tb.vhd:48:13:@80ns:(report note): iteration
adder.vhd:26:13:@80ns:(assertion note): carry detected
adder.vhd:27:13:@80ns:(report note): opA = 11
adder.vhd:28:13:@80ns:(report note): opB = 3
adder.vhd:29:13:@80ns:(report note): expected result = 14
adder.vhd:30:13:@80ns:(report note): myBuffer = 7
adder_tb.vhd:48:13:@90ns:(report note): iteration
adder.vhd:26:13:@90ns:(assertion note): carry detected
adder.vhd:27:13:@90ns:(report note): opA = 10
adder.vhd:28:13:@90ns:(report note): opB = 2
adder.vhd:29:13:@90ns:(report note): expected result = 12
adder.vhd:30:13:@90ns:(report note): myBuffer = 14
adder_tb.vhd:48:13:@100ns:(report note): iteration
adder.vhd:26:13:@100ns:(assertion note): carry detected
adder.vhd:27:13:@100ns:(report note): opA = 9
adder.vhd:28:13:@100ns:(report note): opB = 1
adder.vhd:29:13:@100ns:(report note): expected result = 10
adder.vhd:30:13:@100ns:(report note): myBuffer = 12
./adder_tb:info: simulation stopped by --stop-time
这里有一些问题
由于信号的分配方式,您看到报告的 mybuffer 计算落后了一次。当您分配信号时,例如:
a <= b
;您只是将分配安排在当前增量周期结束时发生。在那之前,所有读取都将 return 信号的当前值,而不是新值。但是,变量会立即更新。如果要在同一个增量循环中检查预期结果,则应改用变量。 (同样理想的是,您将报告测试平台中的实际值和预期值,而不是 DUT)。您没有进位,因为 8 位 + 8 位无符号 return 是 8 位结果。在你的代码中你已经完成了
myBuffer <= resize(unsigned(opA) + unsigned(opB), myBuffer'length);
这是一个扩展为9位的8位结果,因此MSB将始终为0。要实现进位,您至少需要将一个操作数扩展到结果的长度。 VHDL 中的加法总是将所有操作数扩展到最长的长度。最简单的方法是在一个操作数的前面附加一个“0”,因为这是无符号的:
myBuffer <= unsigned('0' & opA) + unsigned(opB);
- 您使用的是正像。如果结果或任何值为 0,则模拟将抛出错误。请改用整数或自然数。