vhdl - VHDL 的 TAP(测试任何协议(protocol))模块

标签 vhdl tap

是否有 VHDL 的 TAP(测试任何协议(protocol))实现?那就太好了,因为这样我就可以使用证明来自动检查我的结果。还有一些不错的格式设置,例如 smolder可以处理它的输出。您可能会问为什么不使用断言。部分 TAP 为我提供了一些很好的报告,例如文件数量和测试数量。我正在寻找一个最小的实现,在开始和结束时进行大量测试以及确定、诊断和失败功能。 is() 确实很好,但不是必需的。我可以写这个,但为什么要重新发明轮子。

这是 this question 中的问题但适用于 VHDL 而不是 Verilog。

最佳答案

我写了一篇我经常使用的文章,但我从未分发过它。就是这样(未包含的 base_pkg 大部分都有 to_string() 实现)。

-- Copyright © 2010 Wesley J. Landaker <<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b0c7dadcf0d9d3d5d3d1c6d5c2de9eded5c4" rel="noreferrer noopener nofollow">[email protected]</a>>
-- 
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.

-- 
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
-- 
-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.

-- Output is standard TAP (Test Anything Protocol) version 13

package test_pkg is

  procedure test_redirect(filename : string);
  procedure test_plan(tests : natural; directive : string := "");
  procedure test_abort(reason : string);
  procedure test_finished(directive : string := "");
  procedure test_comment (message : string);
  procedure test_pass (description : string := ""; directive : string := "");
  procedure test_fail (description : string := ""; directive : string := "");
  procedure test_ok   (result : boolean; description : string := ""; directive : string := "");
  procedure test_equal(actual, expected : integer; description : string := ""; directive : string := "");
  procedure test_equal(actual, expected : real; description : string := ""; directive : string := "");
  procedure test_equal(actual, expected : time; description : string := ""; directive : string := "");
  procedure test_equal(actual, expected : string; description : string := ""; directive : string := "");
  procedure test_equal(actual, expected : bit_vector; description : string := ""; directive : string := "");
  procedure test_approx_absolute(actual, expected, absolute_error : real; description : string := ""; directive : string := "");
  procedure test_approx_relative(actual, expected, relative_error : real; description : string := ""; directive : string := "");

end package;

use std.textio.all;
use work.base_pkg.all;

