VUnit / vunit

VUnit is a unit testing framework for VHDL/SystemVerilog
http://vunit.github.io/
Other
722 stars 260 forks source link

Acceptance test failure for GHDL 3.0.0 under WSL2 #952

Open halfow opened 1 year ago

halfow commented 1 year ago

Hello!

Could not find this as a known issue. So lets post one 😄

Environment

Operating system used: Ubuntu 22.04 (WSL2)

Tool Version Note
vunit 4.7.0 This was also present on master b7fcc7f0215181863d1b1c1456ac2f4b80ba9816
ghdl 3.0.0 Build from sources and to have 2008 support enabled.
GNAT 10.4.0 ghdl compiled with this version
Python 3.10.6 (main, May 29 2023, 11:10:38) [GCC 11.3.0]

Issue

tb_com_lib.tb_com_codec.Test that custom record type can be encoded and decodedfails when running tox -e py310-acceptance-ghdl

For TLDR; see Initial Conclusion at the end

Gathering some data

Running the test stand alone the fault could be reproduced. python vunit/vhdl/com/run.py gives the same single failure (as expected).

python vunit/vhdl/com/run.py "*Test that custom record type can be encoded and decoded" -v

Starting tb_com_lib.tb_com_codec.Test that custom record type can be encoded and decoded
Output file: /<PLACEHOLDER>/vunit/vunit_out/test_output/tb_com_lib.tb_com_codec_<HASH>/output.txt
               0 fs - check                -   ERROR - Relation check failed
/<PLACEHOLDER>/vunit/vunit/vhdl/core/src/core_pkg.vhd:84:7:@0ms:(report failure): Stop simulation on log level error
/usr/local/bin/ghdl:error: report failed
in process .tb_com_codec(test_fixture).test_runner
  from: vunit_lib.core_pkg.core_failure
  from: vunit_lib.logger_pkg.decrease_stop_count
  from: vunit_lib.logger_pkg.decrease_stop_count
  from: vunit_lib.logger_pkg.log
  from: vunit_lib.checker_pkg.log_failing_check
  from: vunit_lib.checker_pkg.failing_check
  from: vunit_lib.check_pkg.check_relation
  from: vunit_lib.check_pkg.check_relation
  from: process tb_com_lib.tb_com_codec(test_fixture).test_runner
/usr/local/bin/ghdl:error: simulation failed
fail (P=0 S=0 F=1 T=1) tb_com_lib.tb_com_codec.Test that custom record type can be encoded and decoded (0.7 seconds)

To have some more data I tried running with the failing check commented out.

elsif run("Test that custom record type can be encoded and decoded") then
  rec1 := decode(encode_record1_t((character'pos(lp), -1, -2, -3)));
  -- check_relation(rec1 = (character'pos(lp), -1, -2, -3));  -- <--- THIS IS THE CHECK THAT FAILS

  rec2 := decode(encode_record2_t((command, 1, -1, -2, -3, '1')));
...
  check_relation(rec3 = (char => rp));

In this case all the following checks passed.

This got me curious. character'pos(lp) might be the villan. As the field of record1_t should be Natural I tried again with out the attribute pos lookup. 40 is used as its seemed to be the intended lp value

elsif run("Test that custom record type can be encoded and decoded") then
  rec1 := decode(encode_record1_t(40, -1, -2, -3)));
  check_relation(rec1 = (40, -1, -2, -3));  -- <--- THIS IS THE CHECK THAT FAILS
...

This worked! I might be on to something!

elsif run("Test that custom record type can be encoded and decoded") then
  rec1 := decode(encode_record1_t((natural(character'pos(lp)), -1, -2, -3)));
  check_relation(rec1 = (natural(character'pos(lp)), -1, -2, -3));
...

Wait, this also worked! Hmm... the attribute might return a incompatible type before its cast.

Here I feel that my knowledge starts to break down and there is enough data for a lazy resolution. Would happily follow along with any deeper analysis of the issue 😄

Deeper down the rabbit hole...

As my GHDL knowledge is to limited and I don't know of a way to print the type of a variable to the console in VHDL. I was left with a guessing game. I will not go down this rabbit hole further then trying integer. With the reasoning that having integer as the common attribute return type would make some sense.

type record1_t is record
  a       : integer;
  b, c, d : integer;
end record record1_t;
elsif run("Test that custom record type can be encoded and decoded") then
  rec1 := decode(encode_record1_t((character'pos(lp), -1, -2, -3)));
  check_relation(rec1 = (character'pos(lp), -1, -2, -3));
...

Unfortunately this guess was incorrect and the explicit casting was necessary in this case as well.

Initial Conclusion

This might be a GHDL issue/quirk. But I got to little knowledge about VUnit and GHDL to say ither.