0

下面是我的一个简单(非时钟)4 位加法器的测试台代码。我的模拟当前将显示发生的任何错误以及最后的“测试完成”。如果没有错误,模拟将简单地返回“测试完成”。
我的问题是: 有没有办法以某种方式包含“if”语句,以便在模拟中未检测到错误时显示“测试完成,没有错误”,并在模拟中显示“测试完成,发现 [x] 错误”在模拟中检测到错误(其中 x 是模拟完成时返回的可变错误数量。)?

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY adder_4bit_TB IS
END adder_4bit_TB;

ARCHITECTURE behavior OF adder_4bit_TB IS 

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

    COMPONENT adder_4bit
    PORT(
         a : IN  std_logic_vector(3 downto 0);
         b : IN  std_logic_vector(3 downto 0);
         carry : OUT  std_logic;
         sum   : OUT  std_logic_vector(3 downto 0)
        );
    END COMPONENT;


   --Inputs
   signal a : std_logic_vector(3 downto 0) := (others => '0');
   signal b : std_logic_vector(3 downto 0) := (others => '0');

    --Outputs
   signal carry : std_logic;
   signal sum   : std_logic_vector(3 downto 0);


BEGIN

    -- Instantiate the Unit Under Test (UUT)
   uut: adder_4bit PORT MAP (
          a => a,
          b => b,
          carry => carry,
          sum => sum
        );


   -- Stimulus process
   stim_proc: process    -- No CLK
   begin        

       -- Initialize Input values
        a <= "0000";
        b <= "0000";

        --Loop over all values of "a" and check sum
        for I in 0 to 15 loop
            --Loop over all values of "b" and check sum
            for J in 0 to 15 loop
                -- Wait for output to update (10 ns)
                wait for 10ns;

                -- Below is the self-verification routune being implemented for the 4 bit Adder.
                -- The routine checks the sum of "a" and "b" at the end of every loop, and 
                -- reports any Errors that may have occured. If no errors occur, simulation
                -- will return "Test Completed" (line109) in Command Window.

                assert (sum = a + b) report "Expected sum of " &
                    integer'image(to_integer(unsigned((a + b)))) & ". For a = " & 
                    integer'image(to_integer(unsigned((a)))) & " and b = " & 
                    integer'image(to_integer(unsigned((b)))) & ", but returned sum was " & 
                    integer'image(to_integer(unsigned((sum)))) severity ERROR;  -- severity level can be NOTE, WARNING, ERROR, or FAILURE

                -- Increment to next value of four bit vector "b"
                b <= b + "0001";
            end loop;   

            -- Increment to next value of four bit vector "a"
            a <= a + "0001";            
        end loop;

        --Echo to user that report has finished
        report "Test completed";

      wait; --will wait forever
   end process;

END;

使用下面的答案,这是生成的工作代码:

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY adder_4bit_TB IS
END adder_4bit_TB;

ARCHITECTURE behavior OF adder_4bit_TB IS 

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

    COMPONENT adder_4bit
    PORT(
         a : IN  std_logic_vector(3 downto 0);
         b : IN  std_logic_vector(3 downto 0);
         carry : OUT  std_logic;
         sum   : OUT  std_logic_vector(3 downto 0)
        );
    END COMPONENT;


   --Inputs
   signal a : std_logic_vector(3 downto 0) := (others => '0');
   signal b : std_logic_vector(3 downto 0) := (others => '0');

    --Outputs
   signal carry : std_logic;
   signal sum   : std_logic_vector(3 downto 0);


    --Outputs (Testbench only)
    signal Errors : boolean;            -- Boolean value.  True if error detected. False if no error detected.     
    signal ErrorCount : integer := 0;   -- Integer value to store the qty of errors.  Intitialized to zero

BEGIN

    -- Instantiate the Unit Under Test (UUT)
   uut: adder_4bit PORT MAP (
          a => a,
          b => b,
          carry => carry,
          sum => sum
        );


   -- Stimulus process
   stim_proc: process    -- No CLK
   begin        

       -- Initialize Input values
        a <= "0000";
        b <= "0000";

        --Loop over all values of "a" and check sum
        for I in 0 to 15 loop
            --Loop over all values of "b" and check sum
            for J in 0 to 15 loop
                -- Wait for output to update (10 ns)
                wait for 10ns;

                -- Below is the self-verification routune being implemented for the 4 bit Adder.
                -- The routine checks the sum of "a" and "b" at the end of every loop, and 
                -- reports any Errors that may have occured.

                if (sum /= a + b) then  ---- "/="  syntax:  test for inequality, result is boolean

                    Errors <= true;
                    ErrorCount <= ErrorCount + 1;
                else
                    Errors <= false;
                end if;

                assert (Errors = false) report "Expected sum of " &

                    integer'image(to_integer(unsigned((a + b)))) & ". For a = " & 
                    integer'image(to_integer(unsigned((a)))) & " and b = " & 
                    integer'image(to_integer(unsigned((b)))) & ", but returned sum was " & 
                    integer'image(to_integer(unsigned((sum)))) severity ERROR;  -- severity level can be NOTE, WARNING, ERROR, or FAILURE

                -- Increment to next value of four bit vector "b"
                b <= b + "0001";
            end loop;   

            -- Increment to next value of four bit vector "a"
            a <= a + "0001";            
        end loop;

        --Echo to user that report has finished
        report "Test completed with " & integer'image(ErrorCount) & " errors";

      wait; --will wait forever
   end process;

