Reputation: 4836
I may have some functions that assert and fail if they're not happy.
How do I test this functionality with VUnit to ensure that these functions do in-fact throw the failure in the right conditions?
For instance, lets say I wanted to check this function:
function to_normalised_float(slv: std_logic_vector) return half_float is
variable temp_hf: half_float;
begin
assert slv'high = 15 report "SLV provided is incorrect length for an FP16";
-- ConstructFloat
return normalise_float(temp_hf);
end function;
I can quite easily test that it returns the expected value if I pass in a value and then assert on the output in my testbench.
However, I also want to be able to test, using VUnit, that if I pass in a 22 bit SLV, that the assertion throws.
This is obviously a very simplified example, but it should explain what I mean.
The equivalent in C# would be Assert.Throws(function)
if that helps.
Upvotes: 1
Views: 678
Reputation: 1440
The ability to inspect asserts will improve with VHDL-2019 support in your simulator but since you're using VUnit I recommend using VUnit mocking (http://vunit.github.io/logging/user_guide.html#mocking and https://github.com/VUnit/vunit/blob/f02c21452a505c527db575b10db94195ceb7ed2f/vunit/vhdl/logging/src/logger_pkg.vhd#L342) which is provided exactly to support your use case.
First replace your assert
with a VUnit check
:
check(slv'high = 15, "SLV provided is incorrect length for an FP16");
When that check fails you will see an error message looking something like this:
0 ps - check - ERROR - SLV provided is incorrect length for an FP16
check
is the VUnit logger
managing this message. You can get this logger by name (get_logger("check")
) and mock it. Mocking means that all output messages (of a specific severity level) will be placed in a queue rather than passed to stdout. The messages in this queue can be inspected to determine if the function works as expected. Here is a slightly modified example testbench to show the principle
library vunit_lib;
context vunit_lib.vunit_context;
library ieee;
use ieee.std_logic_1164.all;
entity tb_example is
generic (runner_cfg : string);
end entity;
architecture tb of tb_example is
begin
main : process
procedure dummy(slv : std_logic_vector) is
begin
check(slv'length = 16, "SLV provided is incorrect length for an FP16");
end;
constant logger : logger_t := get_logger("check");
begin
test_runner_setup(runner, runner_cfg);
while test_suite loop
if run("Test to see dummy fail") then
dummy(x"17");
elsif run("Test that dummy fails with the correct message") then
mock(logger, error);
dummy(x"17");
check_log(logger, "SLV provided is incorrect length for an FP16", error);
unmock(logger);
elsif run("Test that dummy passes with 16 bit inputs") then
mock(logger, error);
dummy(x"1718");
check_no_log;
unmock(logger);
end if;
end loop;
test_runner_cleanup(runner);
end process;
end architecture;
The first test case will fail (which is your problem) but the last two will pass
I can also recommend using check_equal
for a more informative output.
check_equal(slv'length, 16, result("for input length"));
will give you the following error output:
0 fs - check - ERROR - Equality check failed for input length - Got 8. Expected 16.
Upvotes: 1