添加两个无符号(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

这里有一些问题

  1. 由于信号的分配方式,您看到报告的 mybuffer 计算落后了一次。当您分配信号时,例如:a <= b;您只是将分配安排在当前增量周期结束时发生。在那之前,所有读取都将 return 信号的当前值,而不是新值。但是,变量会立即更新。如果要在同一个增量循环中检查预期结果,则应改用变量。 (同样理想的是,您将报告测试平台中的实际值和预期值,而不是 DUT)。

  2. 您没有进位,因为 8 位 + 8 位无符号 return 是 8 位结果。在你的代码中你已经完成了

myBuffer <= resize(unsigned(opA) + unsigned(opB), myBuffer'length);

这是一个扩展为9位的8位结果,因此MSB将始终为0。要实现进位,您至少需要将一个操作数扩展到结果的长度。 VHDL 中的加法总是将所有操作数扩展到最长的长度。最简单的方法是在一个操作数的前面附加一个“0”,因为这是无符号的:

myBuffer <= unsigned('0' & opA) + unsigned(opB);

  1. 您使用的是正像。如果结果或任何值为 0,则模拟将抛出错误。请改用整数或自然数。