END;
4

3 回答 3

2

我建议你看看开源测试框架 VUnit ( https://github.com/LarsAsplund/vunit )。有了它,你可以做到

check_equal(sum, a + b);

在发生错误的情况下会给您这样的错误消息

ERROR: Equality check failed! Got 1111 (15). Expected 1110 (14).

要输出错误统计信息,您可以使用 get_checker_stat 函数。例如

info("Test Summary" & LF & to_string(get_checker_stat));

这给了你这样的东西

INFO: Test Summary
Checks: 6
Passed: 1
Failed: 5
于 2015-08-03T08:37:24.140 回答
0

这将是非常直接的添加到你所拥有的。与其使用断言直接测试求和的结果,不如使用if语句设置 aboolean如果求和不正确,然后根据此断言/计数错误。就像是:

variable Error : boolean;
variable ErrorCount : integer := 0;

...

if (sum /= a + b) then
    Error := true;
    ErrorCount := ErrorCount + 1;
else
    Error := false;
end if;

assert (Error = false) report "Expected sum of " &
                integer'image(to_integer(unsigned((a + b)))) & ". For a = " & 
                integer'image(to_integer(unsigned((a)))) & " and b = " & 
                integer'image(to_integer(unsigned((b)))) & ", but returned sum was " & 
                integer'image(to_integer(unsigned((sum)))) severity ERROR;

...

report "Test completed with " & integer'image(ErrorCount) & " errors";
于 2015-07-27T14:50:24.640 回答
0

您可以使用简单的report语句代替assert并将其包装在一个if..then..end if块中。例如:

if (error_count = 0) then
  report "Test completed." severity NOTE;
else
  report "Test completed with " & INTEGER'image(error_count) & " errors." severity ERROR;
end if;

这是一种更高级的方法:

您可以为隐藏一些内部代码的模拟构建一个帮助程序包,因此模拟使用更清晰的界面。以下示例声明了一个共享变量pass以跟踪是否发生错误。

此外,它声明了三个程序来提供断言“语句”和“打印模拟结果”方法:

  • tbFail 将消息写入模拟器日志并将跟踪变量设置为 false。
  • tbAssert 测试一个条件,如果失败,它会调用 tbFail 来生成一条日志消息
  • tbPrintResult 将整体结果写入标准输出。
    (这也可以在模拟器日志中看到,但特别是它可以被其他命令行工具解析,如果模拟以批处理模式运行。)

这是一个示例帮助程序包

use  std.TextIO.all;

package body simulation is
  -- Test Bench Status Management
  -- =============================================
  --  * Internal state variable to log a failure condition for final reporting.
  --  * Once de-asserted, this variable will never return to a value of true.
  shared variable pass : boolean := true;

  procedure tbFail(msg : in string := "") is
  begin
    if msg'length > 0 then
      report msg severity error;
    end if;
    pass := false;
  end;

  procedure tbAssert(cond : in boolean; msg : in string := "") is
  begin
    if not cond then
      tbFail(msg);
    end if;
  end;

  procedure tbPrintResult is
    variable l : line;
  begin
    write(l, string'("SIMULATION RESULT = "));
    if pass then
      write(l, string'("PASSED"));
    else
      write(l, string'("FAILED"));
    end if;
    writeline(output, l);
  end procedure;
end package;

此代码可以在测试平台中使用,如下所示:

architecture test of arith_prng_tb is
  constant CLOCK_PERIOD_100MHZ  : TIME                := 10 ns;
  constant COMPARE_LIST_8_BITS  : T_SLVV_8(0 TO 15)  := (
    x"12", x"24", x"48", x"90", x"21", x"42", x"85", x"0A",
    x"14", x"28", x"51", x"A2", x"45", x"8B", x"17", x"2E"
  );

  signal SimStop      : std_logic   := '0';
  signal Clock        : STD_LOGIC   := '1';
  signal Test_got     : STD_LOGIC   := '0';
  signal PRNG_Value   : T_SLV_8;
begin
  Clock <= Clock xnor SimStop after CLOCK_PERIOD_100MHZ / 2.0;

  process
  begin
    for i in 0 to 255 loop
      Test_got        <= '1';
      wait until rising_edge(Clock);
      tbAssert(
        (PRNG_Value = COMPARE_LIST_8_BITS(I)),
        "I=" & INTEGER'image(I) &  " Value=" & raw_format_slv_hex(PRNG_Value) & " Expected=" & raw_format_slv_hex(COMPARE_LIST_8_BITS(I))
      );
    end loop;

    Test_got        <= '0';

    -- Report overall simulation result
    tbPrintResult;
    SimStop  <= '1';
    wait;
  end process;

  -- ...
end architecture;

来源:
- PoC.simulation一个用于模拟的帮助程序包(VHDL-2008 版本
- PoC.arith.prng的测试平台- 一个伪随机数生成器

于 2015-07-27T16:02:32.817 回答