VHDL 是否有 TAP(测试任何协议)实现?这会很好,因为这样我就可以使用证明来自动检查我的结果。还有一些不错的格式化程序,例如可以处理输出的smolder 。你可能会问为什么不使用断言。部分 TAP 给了我一些很好的报告,例如文件数量和测试数量。我正在寻找在开始和结束时进行大量测试以及 ok、diag 和 fail 功能的最小实现。is() 真的很好,但不是必需的。我可以写这个,但为什么要重新发明轮子。
这是这个问题中的问题,但对于 VHDL 而不是 Verilog。
我写了一个我经常使用的,但我从来没有分发过。在这里(未包含的 base_pkg 大部分都有 to_string() 实现)。
-- Copyright © 2010 Wesley J. Landaker <wjl@icecavern.net>
--
-- 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;
从我对 TAP 的有限快速阅读来看 - 不太可能......因为大多数 HDL 设计人员与软件测试世界的联系并不那么好(即使他们早在它被称为之前就一直在进行单元测试:) 我喜欢感觉我是一个 HDL 设计师,与软件测试世界有相当好的联系,而且我以前从未遇到过 TAP。我坚持使用 Python 自己的 unittest 功能(并涉足 pytest)。还有我自己使用 VHDL 及其断言的混合物。
不过,这看起来很简单package
……如果您决定自己写一个,请告诉我们!