package body test_pkg is

  file test_output : text;
  shared variable initialized : boolean := false;
  shared variable have_plan : boolean := false;
  shared variable last_test_number : natural := 0;

  function remove_eol(s : string) return string is
    variable s_no_eol : string(s'range);
  begin
    for i in s'range loop
      case s(i) is
        when LF | CR => s_no_eol(i) := '_';
        when others  => s_no_eol(i) := s(i);
      end case;
    end loop;
    return s_no_eol;
  end function;

  function make_safe (s : string) return string is
    variable s_no_hash : string(s'range);
  begin
    for i in s'range loop
      case s(i) is
        when '#'    => s_no_hash(i) := '_';
        when others => s_no_hash(i) := s(i);
      end case;
    end loop;
    return remove_eol(s_no_hash);
  end function;

  procedure init is
    variable l : line;
  begin
    if initialized then
      return;
    end if;
    initialized := true;
    file_open(test_output, "STD_OUTPUT", write_mode);
    write(l, string'("TAP version 13"));
    writeline(test_output, l);
  end procedure;

  procedure test_redirect(filename : string) is
  begin
    init;
    file_close(test_output);
    file_open(test_output, filename, write_mode);
  end procedure;

  procedure test_plan(tests : natural; directive : string := "") is
    variable l : line;
  begin
    init;
    have_plan := true;
    write(l, string'("1.."));
    write(l, tests);
    if directive'length > 0 then
      write(l, " # " & remove_eol(directive));
    end if;
    writeline(test_output, l);
  end procedure;

  procedure test_abort(reason : string) is
    variable l : line;
  begin
    init;
    write(l, "Bail out! " & remove_eol(reason));
    writeline(test_output, l);
    assert false
      report "abort called"
      severity failure;
  end procedure;

  procedure test_finished (directive : string := "") is
  begin
    if not have_plan then
      test_plan(last_test_number, directive);
    elsif directive'length > 0 then
      test_comment("1.." & integer'image(last_test_number) & " # " & directive);
    else
      test_comment("1.." & integer'image(last_test_number));
    end if;
  end procedure;

  procedure test_comment (message : string) is
    variable l : line;
  begin
    init;
    write(l, '#');
    if message'length > 0 then
      write(l, " " & remove_eol(message));
    end if;
    writeline(test_output, l);
  end procedure;

  procedure result (status : string; description : string; directive : string) is
    variable l : line;
  begin
    init;
    last_test_number := last_test_number + 1;
    write(l, status & " ");
    write(l, last_test_number);
    if description'length > 0 then
      write(l, " " & make_safe(description));
    end if;
    if directive'length > 0 then
      write(l, " # " & remove_eol(directive));
    end if;
    writeline(test_output, l);
  end procedure;

  procedure test_pass (description : string := ""; directive : string := "") is
  begin
    result("ok", description, directive);
  end procedure;

  procedure test_fail (description : string := ""; directive : string := "") is
  begin
    result("not ok", description, directive);
  end procedure;

  procedure test_ok (result : boolean; description : string := ""; directive : string := "") is
  begin
    if result then
      test_pass(description, directive);
    else
      test_fail(description, directive);
    end if;
  end procedure;

  procedure test_equal(actual, expected : integer; description : string := ""; directive : string := "") is
    variable ok : boolean := actual = expected;
  begin
    test_ok(ok, description, directive);
    if not ok then
      test_comment("actual = " & integer'image(actual) & ", expected = " & integer'image(expected));
    end if;
  end procedure;

  procedure test_equal(actual, expected : real; description : string := ""; directive : string := "") is
    variable ok : boolean := actual = expected;
  begin
    test_ok(ok, description, directive);
    if not ok then
      test_comment("actual = " & real'image(actual) & ", expected = " & real'image(expected));
    end if;
  end procedure;

  procedure test_equal(actual, expected : time; description : string := ""; directive : string := "") is
    variable ok : boolean := actual = expected;
  begin
    test_ok(ok, description, directive);
    if not ok then
      test_comment("actual = " & time'image(actual) & ", expected = " & time'image(expected));
    end if;
  end procedure;

  procedure test_equal(actual, expected : string; description : string := ""; directive : string := "") is
    variable ok : boolean := actual = expected;
  begin
    test_ok(ok, description, directive);
    if not ok then
      test_comment("actual = " & actual & ", expected = " & expected);
    end if;
  end procedure;

  procedure test_equal(actual, expected : bit_vector; description : string := ""; directive : string := "") is
    variable ok : boolean := actual = expected;
  begin
    test_ok(ok, description, directive);
    if not ok then
      test_comment("actual = " & to_string(actual) & ", expected = " & to_string(expected));
    end if;
  end procedure;

  procedure test_approx_absolute(actual, expected, absolute_error : real; description : string := ""; directive : string := "") is
    variable err : real := abs(actual - expected);
    variable ok : boolean := err <= absolute_error;
  begin
    test_ok(ok, description, directive);
    if not ok then
      test_comment("actual = " & to_string(actual) & ", expected = " & to_string(expected) & ", absolute error = " & to_string(err));
    end if;
  end procedure;

  procedure test_approx_relative(actual, expected, relative_error : real; description : string := ""; directive : string := "") is
    variable err : real := abs(actual - expected)/abs(expected);
    variable ok : boolean := err <= relative_error;
  begin
    test_ok(ok, description, directive);
    if not ok then
      test_comment("actual = " & to_string(actual) & ", expected = " & to_string(expected) & ", relative error = " & to_string(err));
    end if;
  end procedure;

end package body;

关于vhdl - VHDL 的 TAP(测试任何协议(protocol))模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4348569/

相关文章:

vhdl - 从VHDL转换为Verilog,具体案例

optimization - 计算结果和多路复用与否

android - 使用底部导航在flutter中的dart文件之间切换

ios - 如果我们点击背景中的任何地方,除了快速点击 popView 之外,如何删除 popView

ios - 如何在uitextview或uiimage中点按突出显示特定句子

perl - 如何手动创建 TAP 输出

vhdl - VHDL 中 `std_logic` 枚举类型的目的是什么?

在没有 FPGA 的情况下测试我的 HDL 代码(Verilog/VHDL)?

vhdl - 数组作为缓冲区 VHDL

perl - 用 Test::More 写 "skip() unless ok()"可以吗?