如何显示自我验证测试平台中发生的错误数量?

时间:2015-07-27 14:43:44

标签: vhdl xilinx xilinx-ise

下面是我的简单(非时钟)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;

3 个答案:

答案 0 :(得分:2)

我建议您查看开源测试框架VUnit(https://github.com/LarsAsplund/vunit)。你可以这样做

shell_exec('nohup php /my/daemon/daemon.php &');

如果出现错误,将会出现类似

的错误消息
check_equal(sum, a + b);

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

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

给你这样的东西

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

答案 1 :(得分:0)

这将非常简单地添加到您拥有的内容中。如果总和不正确,则使用if语句设置boolean,而不是使用断言来直接测试总和的结果,然后根据此声明/计算错误。类似的东西:

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

答案 2 :(得分: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以跟踪是否发生错误。

此外,它宣布了三个程序来提供断言声明&#39;和打印模拟结果&#39;方法:

  • tbFail将消息写入模拟器日志,并将跟踪变量设置为false。
  • tbAssert测试条件,如果失败,则调用tbFail生成日志消息
  • tbPrintResult将整体结果写入stdout (这也可以在模拟器日志中看到,但如果模拟以批处理模式运行,尤其可以通过其他命令行工具进行解析。)

以下是helper package示例:

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;

此代码可以在testbench中使用,如下所示:

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 version
  - PoC.arith.prng的测试平台 - 伪随机数生成器