From 2d157b29b0d155650c9a41805195b74db27b46dd Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Thu, 25 Jun 2026 20:12:49 +0100 Subject: [PATCH 01/29] Optimize assetOn checks furter --- src/V3Assert.cpp | 34 +++++++++++++--------------- test_regress/t/t_assert_opt_check.py | 4 ++-- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/V3Assert.cpp b/src/V3Assert.cpp index 8d4bf5275..09f6d1126 100644 --- a/src/V3Assert.cpp +++ b/src/V3Assert.cpp @@ -278,30 +278,26 @@ class AssertVisitor final : public VNVisitor { } VL_UNREACHABLE; } - static string assertActionControlPrefix(VAssertDirectiveType directiveType) { - const int controlled = !!(static_cast(directiveType) - & (static_cast(VAssertDirectiveType::ASSERT) - | static_cast(VAssertDirectiveType::COVER) - | static_cast(VAssertDirectiveType::ASSUME))); - const int checkRuntime = controlled & static_cast(v3Global.opt.assertOn()); - return "("s + std::to_string(controlled ^ 1) + " || ("s + std::to_string(checkRuntime) - + " && "s; + + static bool isControlled(VAssertDirectiveType directiveType) { + return (static_cast(directiveType) + & (static_cast(VAssertDirectiveType::ASSERT) + | static_cast(VAssertDirectiveType::COVER) + | static_cast(VAssertDirectiveType::ASSUME))); } static AstNodeExpr* assertPassOnCond(FileLine* fl, VAssertType type, VAssertDirectiveType directiveType, bool vacuous) { + if (!isControlled(directiveType)) return new AstConst{fl, AstConst::BitTrue{}}; + if (!v3Global.opt.assertOn()) return new AstConst{fl, AstConst::BitFalse{}}; return new AstCExpr{fl, AstCExpr::Pure{}, - assertActionControlPrefix(directiveType) - + assertCtlGetCall(assertPassOnQuery(vacuous), type, directiveType) - + "))"s, - 1}; + assertCtlGetCall(assertPassOnQuery(vacuous), type, directiveType), 1}; } static AstNodeExpr* assertFailOnCond(FileLine* fl, VAssertType type, VAssertDirectiveType directiveType) { + if (!isControlled(directiveType)) return new AstConst{fl, AstConst::BitTrue{}}; + if (!v3Global.opt.assertOn()) return new AstConst{fl, AstConst::BitFalse{}}; return new AstCExpr{fl, AstCExpr::Pure{}, - assertActionControlPrefix(directiveType) - + assertCtlGetCall("ASSERT_CTL_FAIL_ON", type, directiveType) - + "))"s, - 1}; + assertCtlGetCall("ASSERT_CTL_FAIL_ON", type, directiveType), 1}; } string assertDisplayMessage(const AstNode* nodep, const string& prefix, const string& message, VDisplayType severity) { @@ -374,6 +370,7 @@ class AssertVisitor final : public VNVisitor { AstNodeIf* const newp = new AstIf{fl, condp, bodyp}; newp->isBoundsCheck(true); // To avoid LATCH warning newp->user1(true); // Don't assert/cover this if + newp->user2(true); // Mark as an assertOn() check return newp; } static AstNodeStmt* newIfAssertFailOn(AstNode* bodyp, VAssertDirectiveType directiveType, @@ -385,6 +382,7 @@ class AssertVisitor final : public VNVisitor { AstNodeIf* const newp = new AstIf{fl, condp, bodyp}; newp->isBoundsCheck(true); // To avoid LATCH warning newp->user1(true); // Don't assert/cover this if + newp->user2(true); // Mark as an assertOn() check return newp; } @@ -696,10 +694,10 @@ class AssertVisitor final : public VNVisitor { VL_DO_DANGLING(pushDeletep(nodep), nodep); return; } - - iterateChildren(nodep); } + iterateChildren(nodep); + if (nodep->user2()) { // Combine consecutive assertOn checks if possible if (AstIf* const backp = VN_CAST(nodep->backp(), If)) { diff --git a/test_regress/t/t_assert_opt_check.py b/test_regress/t/t_assert_opt_check.py index 62b5a95d0..0e970d46e 100755 --- a/test_regress/t/t_assert_opt_check.py +++ b/test_regress/t/t_assert_opt_check.py @@ -15,7 +15,7 @@ test.compile(verilator_flags2=['--binary', '--stats']) test.execute(check_finished=True) -test.file_grep(test.stats, r'Assertions, assertOn checks combined\s+(\d+)', 3) -test.file_grep(test.stats, r'Assertions, assertOn checks hoisted\s+(\d+)', 16) +test.file_grep(test.stats, r'Assertions, assertOn checks combined\s+(\d+)', 4) +test.file_grep(test.stats, r'Assertions, assertOn checks hoisted\s+(\d+)', 42) test.passes() From 38533013670b950ff207fb192b3ea60ad8b0fa8a Mon Sep 17 00:00:00 2001 From: Yilou Wang Date: Fri, 26 Jun 2026 12:00:44 +0200 Subject: [PATCH 02/29] Fix disable iff ignored when its condition is held continuously true (#7841) --- src/V3AssertNfa.cpp | 12 +++- test_regress/t/t_cover_sequence.v | 2 +- test_regress/t/t_property_accept_reject_on.v | 20 +++--- test_regress/t/t_property_disable_iff_held.py | 18 +++++ test_regress/t/t_property_disable_iff_held.v | 65 +++++++++++++++++++ test_regress/t/t_sequence_within.v | 8 +-- 6 files changed, 109 insertions(+), 16 deletions(-) create mode 100755 test_regress/t/t_property_disable_iff_held.py create mode 100644 test_regress/t/t_property_disable_iff_held.v diff --git a/src/V3AssertNfa.cpp b/src/V3AssertNfa.cpp index 7949f8563..6a35273a5 100644 --- a/src/V3AssertNfa.cpp +++ b/src/V3AssertNfa.cpp @@ -1983,8 +1983,18 @@ class SvaNfaLowering final { AstNodeExpr*& sigp = c.vtx[i]->datap()->stateSigp; if (sigp) VL_DO_DANGLING(sigp->deleteTree(), sigp); } - // Disable iff gating on throughout/required-step rejects (IEEE 16.12). + // Disable iff gating (IEEE 1800-2023 16.12). The edge counter misses a + // continuously-true disable, so gate on the current level value too. if (c.disableExprp) { + // terminalActivep is always set, so gate it unconditionally. + AstNodeExpr* const notTermp + = new AstLogNot{c.flp, c.disableExprp->cloneTreePure(false)}; + sigs.terminalActivep = new AstLogAnd{c.flp, sigs.terminalActivep, notTermp}; + if (sigs.rejectBasep) { + AstNodeExpr* const notDisp + = new AstLogNot{c.flp, c.disableExprp->cloneTreePure(false)}; + sigs.rejectBasep = new AstLogAnd{c.flp, sigs.rejectBasep, notDisp}; + } if (sigs.throughoutRejectp) { AstNodeExpr* const notDisp = new AstLogNot{c.flp, c.disableExprp->cloneTreePure(false)}; diff --git a/test_regress/t/t_cover_sequence.v b/test_regress/t/t_cover_sequence.v index 719a3c1ba..42f39949e 100644 --- a/test_regress/t/t_cover_sequence.v +++ b/test_regress/t/t_cover_sequence.v @@ -79,7 +79,7 @@ module t ( `endif `checkd(hit_simple, 96); // Questa: 95 `checkd(hit_clocked, 149); // Questa: 149 - `checkd(hit_clocked_disable, 28); // Questa: 27 + `checkd(hit_clocked_disable, 27); // Questa: 27 `checkd(hit_default_disable, 30); // Questa: 30 `checkd(hit_consrep_2, 30); // Questa: 29 `checkd(hit_consrep_3, 14); // Questa: 13 diff --git a/test_regress/t/t_property_accept_reject_on.v b/test_regress/t/t_property_accept_reject_on.v index 020e754f2..1affe217c 100644 --- a/test_regress/t/t_property_accept_reject_on.v +++ b/test_regress/t/t_property_accept_reject_on.v @@ -94,16 +94,16 @@ module t ( end else if (cyc == 99) begin `checkh(crc, 64'hc77bb9b3784ea091); - `checkd(count_fail1, 29); // Questa: 14 - `checkd(count_fail2, 65); // Questa: 64 - `checkd(count_fail3, 29); // Questa: 14 - `checkd(count_fail4, 65); // Questa: 64 - `checkd(count_fail5, 46); // Questa: 31 - `checkd(count_fail6, 65); // Questa: 59 - `checkd(count_fail7, 29); // Questa: 14 - `checkd(count_fail8, 14); // Questa: 10 - `checkd(count_fail9, 29); // Questa: 14 - `checkd(count_fail10, 29); // Questa: 14 + `checkd(count_fail1, 28); // Questa: 14 + `checkd(count_fail2, 64); // Questa: 64 + `checkd(count_fail3, 28); // Questa: 14 + `checkd(count_fail4, 64); // Questa: 64 + `checkd(count_fail5, 45); // Questa: 31 + `checkd(count_fail6, 64); // Questa: 59 + `checkd(count_fail7, 28); // Questa: 14 + `checkd(count_fail8, 13); // Questa: 10 + `checkd(count_fail9, 28); // Questa: 14 + `checkd(count_fail10, 28); // Questa: 14 $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_property_disable_iff_held.py b/test_regress/t/t_property_disable_iff_held.py new file mode 100755 index 000000000..8c5881f1b --- /dev/null +++ b/test_regress/t/t_property_disable_iff_held.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile(timing_loop=True, verilator_flags2=['--assert --timing --coverage']) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_property_disable_iff_held.v b/test_regress/t/t_property_disable_iff_held.v new file mode 100644 index 000000000..04530fc6e --- /dev/null +++ b/test_regress/t/t_property_disable_iff_held.v @@ -0,0 +1,65 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2026 PlanV GmbH +// SPDX-License-Identifier: CC0-1.0 + +// verilog_format: off +`define stop $stop +`define checkd(gotv, expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); +// verilog_format: on + +// IEEE 1800-2023 16.12: a disable iff condition held continuously true must +// disable every attempt of a multi-cycle property (verilator/verilator#7792). +// en_held is a plain non-$sampled, non-constant signal held 1, so it exercises +// the NFA disable-counter path. The held assert/cover must never fire; the +// `disable iff (1'b0)` controls prove the same assert/cover do fire when enabled. + +module t ( + input clk +); + int cyc = 0; + reg [63:0] crc = 64'h5aef0c8d_d70a4497; + wire a = crc[0]; + wire b = crc[4]; + + bit en_held = 1'b1; + + int n_held_assert = 0; + int n_held_cover = 0; + int n_ctrl_assert = 0; + int n_ctrl_cover = 0; + + // Held-true disable: assert + cover must be fully suppressed. + assert property (@(posedge clk) disable iff (en_held) (a ##1 b)) + else n_held_assert <= n_held_assert + 1; + cover property (@(posedge clk) disable iff (en_held) (a ##1 b)) + n_held_cover <= n_held_cover + 1; + + // Enabled control (disable iff 1'b0): same assert + cover must fire. + assert property (@(posedge clk) disable iff (1'b0) (a ##1 b)) + else n_ctrl_assert <= n_ctrl_assert + 1; + cover property (@(posedge clk) disable iff (1'b0) (a ##1 b)) + n_ctrl_cover <= n_ctrl_cover + 1; + + always @(posedge clk) begin + cyc <= cyc + 1; + crc <= {crc[62:0], crc[63] ^ crc[2] ^ crc[0]}; + if (cyc == 99) begin + `checkd(n_held_assert, 0); // Questa: 0 + `checkd(n_held_cover, 0); // Questa: 0 + `checkd(n_ctrl_assert, 58); // Questa: 58 + `checkd(n_ctrl_cover, 26); // Questa: 26 + $write("*-* All Finished *-*\n"); + $finish; + end + end +endmodule + +`ifndef VERILATOR +module wrap; + logic clk = 0; + always #5 clk = ~clk; + t inst (.clk(clk)); +endmodule +`endif diff --git a/test_regress/t/t_sequence_within.v b/test_regress/t/t_sequence_within.v index 093b7afcb..dcffaae56 100644 --- a/test_regress/t/t_sequence_within.v +++ b/test_regress/t/t_sequence_within.v @@ -107,14 +107,14 @@ module t ( // engine-wide behavior, not within-specific. `checkd(count_p1, 23); // Questa: 23 `checkd(count_p2, 44); // Questa: 44 - `checkd(count_p3, 26); // Questa: 20 - `checkd(count_p4, 24); // Questa: 22 + `checkd(count_p3, 25); // Questa: 20 + `checkd(count_p4, 23); // Questa: 22 `checkd(count_p5, 26); // Questa: 26 `checkd(count_p6, 21); // Questa: 16 `checkd(count_p7, 15); // Questa: 9 `checkd(count_p8, 15); // Questa: 4 - `checkd(count_p9, 17); // Questa: 10 - `checkd(count_p10, 24); // Questa: 15 + `checkd(count_p9, 15); // Questa: 10 + `checkd(count_p10, 23); // Questa: 15 $write("*-* All Finished *-*\n"); $finish; end From d023b3b075b2632bc02ac834eee54d0b466232fc Mon Sep 17 00:00:00 2001 From: Matthew Ballance Date: Sun, 28 Jun 2026 06:28:09 -0700 Subject: [PATCH 03/29] Support dynamic loading of VPI extensions (#7727) --- bin/verilator | 1 + configure.ac | 28 ++++++ docs/guide/exe_sim.rst | 14 +++ include/verilated.cpp | 69 ++++++++++++++ include/verilated.h | 3 + include/verilated.mk.in | 4 + src/V3EmitCMain.cpp | 2 + src/V3EmitMk.cpp | 17 ++++ test_regress/t/t_flag_main_vpi.cpp | 94 ++++++++++++++++++++ test_regress/t/t_flag_main_vpi.out | 2 + test_regress/t/t_flag_main_vpi.py | 30 +++++++ test_regress/t/t_flag_main_vpi.v | 28 ++++++ test_regress/t/t_flag_main_vpi_badentry.out | 2 + test_regress/t/t_flag_main_vpi_badentry.py | 25 ++++++ test_regress/t/t_flag_main_vpi_badlib.out | 2 + test_regress/t/t_flag_main_vpi_badlib.py | 26 ++++++ test_regress/t/t_flag_main_vpi_bootstrap.out | 2 + test_regress/t/t_flag_main_vpi_bootstrap.py | 25 ++++++ test_regress/t/t_flag_main_vpi_lib2.cpp | 25 ++++++ test_regress/t/t_flag_main_vpi_multi.out | 3 + test_regress/t/t_flag_main_vpi_multi.py | 42 +++++++++ test_regress/t/t_flag_main_vpi_noarray.cpp | 21 +++++ test_regress/t/t_flag_main_vpi_noarray.out | 2 + test_regress/t/t_flag_main_vpi_noarray.py | 25 ++++++ test_regress/t/t_flag_main_vpi_noexe.py | 30 +++++++ test_regress/t/t_flag_main_vpi_nowarn.out | 3 + test_regress/t/t_flag_main_vpi_nowarn.py | 24 +++++ 27 files changed, 549 insertions(+) create mode 100644 test_regress/t/t_flag_main_vpi.cpp create mode 100644 test_regress/t/t_flag_main_vpi.out create mode 100755 test_regress/t/t_flag_main_vpi.py create mode 100644 test_regress/t/t_flag_main_vpi.v create mode 100644 test_regress/t/t_flag_main_vpi_badentry.out create mode 100755 test_regress/t/t_flag_main_vpi_badentry.py create mode 100644 test_regress/t/t_flag_main_vpi_badlib.out create mode 100755 test_regress/t/t_flag_main_vpi_badlib.py create mode 100644 test_regress/t/t_flag_main_vpi_bootstrap.out create mode 100755 test_regress/t/t_flag_main_vpi_bootstrap.py create mode 100644 test_regress/t/t_flag_main_vpi_lib2.cpp create mode 100644 test_regress/t/t_flag_main_vpi_multi.out create mode 100755 test_regress/t/t_flag_main_vpi_multi.py create mode 100644 test_regress/t/t_flag_main_vpi_noarray.cpp create mode 100644 test_regress/t/t_flag_main_vpi_noarray.out create mode 100755 test_regress/t/t_flag_main_vpi_noarray.py create mode 100755 test_regress/t/t_flag_main_vpi_noexe.py create mode 100644 test_regress/t/t_flag_main_vpi_nowarn.out create mode 100755 test_regress/t/t_flag_main_vpi_nowarn.py diff --git a/bin/verilator b/bin/verilator index 57fd60507..cb866e243 100755 --- a/bin/verilator +++ b/bin/verilator @@ -653,6 +653,7 @@ description of these arguments. +verilator+solver+file+ Set random solver log filename +verilator+V Show verbose version and config +verilator+version Show version and exit + +verilator+vpi+[:] Load VPI shared library +verilator+wno+unsatconstr+ Disable constraint warnings diff --git a/configure.ac b/configure.ac index 6917f0c4b..00d8ac713 100644 --- a/configure.ac +++ b/configure.ac @@ -589,6 +589,34 @@ m4_foreach([ldflag], [ AC_SUBST(CFG_LDLIBS_THREADS) AC_SUBST(CFG_LDFLAGS_THREADS_CMAKE) +# Find link flags for runtime VPI library loading (+verilator+vpi+). +# The model executable must export its VPI symbols so the dlopen'd library can +# resolve them: -rdynamic (GNU ld) or -Wl,-export_dynamic (Darwin); the first the +# linker accepts wins. -ldl provides dlopen/dlsym where it is a separate library. +_MY_LDLIBS_CHECK_SET(CFG_LDFLAGS_DYNAMIC, -rdynamic) +# -Wl,-export_dynamic contains a comma, so probe it directly rather than through +# the _MY_LDLIBS_CHECK_* macros (which re-expand their flag argument unquoted). +if test "$CFG_LDFLAGS_DYNAMIC" = ""; then + ACO_SAVE_LIBS="$LIBS" + LIBS="$LIBS -Wl,-export_dynamic" + AC_MSG_CHECKING([whether $CXX linker accepts -Wl,-export_dynamic]) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[]])], + [_my_result=yes + if test -s conftest.err; then + if grep -e "-export_dynamic" conftest.err >/dev/null; then + _my_result=no + fi + fi], + [_my_result=no]) + AC_MSG_RESULT($_my_result) + LIBS="$ACO_SAVE_LIBS" + if test "$_my_result" = "yes"; then CFG_LDFLAGS_DYNAMIC="-Wl,-export_dynamic"; fi +fi +AC_SUBST(CFG_LDFLAGS_DYNAMIC) +_MY_LDLIBS_CHECK_OPT(CFG_LDLIBS_DYNAMIC, -ldl) +AC_SUBST(CFG_LDLIBS_DYNAMIC) + # If 'mold' is installed, use it to link for faster buildtimes _MY_LDLIBS_CHECK_OPT(CFG_LDFLAGS_SRC, -fuse-ld=mold) _MY_LDLIBS_CHECK_OPT(CFG_LDFLAGS_VERILATED, -fuse-ld=mold) diff --git a/docs/guide/exe_sim.rst b/docs/guide/exe_sim.rst index ac2b73f16..190367346 100644 --- a/docs/guide/exe_sim.rst +++ b/docs/guide/exe_sim.rst @@ -139,6 +139,20 @@ Options: Displays program version and exits. +.. option:: +verilator+vpi+[:] + + Load a VPI shared library before simulation starts. Only available when the + model was Verilated with :vlopt:`--vpi` and :vlopt:`--main` (or + :vlopt:`--binary`). ```` is the path to the shared library. If + ``:`` is given, that named no-argument function is called; + otherwise the library's ``vlog_startup_routines`` array (IEEE 1800 38.37.2) is + invoked. May be repeated to load multiple libraries. + + Runtime loading is supported on POSIX platforms only (it relies on the + executable exporting its VPI symbols to the loaded library); on Windows the + argument is rejected and the VPI code must instead be statically linked + into the model. + .. option:: +verilator+wno+unsatconstr+ Disable unsatisfied constraint warnings at simulation runtime. When set to diff --git a/include/verilated.cpp b/include/verilated.cpp index 9cbb58ffc..a92c6ca5f 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -89,6 +89,12 @@ # include # define _VL_HAVE_GETRLIMIT #endif +#if VM_VPI +# include +# ifndef _WIN32 +# include // dlopen +# endif +#endif #include "verilated_threads.h" // clang-format on @@ -260,6 +266,58 @@ void VL_WARN_MT(const char* filename, int linenum, const char* hier, const char* }}); } +//=========================================================================== +// Runtime VPI shared library loading (--vpi) + +// Load one VPI shared library named by a +verilator+vpi+[:] argument. +// 'arg' is the payload after the prefix: either "" (invoke the library's +// vlog_startup_routines array) or ":" (invoke the named bootstrap). +void Verilated::loadVpiLib(const std::string& arg) VL_MT_UNSAFE { +#if VM_VPI + if (arg.empty()) return; +#ifdef _WIN32 + VL_FATAL_MT("", 0, "", + "+verilator+vpi+: runtime VPI library loading is not supported on" + " Windows; link the VPI code into the model instead"); +#else + using vlog_startup_t = void (*)(); + // Split : on the last ':' + const std::string::size_type colon_pos = arg.rfind(':'); + const bool has_entry = (colon_pos != std::string::npos); + const std::string libpath = has_entry ? arg.substr(0, colon_pos) : arg; + const std::string entry_name = has_entry ? arg.substr(colon_pos + 1) : std::string{}; + void* handle = dlopen(libpath.c_str(), RTLD_LAZY); + if (!handle) + // The library path is stable; the dlerror() text is platform-specific, so put it on + // a separate "- " line (test golden files strip "- " lines, keeping output portable). + VL_FATAL_MT( + "", 0, "", + (std::string{"Cannot load VPI library: "} + libpath + "\n- dlerror: " + dlerror()) + .c_str()); + if (has_entry) { + vlog_startup_t bsp = reinterpret_cast(dlsym(handle, entry_name.c_str())); + if (!bsp) + VL_FATAL_MT( + "", 0, "", + (std::string{"Cannot find VPI bootstrap '"} + entry_name + "' in: " + libpath) + .c_str()); + bsp(); + } else { + vlog_startup_t* routinesp + = reinterpret_cast(dlsym(handle, "vlog_startup_routines")); + if (!routinesp) + VL_FATAL_MT( + "", 0, "", + (std::string{"Cannot find 'vlog_startup_routines' in: "} + libpath).c_str()); + for (int j = 0; routinesp[j]; ++j) routinesp[j](); + } +#endif +#else + // Never reached: the command-line handler only calls this when compiled with --vpi. + (void)arg; +#endif +} + //=========================================================================== // Debug prints @@ -3544,6 +3602,17 @@ void VerilatedContextImp::commandArgVl(const std::string& arg) { // and the run can be reproduced by passing +verilator+seed+. if (u64 == 0) u64 = pickRandomSeed(); randSeed(static_cast(u64)); + } else if (commandArgVlString(arg, "+verilator+vpi+", str)) { + // With --vpi, load the requested shared library now. Without --vpi there is + // no VPI runtime, so warn the argument is ignored. +#if VM_VPI + Verilated::loadVpiLib(str); +#else + VL_WARN_MT( + "COMMAND_LINE", 0, "", + ("+verilator+vpi+ ignored: simulation was not compiled with --vpi '" + arg + "'") + .c_str()); // LCOV_EXCL_LINE (gcov zeroes this wrapped continuation line) +#endif } else if (arg == "+verilator+V") { VerilatedImp::versionDump(); // Someday more info too VL_FATAL_MT("COMMAND_LINE", 0, "", diff --git a/include/verilated.h b/include/verilated.h index 59ae1ad8c..73c7e5b2a 100644 --- a/include/verilated.h +++ b/include/verilated.h @@ -1036,6 +1036,9 @@ public: static void scTraceBeforeElaborationError() VL_ATTR_NORETURN VL_MT_SAFE; static void stackCheck(QData needSize) VL_MT_UNSAFE; + // Internal: Load a VPI shared library (+verilator+vpi+[:]) + static void loadVpiLib(const std::string& arg) VL_MT_UNSAFE; + // Internal: Get and set DPI context static const VerilatedScope* dpiScope() VL_MT_SAFE { return t_s.t_dpiScopep; } static void dpiScope(const VerilatedScope* scopep) VL_MT_SAFE { t_s.t_dpiScopep = scopep; } diff --git a/include/verilated.mk.in b/include/verilated.mk.in index 9d3f3b2e7..a90907755 100644 --- a/include/verilated.mk.in +++ b/include/verilated.mk.in @@ -52,6 +52,9 @@ CFG_GCH_IF_CLANG = @CFG_GCH_IF_CLANG@ CFG_LDFLAGS_VERILATED = @CFG_LDFLAGS_VERILATED@ # Linker libraries for multithreading CFG_LDLIBS_THREADS = @CFG_LDLIBS_THREADS@ +# Linker flags/libraries for runtime VPI library loading (+verilator+vpi+) +CFG_LDFLAGS_DYNAMIC = @CFG_LDFLAGS_DYNAMIC@ +CFG_LDLIBS_DYNAMIC = @CFG_LDLIBS_DYNAMIC@ ###################################################################### # Programs @@ -93,6 +96,7 @@ VK_CPPFLAGS_ALWAYS += \ -DVM_TRACE_FST=$(VM_TRACE_FST) \ -DVM_TRACE_VCD=$(VM_TRACE_VCD) \ -DVM_TRACE_SAIF=$(VM_TRACE_SAIF) \ + -DVM_VPI=$(VM_VPI) \ $(CFG_CXXFLAGS_NO_UNUSED) \ ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users diff --git a/src/V3EmitCMain.cpp b/src/V3EmitCMain.cpp index 000567eaf..0d3fd0b6d 100644 --- a/src/V3EmitCMain.cpp +++ b/src/V3EmitCMain.cpp @@ -104,6 +104,8 @@ private: puts("\n"); if (v3Global.opt.vpi()) { + // VPI shared libraries requested via +verilator+vpi+ are loaded by + // contextp->commandArgs() above, before the statically-linked startup routines. puts("// Hook VPI startup routines and invoke callback\n"); puts("if (vlog_startup_routines) {\n"); puts(/**/ "for (auto routinep = &vlog_startup_routines[0]; *routinep; routinep++)" diff --git a/src/V3EmitMk.cpp b/src/V3EmitMk.cpp index f76945279..a63d328f3 100644 --- a/src/V3EmitMk.cpp +++ b/src/V3EmitMk.cpp @@ -567,6 +567,12 @@ public: of.puts("VM_TRACE_VCD = "); of.puts(v3Global.opt.traceEnabledVcd() ? "1" : "0"); of.puts("\n"); + of.puts("# VPI enabled? 0/1 (from --vpi)\n"); + of.puts("VM_VPI = "); + of.puts(v3Global.opt.vpi() ? "1" : "0"); + of.puts("\n"); + // Link flags for runtime VPI library loading are emitted by emitOverallMake() after + // verilated.mk is included (so $(CFG_LDFLAGS_DYNAMIC)/$(CFG_LDLIBS_DYNAMIC) are defined). of.puts("\n### Object file lists...\n"); for (int support = 0; support < 3; ++support) { @@ -729,6 +735,17 @@ public: of.puts("\n### Executable rules... (from --exe)\n"); of.puts("VPATH += $(VM_USER_DIR)\n"); of.puts("\n"); + + if (v3Global.opt.vpi()) { + // Runtime VPI library loading (+verilator+vpi+) needs the executable to + // export its VPI symbols so the dlopen'd library can resolve them, plus the + // dl library for dlopen/dlsym. The exact flags are probed at configure time + // (CFG_LDFLAGS_DYNAMIC / CFG_LDLIBS_DYNAMIC in verilated.mk). + of.puts("# Runtime VPI library loading (+verilator+vpi+) link requirements\n"); + of.puts("LDFLAGS += $(CFG_LDFLAGS_DYNAMIC)\n"); + of.puts("LDLIBS += $(CFG_LDLIBS_DYNAMIC)\n"); + of.puts("\n"); + } } const string compilerIncludePch diff --git a/test_regress/t/t_flag_main_vpi.cpp b/test_regress/t/t_flag_main_vpi.cpp new file mode 100644 index 000000000..1be31452a --- /dev/null +++ b/test_regress/t/t_flag_main_vpi.cpp @@ -0,0 +1,94 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// DESCRIPTION: Verilator: VPI test library for t_flag_main_vpi +// +// Loaded at runtime via +verilator+vpi+ to verify that --binary --vpi +// correctly loads shared libraries and invokes vlog_startup_routines[] (or a +// named bootstrap). The design drives its own clock; this library only +// observes 'count' via a cbValueChange callback and calls $finish after +// MAX_TICKS edges -- so a successful $finish proves the library was loaded +// and is able to register callbacks and reach signals by name. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of either the GNU Lesser General Public License Version 3 +// or the Perl Artistic License Version 2.0. +// SPDX-FileCopyrightText: 2025 Wilson Snyder +// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 +// +//************************************************************************* + +#include "vpi_user.h" + +#include +#include + +// Number of count increments to observe before calling $finish +static const int MAX_TICKS = 10; +static vpiHandle s_count_handle = nullptr; + +static PLI_INT32 count_change_cb(p_cb_data /*cb_data*/) { + if (!s_count_handle) return 0; + s_vpi_value val; + val.format = vpiIntVal; + vpi_get_value(s_count_handle, &val); + if (val.value.integer >= MAX_TICKS) { + vpi_printf(const_cast("*-* All Finished *-*\n")); + vpi_control(vpiFinish, 0); + } + return 0; +} + +static PLI_INT32 start_of_sim_cb(p_cb_data /*cb_data*/) { + s_count_handle = vpi_handle_by_name(const_cast("t.count"), nullptr); + if (!s_count_handle) { + vpi_printf(const_cast("ERROR: cannot find t.count\n")); + vpi_control(vpiFinish, 1); + return 0; + } + // Observe count: fire a callback whenever it changes + t_cb_data cb_data; + s_vpi_time t; + s_vpi_value val; + t.type = vpiSuppressTime; + val.format = vpiSuppressVal; + cb_data.reason = cbValueChange; + cb_data.cb_rtn = count_change_cb; + cb_data.obj = s_count_handle; + cb_data.time = &t; + cb_data.value = &val; + cb_data.user_data = nullptr; + vpi_register_cb(&cb_data); + return 0; +} + +static PLI_INT32 end_of_sim_cb(p_cb_data /*cb_data*/) { + vpi_printf(const_cast("VPI end of simulation\n")); + return 0; +} + +static void register_callbacks() { + // cbStartOfSimulation + t_cb_data cb_data; + s_vpi_time t; + t.type = vpiSuppressTime; + cb_data.reason = cbStartOfSimulation; + cb_data.cb_rtn = start_of_sim_cb; + cb_data.obj = nullptr; + cb_data.time = &t; + cb_data.value = nullptr; + cb_data.user_data = nullptr; + vpi_register_cb(&cb_data); + + // cbEndOfSimulation + cb_data.reason = cbEndOfSimulation; + cb_data.cb_rtn = end_of_sim_cb; + vpi_register_cb(&cb_data); +} + +// IEEE 1800 section 37: vlog_startup_routines[] -- null-terminated array of startup functions +extern "C" { +void (*vlog_startup_routines[])() = {register_callbacks, nullptr}; + +// Named bootstrap entrypoint -- used when library is loaded as :my_vpi_bootstrap +void my_vpi_bootstrap() { register_callbacks(); } +} diff --git a/test_regress/t/t_flag_main_vpi.out b/test_regress/t/t_flag_main_vpi.out new file mode 100644 index 000000000..6a9a7f37b --- /dev/null +++ b/test_regress/t/t_flag_main_vpi.out @@ -0,0 +1,2 @@ +*-* All Finished *-* +VPI end of simulation diff --git a/test_regress/t/t_flag_main_vpi.py b/test_regress/t/t_flag_main_vpi.py new file mode 100755 index 000000000..695b70e76 --- /dev/null +++ b/test_regress/t/t_flag_main_vpi.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2025 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt') + +# Compile with --binary --vpi to exercise the VPI-aware generated main. +# Also compile a VPI shared library to be loaded at runtime via +verilator+vpi+. +test.compile(make_pli=True, verilator_flags2=["--binary --vpi --public-flat-rw"]) + +# Run the generated binary; load the VPI library via the +verilator+vpi+ plusarg. +# The VPI library's output (observed 'count' reaching MAX_TICKS, then end-of-sim) is +# checked against the golden .out file. +# Also pass a non-VPI plusarg (skipped by the loader's prefix check) and a bare +# +verilator+vpi+ with an empty payload (skipped by the empty-arg check), so both +# loader-skip branches are exercised alongside the real library load. +test.execute(all_run_flags=[ + "+othertest", "+verilator+vpi+", "+verilator+vpi+" + test.obj_dir + "/libvpi.so" +], + check_finished=True, + expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_flag_main_vpi.v b/test_regress/t/t_flag_main_vpi.v new file mode 100644 index 000000000..c688405ca --- /dev/null +++ b/test_regress/t/t_flag_main_vpi.v @@ -0,0 +1,28 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain +// SPDX-FileCopyrightText: 2025 Wilson Snyder +// SPDX-License-Identifier: CC0-1.0 + +// Test for --binary --vpi runtime library loading. The design provides its +// own clock (so the simulation has Verilog event activity); the VPI library +// (t_flag_main_vpi.cpp), loaded at runtime via +verilator+vpi+, observes +// 'count' via a cbValueChange callback and calls $finish after MAX_TICKS +// edges. Signals are public so the library can reach them by name +// (requires --public-flat-rw). +module t; + + reg clk /*verilator public_flat_rw*/; + reg [31:0] count /*verilator public_flat_rw*/; + + initial begin + clk = 0; + count = 0; + end + + // Self-driving clock: the design itself keeps the simulation alive + always #5 clk = ~clk; + + always @(posedge clk) count <= count + 1; + +endmodule diff --git a/test_regress/t/t_flag_main_vpi_badentry.out b/test_regress/t/t_flag_main_vpi_badentry.out new file mode 100644 index 000000000..6283fa03f --- /dev/null +++ b/test_regress/t/t_flag_main_vpi_badentry.out @@ -0,0 +1,2 @@ +%Error: Cannot find VPI bootstrap 'no_such_fn' in: obj_vlt/t_flag_main_vpi_badentry/libvpi.so +Aborting... diff --git a/test_regress/t/t_flag_main_vpi_badentry.py b/test_regress/t/t_flag_main_vpi_badentry.py new file mode 100755 index 000000000..15398a3e5 --- /dev/null +++ b/test_regress/t/t_flag_main_vpi_badentry.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2025 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt') + +# A valid library loaded with a : entry that does not exist must +# fail with a clear error (the missing-named-bootstrap branch of the loader). +test.top_filename = 't/t_flag_main_vpi.v' +test.pli_filename = 't/t_flag_main_vpi.cpp' + +test.compile(make_pli=True, verilator_flags2=["--binary --vpi --public-flat-rw"]) + +test.execute(fails=True, + all_run_flags=["+verilator+vpi+" + test.obj_dir + "/libvpi.so:no_such_fn"], + expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_flag_main_vpi_badlib.out b/test_regress/t/t_flag_main_vpi_badlib.out new file mode 100644 index 000000000..752708e9e --- /dev/null +++ b/test_regress/t/t_flag_main_vpi_badlib.out @@ -0,0 +1,2 @@ +%Error: Cannot load VPI library: obj_vlt/t_flag_main_vpi_badlib/nonexistent.so +Aborting... diff --git a/test_regress/t/t_flag_main_vpi_badlib.py b/test_regress/t/t_flag_main_vpi_badlib.py new file mode 100755 index 000000000..2ac211d49 --- /dev/null +++ b/test_regress/t/t_flag_main_vpi_badlib.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2025 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt') + +# +verilator+vpi+ pointing at a non-existent library must fail with a clear +# error (the dlopen-failure branch of the runtime loader). +test.top_filename = 't/t_flag_main_vpi.v' + +test.compile(verilator_flags2=["--binary --vpi --public-flat-rw"]) + +# The fatal names the (stable, relative) library path; the platform-specific dlerror() +# detail is emitted on a "- " line, which golden comparison strips, so the .out is portable. +test.execute(fails=True, + all_run_flags=["+verilator+vpi+" + test.obj_dir + "/nonexistent.so"], + expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_flag_main_vpi_bootstrap.out b/test_regress/t/t_flag_main_vpi_bootstrap.out new file mode 100644 index 000000000..6a9a7f37b --- /dev/null +++ b/test_regress/t/t_flag_main_vpi_bootstrap.out @@ -0,0 +1,2 @@ +*-* All Finished *-* +VPI end of simulation diff --git a/test_regress/t/t_flag_main_vpi_bootstrap.py b/test_regress/t/t_flag_main_vpi_bootstrap.py new file mode 100755 index 000000000..4c5c21e70 --- /dev/null +++ b/test_regress/t/t_flag_main_vpi_bootstrap.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2025 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt') + +# Same design and VPI library as t_flag_main_vpi, but loaded via the +# +verilator+vpi+: named-bootstrap syntax instead of vlog_startup_routines[]. +test.top_filename = 't/t_flag_main_vpi.v' +test.pli_filename = 't/t_flag_main_vpi.cpp' + +test.compile(make_pli=True, verilator_flags2=["--binary --vpi --public-flat-rw"]) + +test.execute(all_run_flags=["+verilator+vpi+" + test.obj_dir + "/libvpi.so:my_vpi_bootstrap"], + check_finished=True, + expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_flag_main_vpi_lib2.cpp b/test_regress/t/t_flag_main_vpi_lib2.cpp new file mode 100644 index 000000000..8f5bba74b --- /dev/null +++ b/test_regress/t/t_flag_main_vpi_lib2.cpp @@ -0,0 +1,25 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// DESCRIPTION: Verilator: Second VPI test library for t_flag_main_vpi_multi +// +// A second, independent VPI library loaded alongside t_flag_main_vpi.cpp via a +// repeated +verilator+vpi+ argument, to verify multiple libraries are loaded. +// Its startup routine prints a marker proving it was loaded; it does not drive +// or finish the simulation (the first library does that). +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of either the GNU Lesser General Public License Version 3 +// or the Perl Artistic License Version 2.0. +// SPDX-FileCopyrightText: 2025 Wilson Snyder +// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 +// +//************************************************************************* + +#include "vpi_user.h" + +static void lib2_startup() { vpi_printf(const_cast("second VPI library loaded\n")); } + +// IEEE 1800 section 37: vlog_startup_routines[] -- null-terminated array of startup functions +extern "C" { +void (*vlog_startup_routines[])() = {lib2_startup, nullptr}; +} diff --git a/test_regress/t/t_flag_main_vpi_multi.out b/test_regress/t/t_flag_main_vpi_multi.out new file mode 100644 index 000000000..04f3f5e6d --- /dev/null +++ b/test_regress/t/t_flag_main_vpi_multi.out @@ -0,0 +1,3 @@ +second VPI library loaded +*-* All Finished *-* +VPI end of simulation diff --git a/test_regress/t/t_flag_main_vpi_multi.py b/test_regress/t/t_flag_main_vpi_multi.py new file mode 100755 index 000000000..af3e301ee --- /dev/null +++ b/test_regress/t/t_flag_main_vpi_multi.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2025 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import os +import platform +import vltest_bootstrap + +test.scenarios('vlt') + +# Two +verilator+vpi+ arguments load two independent libraries: the first +# (t_flag_main_vpi.cpp) observes the design and calls $finish; the second +# (t_flag_main_vpi_lib2.cpp) prints a marker proving it too was loaded. +test.top_filename = 't/t_flag_main_vpi.v' +test.pli_filename = 't/t_flag_main_vpi.cpp' + +test.compile(make_pli=True, verilator_flags2=["--binary --vpi --public-flat-rw"]) + +# Build the second VPI library (make_pli only builds libvpi.so), mirroring the +# driver's own pli flags. +root = os.environ['VERILATOR_ROOT'] +pli2_cmd = [ + os.environ['CXX'], "-I" + root + "/include/vltstd", "-I" + root + "/include", "-fPIC", + "-shared" +] +pli2_cmd += (["-Wl,-undefined,dynamic_lookup"] if platform.system() == 'Darwin' else ["-rdynamic"]) +pli2_cmd += ["-o", test.obj_dir + "/libvpi2.so", "t/t_flag_main_vpi_lib2.cpp"] +test.run(logfile=test.obj_dir + "/pli2_compile.log", cmd=pli2_cmd) + +test.execute(all_run_flags=[ + "+verilator+vpi+" + test.obj_dir + "/libvpi.so", + "+verilator+vpi+" + test.obj_dir + "/libvpi2.so" +], + check_finished=True, + expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_flag_main_vpi_noarray.cpp b/test_regress/t/t_flag_main_vpi_noarray.cpp new file mode 100644 index 000000000..02568d282 --- /dev/null +++ b/test_regress/t/t_flag_main_vpi_noarray.cpp @@ -0,0 +1,21 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// DESCRIPTION: Verilator: VPI test library lacking vlog_startup_routines +// +// Loaded via +verilator+vpi+ with no : entry, to exercise +// the loader's error path when a library defines neither a named bootstrap +// nor the vlog_startup_routines[] array. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of either the GNU Lesser General Public License Version 3 +// or the Perl Artistic License Version 2.0. +// SPDX-FileCopyrightText: 2025 Wilson Snyder +// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 +// +//************************************************************************* + +#include "vpi_user.h" + +// Intentionally no vlog_startup_routines and no bootstrap; just some symbol so +// the shared object is non-empty and loads successfully. +extern "C" void t_flag_main_vpi_noarray_present() {} diff --git a/test_regress/t/t_flag_main_vpi_noarray.out b/test_regress/t/t_flag_main_vpi_noarray.out new file mode 100644 index 000000000..a7f54a6af --- /dev/null +++ b/test_regress/t/t_flag_main_vpi_noarray.out @@ -0,0 +1,2 @@ +%Error: Cannot find 'vlog_startup_routines' in: obj_vlt/t_flag_main_vpi_noarray/libvpi.so +Aborting... diff --git a/test_regress/t/t_flag_main_vpi_noarray.py b/test_regress/t/t_flag_main_vpi_noarray.py new file mode 100755 index 000000000..9dd2ac853 --- /dev/null +++ b/test_regress/t/t_flag_main_vpi_noarray.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2025 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt') + +# A library loaded with no : entry that lacks vlog_startup_routines +# must fail with a clear error (the missing-array branch of the loader). +test.top_filename = 't/t_flag_main_vpi.v' +test.pli_filename = 't/t_flag_main_vpi_noarray.cpp' + +test.compile(make_pli=True, verilator_flags2=["--binary --vpi --public-flat-rw"]) + +test.execute(fails=True, + all_run_flags=["+verilator+vpi+" + test.obj_dir + "/libvpi.so"], + expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_flag_main_vpi_noexe.py b/test_regress/t/t_flag_main_vpi_noexe.py new file mode 100755 index 000000000..1f347105b --- /dev/null +++ b/test_regress/t/t_flag_main_vpi_noexe.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2025 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt') + +# --vpi without --exe (no generated main, library-only output): the Makefile +# must still report VM_VPI = 1, but must NOT add the runtime-VPI link flags since +# there is no executable to export VPI symbols from. Exercises the exe()==false +# branch of the VPI link-flag gate in V3EmitMk. +test.top_filename = 't/t_flag_main_vpi.v' + +test.compile(make_main=False, verilator_make_gmake=False, verilator_flags2=["--vpi --timing"]) + +test.file_grep(test.obj_dir + "/V" + test.name + "_classes.mk", r'VM_VPI = 1') +# Without --exe there is no executable to export symbols from or to dlopen into, +# so the runtime-VPI link flags (CFG_LDFLAGS_DYNAMIC/CFG_LDLIBS_DYNAMIC, probed at +# configure time) must not be referenced in the generated Makefile. +mk = test.obj_dir + "/V" + test.name + ".mk" +test.file_grep_not(mk, r'CFG_LDFLAGS_DYNAMIC') +test.file_grep_not(mk, r'CFG_LDLIBS_DYNAMIC') + +test.passes() diff --git a/test_regress/t/t_flag_main_vpi_nowarn.out b/test_regress/t/t_flag_main_vpi_nowarn.out new file mode 100644 index 000000000..e51042279 --- /dev/null +++ b/test_regress/t/t_flag_main_vpi_nowarn.out @@ -0,0 +1,3 @@ +%Warning: COMMAND_LINE:0: +verilator+vpi+ ignored: simulation was not compiled with --vpi '+verilator+vpi+/nonexistent.so' +[0] Hello +*-* All Finished *-* diff --git a/test_regress/t/t_flag_main_vpi_nowarn.py b/test_regress/t/t_flag_main_vpi_nowarn.py new file mode 100755 index 000000000..ab077f4f5 --- /dev/null +++ b/test_regress/t/t_flag_main_vpi_nowarn.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2025 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt') + +# Compile with --binary but WITHOUT --vpi. +# Passing +verilator+vpi+ at runtime should emit a warning, not load anything. +test.compile(top_filename='t/t_flag_main.v', verilator_flags2=["--binary"]) + +# Without --vpi there is no loader, so the plusarg is ignored with a warning (checked via +# the golden .out). The plusarg value is fixed, so the warning text is portable. +test.execute(all_run_flags=["+verilator+vpi+/nonexistent.so"], + check_finished=True, + expect_filename=test.golden_filename) + +test.passes() From 59b85f670b0d379f84469ed4bc620e9a31c5c1ea Mon Sep 17 00:00:00 2001 From: Nick Brereton <85175726+nbstrike@users.noreply.github.com> Date: Sun, 28 Jun 2026 09:30:48 -0400 Subject: [PATCH 04/29] Fix constant pool recache after dead scope removal (#7845) --- src/V3AstNodeOther.h | 4 +- src/V3AstNodes.cpp | 25 ++++++-- src/V3Dead.cpp | 2 +- test_regress/t/t_opt_constpool_recache.py | 21 +++++++ test_regress/t/t_opt_constpool_recache.v | 75 +++++++++++++++++++++++ 5 files changed, 119 insertions(+), 8 deletions(-) create mode 100755 test_regress/t/t_opt_constpool_recache.py create mode 100644 test_regress/t/t_opt_constpool_recache.v diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index 666a3ec22..3c25a9992 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -1000,8 +1000,8 @@ public: // this matters, the caller must handle the dtype difference as appropriate. If 'mergeDType' is // false, the returned VarScope will have _->dtypep()->sameTree(initp->dtypep()) return true. AstVarScope* findConst(AstConst* initp, bool mergeDType); - // Rebuild hashes after potential removals - void reCache(); + // Rebuild hashes and missing variable scopes after potential removals + void rebuildVarScopesAndCache(); }; class AstConstraint final : public AstNode { // Constraint diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index ec26f24a9..aba8a9d0f 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include // Routines for dumping dict fields (NOTE: due to leading ',' they can't be used for first field in @@ -1779,14 +1780,28 @@ AstVarScope* AstConstPool::findConst(AstConst* initp, bool mergeDType) { return varScopep; } -void AstConstPool::reCache() { +void AstConstPool::rebuildVarScopesAndCache() { m_tables.clear(); m_consts.clear(); + std::unordered_map varScopeps; for (AstVarScope* vscp = m_scopep->varsp(); vscp; vscp = VN_CAST(vscp->nextp(), VarScope)) { - AstNode* const valuep = vscp->varp()->valuep(); - const V3Hash hash = V3Hasher::uncachedHash(valuep); - if (VN_IS(valuep, InitArray)) m_tables.emplace(hash.value(), vscp); - if (VN_IS(valuep, Const)) m_consts.emplace(hash.value(), vscp); + varScopeps.emplace(vscp->varp(), vscp); + } + for (AstNode* nodep = m_modp->stmtsp(); nodep; nodep = nodep->nextp()) { + AstVar* const varp = VN_CAST(nodep, Var); + if (!varp) continue; + AstNode* const valuep = varp->valuep(); + if (!valuep) continue; + const bool isTable = VN_IS(valuep, InitArray); + const AstConst* const constp = VN_CAST(valuep, Const); + if (!isTable && !constp) continue; + AstVarScope*& vscp = varScopeps[varp]; + if (!vscp) { + vscp = new AstVarScope{varp->fileline(), m_scopep, varp}; + m_scopep->addVarsp(vscp); + } + if (isTable) m_tables.emplace(V3Hasher::uncachedHash(valuep).value(), vscp); + if (constp) m_consts.emplace(constp->num().toHash().value(), vscp); } } diff --git a/src/V3Dead.cpp b/src/V3Dead.cpp index 677f0b2aa..411ec57eb 100644 --- a/src/V3Dead.cpp +++ b/src/V3Dead.cpp @@ -597,7 +597,7 @@ public: // We may have removed some datatypes, cleanup nodep->typeTablep()->repairCache(); VIsCached::clearCacheTree(); // Removing assignments may affect isPure - nodep->constPoolp()->reCache(); + nodep->constPoolp()->rebuildVarScopesAndCache(); } ~DeadVisitor() override { V3Stats::addStatSum("Optimizations, deadified FTasks", m_statFTasksDeadified); diff --git a/test_regress/t/t_opt_constpool_recache.py b/test_regress/t/t_opt_constpool_recache.py new file mode 100755 index 000000000..ac30d3a16 --- /dev/null +++ b/test_regress/t/t_opt_constpool_recache.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.compile(verilator_flags2=['--binary', '--stats']) + +test.execute() + +test.file_grep(test.stats, r'Optimizations, Cases table normal\s+(\d+)', 1) +test.file_grep(test.stats, r'ConstPool, Constants emitted\s+(\d+)', 1) + +test.passes() diff --git a/test_regress/t/t_opt_constpool_recache.v b/test_regress/t/t_opt_constpool_recache.v new file mode 100644 index 000000000..35ca38a27 --- /dev/null +++ b/test_regress/t/t_opt_constpool_recache.v @@ -0,0 +1,75 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2026 Wilson Snyder +// SPDX-License-Identifier: CC0-1.0 + +// verilog_format: off +`define stop $stop +`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0x exp=%0x (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0); +// verilog_format: on + +module t; + logic clk = 1'b0; + always #5 clk = ~clk; + + logic [31:0] cyc = 0; + logic [3:0] idx; + assign idx = cyc[3:0]; + + // V3Case lowers this to a 512-bit constant-pool lookup table before V3Dead + // calls AstConstPool::rebuildVarScopesAndCache(). + logic [31:0] case_word; + always_comb + case (idx) + 4'h0: case_word = 32'h00000000; + 4'h1: case_word = 32'h00000001; + 4'h2: case_word = 32'h00000002; + 4'h3: case_word = 32'h00000003; + 4'h4: case_word = 32'h00000004; + 4'h5: case_word = 32'h00000005; + 4'h6: case_word = 32'h00000006; + 4'h7: case_word = 32'h00000007; + 4'h8: case_word = 32'h00000008; + 4'h9: case_word = 32'h00000009; + 4'ha: case_word = 32'h0000000a; + 4'hb: case_word = 32'h0000000b; + 4'hc: case_word = 32'h0000000c; + 4'hd: case_word = 32'h0000000d; + 4'he: case_word = 32'h0000000e; + default: case_word = 32'h0000000f; + endcase + + localparam logic [511:0] TABLE = { + 32'h0000000f, + 32'h0000000e, + 32'h0000000d, + 32'h0000000c, + 32'h0000000b, + 32'h0000000a, + 32'h00000009, + 32'h00000008, + 32'h00000007, + 32'h00000006, + 32'h00000005, + 32'h00000004, + 32'h00000003, + 32'h00000002, + 32'h00000001, + 32'h00000000 + }; + + // V3Premit extracts this matching wide constant after V3Dead recached the + // const-pool contents created by V3Case. + logic [31:0] static_word; + assign static_word = TABLE[{idx, 5'b0} +: 32]; + + always @(posedge clk) begin + `checkh(case_word, static_word); + cyc <= cyc + 32'd1; + if (cyc == 32'd32) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end +endmodule From 9448e4366ca6aaaf7ca2eefe9f29a2a302971f90 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 28 Jun 2026 09:42:01 -0400 Subject: [PATCH 05/29] Fix MSVC warning. No functional change. --- include/verilated.cpp | 1 - src/V3LinkInc.cpp | 1 + src/V3Randomize.cpp | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/verilated.cpp b/include/verilated.cpp index a92c6ca5f..a5fdc91ac 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -377,7 +377,6 @@ void VL_PRINTF_MT(const char* formatp, ...) VL_MT_SAFE { } void VL_FFLUSH_MT() VL_MT_SAFE { - va_list ap; VerilatedThreadMsgQueue::post(VerilatedMsg{[=]() { // Verilated::runFlushCallbacks(); }}); diff --git a/src/V3LinkInc.cpp b/src/V3LinkInc.cpp index f8e3c6138..e473325cd 100644 --- a/src/V3LinkInc.cpp +++ b/src/V3LinkInc.cpp @@ -307,6 +307,7 @@ class LinkIncVisitor final : public VNVisitor { return new AstSub{nodep->fileline(), lhsp, rhsp}; case AstAssignCompound::operation::Xor: return new AstXor{nodep->fileline(), lhsp, rhsp}; + default:; // Error below // LCOV_EXCL_LINE } } nodep->v3fatalSrc("Unhandled compound assignment operation"); diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index 95a4d35aa..2786ea305 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -1053,7 +1053,7 @@ class ConstraintExprVisitor final : public VNVisitor { nodep->user1(false); return; } - bool anyChild = false; + int anyChild = false; // Used as bool if (AstNodeExpr* const cp = VN_CAST(nodep->op1p(), NodeExpr)) { propagateUser1InlineRecurse(cp); anyChild |= cp->user1(); From 657d5f6abf269f6dd8b4957bb009fdfd3ced6cd2 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 28 Jun 2026 15:34:50 -0400 Subject: [PATCH 06/29] Tests: Add t_initial_dlyass2 (#5210). Fixes #5210. (Confirms fixed in master earlier). --- test_regress/t/t_initial_dlyass2.py | 18 +++++++++++ test_regress/t/t_initial_dlyass2.v | 50 +++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100755 test_regress/t/t_initial_dlyass2.py create mode 100644 test_regress/t/t_initial_dlyass2.v diff --git a/test_regress/t/t_initial_dlyass2.py b/test_regress/t/t_initial_dlyass2.py new file mode 100755 index 000000000..46d1fe4c0 --- /dev/null +++ b/test_regress/t/t_initial_dlyass2.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile(verilator_flags2=['--binary']) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_initial_dlyass2.v b/test_regress/t/t_initial_dlyass2.v new file mode 100644 index 000000000..02e25a323 --- /dev/null +++ b/test_regress/t/t_initial_dlyass2.v @@ -0,0 +1,50 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2026 Wilson Snyder +// SPDX-License-Identifier: CC0-1.0 + +// verilog_format: off +`define stop $stop +`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); +// verilog_format: on + +module t; + + reg clk = 1; + reg [7:0] d = 0; + reg [7:0] q = 0; + + // Clock generation + always #0.5 clk = ~clk; + + // Input signal generation + initial begin + // verilator lint_off INITIALDLY + d <= 0; + repeat (5) @(posedge clk); + d <= 1; + @(posedge clk); + d <= 2; + @(posedge clk); + d <= 3; + @(posedge clk); + d <= 4; + @(posedge clk); + d <= 0; + repeat (5) @(posedge clk); + $finish; + end + + // Unit under test (flip-flop) + always @(posedge clk) q <= d; + + always @(negedge clk) begin + $display("[%0t] d=%x q=%x", $time, d, q); + if (d == 1) `checkd(q, 0); + if (d == 2) `checkd(q, 1); + if (d == 3) `checkd(q, 2); + if (d == 4) `checkd(q, 3); + end + +endmodule From c4f63583bcbe2436621995436d9661a4be7aa8a4 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 28 Jun 2026 15:40:10 -0400 Subject: [PATCH 07/29] Tests: Fix t_cover_expr_fork data location --- test_regress/t/t_cover_expr_fork.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_regress/t/t_cover_expr_fork.py b/test_regress/t/t_cover_expr_fork.py index 8b6c049d2..57b6e30b1 100755 --- a/test_regress/t/t_cover_expr_fork.py +++ b/test_regress/t/t_cover_expr_fork.py @@ -13,6 +13,6 @@ test.scenarios('simulator') test.compile(verilator_flags2=['--coverage-expr --binary']) -test.execute() +test.execute(all_run_flags=[" +verilator+coverage+file+" + test.obj_dir + "/coverage.dat"]) test.passes() From 6006f91e2edb21d68625d07a2858471d0aeb218a Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 28 Jun 2026 16:07:37 -0400 Subject: [PATCH 08/29] Tests: Add t_queue_array (#6921 test) --- test_regress/t/t_queue_array.py | 18 +++++++ test_regress/t/t_queue_array.v | 87 +++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100755 test_regress/t/t_queue_array.py create mode 100644 test_regress/t/t_queue_array.v diff --git a/test_regress/t/t_queue_array.py b/test_regress/t/t_queue_array.py new file mode 100755 index 000000000..8a938befd --- /dev/null +++ b/test_regress/t/t_queue_array.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_queue_array.v b/test_regress/t/t_queue_array.v new file mode 100644 index 000000000..c729a4654 --- /dev/null +++ b/test_regress/t/t_queue_array.v @@ -0,0 +1,87 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2026 Wilson Snyder +// SPDX-License-Identifier: CC0-1.0 + +// verilog_format: off +`define stop $stop +`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0); +// verilog_format: on + +module t; + + int normal_queue[$]; + int array_of_queues[3][$]; + int aa_of_queues[int][$]; + + function void test_normal_queue(); + $display("[%0t] %m: Testing single queue (int normal_queue [$])", $realtime); + `checkd(normal_queue.size(), 0); + repeat (4) normal_queue.push_back($urandom); + `checkd(normal_queue.size(), 4); + repeat (4) void'(normal_queue.pop_front()); + `checkd(normal_queue.size(), 0); + endfunction + + function void test_array_of_queues(); + $display("[%0t] %m: Testing array of queues (int array_of_queues [3][$])", $realtime); + array_of_queues[0] = {}; + array_of_queues[1] = {}; + array_of_queues[2] = {}; + + for (int i = 0; i < 3; i++) begin + `checkd(array_of_queues[i].size(), 0); + end + + for (int i = 0; i < 3; i++) begin + for (int j = 0; j < 4; j++) begin : push_4_items + array_of_queues[i].push_back($urandom); + $display("[%0t] %m: array_of_queues, pushed item to queue %0d: [0]=%p [1]=%p [2]=%p", + $realtime, i, array_of_queues[0], array_of_queues[1], array_of_queues[2]); + `checkd(array_of_queues[i].size(), j + 1); + end + end + + for (int i = 0; i < 3; i++) begin : pop_4_items_from_each + repeat (4) void'(array_of_queues[i].pop_front()); + `checkd(array_of_queues[i].size(), 0); + end + endfunction + + function void test_aa_of_queues(); + $display("[%0t] %m: Testing associative-array of queues (int aa_of_queues [int][$])", + $realtime); + + aa_of_queues[0] = {}; + aa_of_queues[1] = {}; + aa_of_queues[2] = {}; + + for (int i = 0; i < 3; i++) begin + `checkd(aa_of_queues[i].size(), 0); + end + + for (int i = 0; i < 3; i++) begin + for (int j = 0; j < 4; j++) begin : push_4_items + aa_of_queues[i].push_back($urandom); + $display("[%0t] %m: aa_of_queues, pushed item to queue %0d: [0]=%p [1]=%p [2]=%p", + $realtime, i, aa_of_queues[0], aa_of_queues[1], aa_of_queues[2]); + `checkd(aa_of_queues[i].size(), j + 1); + end + end + + for (int i = 0; i < 3; i++) begin + repeat (4) void'(aa_of_queues[i].pop_front()); + `checkd(aa_of_queues[i].size(), 0); + end + endfunction + + + initial begin + test_normal_queue(); + test_aa_of_queues(); + test_array_of_queues(); + $finish; + end + +endmodule From 276f2f344d88d186af5615afa5679d64ca174d30 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 28 Jun 2026 16:15:54 -0400 Subject: [PATCH 09/29] Commentary: Changes update --- Changes | 32 ++++++++-- docs/spelling.txt | 2 + test_regress/t/t_assert_ctl_pass_actions.v | 55 +++++++++------- .../t/t_assert_ctl_type_runtime_bad.v | 2 +- test_regress/t/t_assert_disabled.v | 6 +- test_regress/t/t_assertcontrol.v | 7 +-- test_regress/t/t_class_member_shadow_type.v | 2 +- test_regress/t/t_constraint_dist_foreach_if.v | 50 +++++++++------ test_regress/t/t_constraint_dist_range.v | 63 ++++++++++++------- test_regress/t/t_cuse_struct_pkg.v | 12 ++-- test_regress/t/t_flag_main_vpi.v | 4 +- test_regress/t/t_opt_constpool_recache.v | 2 +- test_regress/t/t_opt_inline_cfuncs_args.v | 2 +- test_regress/t/t_opt_inline_cfuncs_dup.v | 2 +- .../t/t_virtual_interface_method_sched.v | 12 +++- 15 files changed, 161 insertions(+), 92 deletions(-) diff --git a/Changes b/Changes index 438a8c265..08d60bba0 100644 --- a/Changes +++ b/Changes @@ -32,7 +32,7 @@ Verilator 5.049 devel * Improve `--coverage-fsm` (#7490) (#7529) (#7561) (#7573) (#7619). [Yogish Sekhar] * Change `+verilator+seed` to default to 1, and 0 to randomly select (#7325) (#7516). [Miguel] * Change JSON to include parameter constant mnemonics for FSM Coverage (#7531). [Yogish Sekhar] -* Support assert property 'default disable iff` (#4848) (#7723). [Artur Bieniek, Antmicro Ltd.] +* Support assert property `default disable iff` (#4848) (#7723). [Artur Bieniek, Antmicro Ltd.] * Support printing enum names for %p and %s (#5523) (#7338 repair) (#7521) (#7527). [Nick Brereton] * Support weak `until` / `until_with` property operators (#7290) (#7548) (#7685). [Yilou Wang] * Support `s_eventually` (#7291) (#7508). [Bartłomiej Chmiel, Antmicro Ltd.] @@ -67,6 +67,7 @@ Verilator 5.049 devel * Support property case (#7682) (#7721). [Artur Bieniek, Antmicro Ltd.] * Support `s_until` and `s_until_with`(#7722). [Artur Bieniek, Antmicro Ltd.] * Support covergroup runtime model Phase A1 (#7728). [Matthew Ballance] +* Support hierarchical reference cross members (#7749) (#7820). [Matthew Ballance] * Support reduction XOR/AND operations in constraints (#7753). [Kornel Uriasz, Antmicro Ltd.] * Support NBAs in initial blocks (#7754). [Igor Zaworski, Antmicro Ltd.] * Support assertion control system tasks in classes and interfaces (#7761). [Yilou Wang] @@ -75,6 +76,11 @@ Verilator 5.049 devel * Support $assertcontrol control_type from lock to kill (#7788). [Yilou Wang] * Support unbounded always [m:$] and strong s_always liveness (#7798). [Yilou Wang] * Support method calls on a sub-interface via a virtual interface (#7800). [Yilou Wang] +* Support global $assertcontrol (#7807). [Artur Bieniek, Antmicro Ltd.] +* Support VPI access to unpacked struct members (#7823). [Nick Brereton] +* Support variable-length intersect in SVA sequences (#7835). [Yilou Wang] +* Support dynamic loading of VPI extensions (#7727). [Matthew Ballance] +* Optimize DFG cycle breaking to do less work (#7210). [Geza Lore, Testorrent USA, Inc.] * Optimize emitting to_string() for compiler speedup (#7468). [Jakub Michalski, Antmicro Ltd.] * Optimize additional DFG peephole cases (#7553). [Varun Koyyalagunta, Testorrent USA, Inc.] * Optimize forced signal handling (#7554 partial) (#7572) (#7594) (#7596). [Krzysztof Bieganski, Artur Bieniek, Antmicro Ltd.] @@ -97,7 +103,12 @@ Verilator 5.049 devel * Optimize input combinational logic by change detection (#7784). [Geza Lore, Testorrent USA, Inc.] * Optimize decoder case statements into lookup tables (#7795). [Geza Lore, Testorrent USA, Inc.] * Optimize wide decoder case statements into decoder expressions (#7804). [Geza Lore, Testorrent USA, Inc.] -* Optimize DFG cycle breaking to do less work (#7210). [Geza Lore, Testorrent USA, Inc.] +* Optimize statically known oversize shifts (#7806). [Geza Lore, Testorrent USA, Inc.] +* Optimize generated function inlining (#7811). [Geza Lore, Testorrent USA, Inc.] +* Optimize bit-scan loops into most-set-bit or $countones (#7822). [Thomas Santerre] +* Optimize additional expression patterns (#7824). [Geza Lore, Testorrent USA, Inc.] +* Optimize module inlining heuristic (#7837). [Geza Lore, Testorrent USA, Inc.] +* Fix `$bits` on unpacked structs (#4521) (#7796). [Nick Brereton] * Fix TSP variable ordering for mtasks (#5342) (#7610). [Muzaffer Kal] * Fix inlining static initializer in V3Gate (#5381) (#7503). [Andrew Nolte] [Geza Lore, Testorrent USA, Inc.] * Fix timed nested fork block with disable (#6720) (#7743). [Marco Bartoli] @@ -147,6 +158,7 @@ Verilator 5.049 devel * Fix reference counting for modport task references (#7628). [Nick Brereton] * Fix internal error when handling typedefs containing parameterized class type members (#7635) (#7661). [em2machine] * Fix forceable signal with a procedural continuous assign (#7638) (#7639). [Zubin Jain] +* Fix scheduling of virtual interface method writes (#7641). [Artur Bieniek, Antmicro Ltd.] * Fix implicit conversions of VlWide (#7642). [Geza Lore, Testorrent USA, Inc.] * Fix CASEINCOMPLETE to not warn on `unique0 case` (#7647). * Fix hierarchical coverage counts for duplicate no-inline module instances (#7649). [Yogish Sekhar] @@ -173,17 +185,27 @@ Verilator 5.049 devel * Fix s_eventually in parameterized interfaces (#7741). [Nick Brereton] * Fix dpi export pointers (#7742) (#7751). [Yilin Li] * Fix force on unpacked bit select (#7744) (#7745). [Nikolai Kumar] +* Fix `$` as unsupported coverpoint-bin range bounds (#7750) (#7825). [Matthew Ballance] * Fix FSM detect unchecked casts and variable redeclaration (#7758). [Adam Kostrzewski, Antmicro Ltd.] * Fix no-scope internal error on virtual interface method calls (#7759). [Yilou Wang] -* Fix 'case (_) inside' with x wildcards (#7766). [Geza Lore, Testorrent USA, Inc.] +* Fix `case (_) inside` with x wildcards (#7766). [Geza Lore, Testorrent USA, Inc.] * Fix not failing assertion when RHS of a range window rejects once (#7773). [Artur Bieniek, Antmicro Ltd.] * Fix $fflush and autoflush with --threads (#7782). * Fix out-of-bounds read value for 2-state types (#7785). [Jakub Michalski] * Fix `cover property` of an implication counting vacuous matches (#7789). [Yilou Wang] * Fix randomization of dynamic arrays of objects (#7790). [Ryszard Rozak, Antmicro Ltd.] -* Fix `$bits` on unpacked structs (#4521) (#7796). [Nick Brereton] * Fix randomize() with skipping derived pre/post_randomize (#7799). [Yilou Wang] +* Fix skewed dist operator for arrays (#7802). [Jakub Wasilewski, Antmicro Ltd.] * Fix assertion when loop unrolling failed (#7810). [Geza Lore, Testorrent USA, Inc.] +* Fix CASEINCOMPLETE for all uncovered enum items (#7815) (#7817). [Saksham] +* Fix split optimization nested-class crash (#7826). [Igor Zaworski, Antmicro Ltd.] +* Fix class/var named identically to an enclosing-scope type (#7827) (#7828). [Tom Jackson] +* Fix performance on large package-scoped structs (#7830). [Wolfgang Mayerwieser] +* Fix unclocked concurrent assertion misreported as unsupported (#7831). [Yilou Wang] +* Fix insertion of expression coverage statement (#7832). [Ryszard Rozak, Antmicro Ltd.] +* Fix lifetime of expression coverage variable (#7834). [Ryszard Rozak, Antmicro Ltd.] +* Fix disable iff ignored when its condition is held continuously true (#7841). [Yilou Wang] +* Fix constant pool cache after dead scope removal (#7845). [Nick Brereton] Verilator 5.048 2026-04-26 @@ -520,7 +542,7 @@ Verilator 5.044 2026-01-01 * Support clocking output delay `1step` (#6681). [Ondrej Ille] * Support parsing of dotted `bins_expression` (#6683). [Pawel Kojma, Antmicro Ltd.] * Support constant expression cycle delays in sequences (#6691). [Ryszard Rozak, Antmicro Ltd.] -* Support general global constraints (#6709) (#6711). [Yilou Wang] +* Support general global constraints (#6709) (#6711) (#7833) (#7838). [Yilou Wang] * Support complex std::randomize patterns (#6736) (#6737). [Yilou Wang] * Support `rand_mode` in global constraint gathering (#6740) (#6752). [Yilou Wang] * Support reduction or in constraints (#6840). [Pawel Kojma, Antmicro Ltd.] diff --git a/docs/spelling.txt b/docs/spelling.txt index fa7fae5e9..a9d91f52b 100644 --- a/docs/spelling.txt +++ b/docs/spelling.txt @@ -684,6 +684,7 @@ countones cout covergroup covergroups +coverpoint coverpoints cpp cppstyle @@ -1207,6 +1208,7 @@ typename uint un unbased +unclocked uncomment undef undefineall diff --git a/test_regress/t/t_assert_ctl_pass_actions.v b/test_regress/t/t_assert_ctl_pass_actions.v index 3768f4bd1..3a7065569 100644 --- a/test_regress/t/t_assert_ctl_pass_actions.v +++ b/test_regress/t/t_assert_ctl_pass_actions.v @@ -36,7 +36,8 @@ interface AssertCtlIface; $assertcontrol(3, 2, 1); endfunction function void fail_check(); - assert (0) `stop; else fails++; + assert (0) `stop; + else fails++; endfunction function void run_checks(); assert_off(); @@ -69,12 +70,13 @@ module t; $assertcontrol(3, 2, 1); endfunction function void fail_check(); - assert (0) `stop; else class_fails++; + assert (0) `stop; + else class_fails++; endfunction endclass AssertCtlClass assert_ctl_class; - AssertCtlIface assert_ctl_iface(); + AssertCtlIface assert_ctl_iface (); virtual AssertCtlIface v_assert_ctl_iface = assert_ctl_iface; always #5 clk = !clk; @@ -84,17 +86,17 @@ module t; assert property (@(posedge clk) 1'b0 |-> ##1 1'b1) begin vacuous_passes++; - end else - `stop; + end + else `stop; assert property (@(posedge clk) 1'b1 |-> ##1 1'b1) begin nonvacuous_passes++; - end else - `stop; + end + else `stop; assert property (@(posedge clk) 1'b1 |-> ##1 1'b0) begin - end else - concurrent_fails++; + end + else concurrent_fails++; task automatic tick_and_check(input int exp_vacuous, input int exp_nonvacuous, input int exp_concurrent_fails); @@ -110,62 +112,73 @@ module t; $assertcontrol(4, 16, 1); $assertcontrol(5, 16, 1); - $assertcontrol(3*`IMPURE_ONE, 2*`IMPURE_ONE); + $assertcontrol(3 * `IMPURE_ONE, 2 * `IMPURE_ONE); $assertcontrol(3, 255, 7); $assertcontrol(6, 255, 7); $assertcontrol(8, 255, 7); - assert (1) imm_passes++; else `stop; + assert (1) imm_passes++; + else `stop; `checkd(imm_passes, 1); $assertcontrol(1, 2, 1); $assertcontrol(4, 2, 1); - assert (1) imm_passes++; else `stop; + assert (1) imm_passes++; + else `stop; `checkd(imm_passes, 2); $assertcontrol(2, 2, 1); $assertcontrol(4, 2, 1); - assert (1) imm_passes++; else `stop; + assert (1) imm_passes++; + else `stop; `checkd(imm_passes, 2); $assertcontrol(3, 2, 1); $assertcontrol(1, 2, 1); $assertcontrol(7, 2, 1); - assert (1) imm_passes++; else `stop; + assert (1) imm_passes++; + else `stop; `checkd(imm_passes, 3); $assertcontrol(2, 2, 1); $assertcontrol(7, 2, 1); - assert (1) imm_passes++; else `stop; + assert (1) imm_passes++; + else `stop; `checkd(imm_passes, 3); $assertcontrol(10, 2, 1); - assert (1) imm_passes++; else `stop; + assert (1) imm_passes++; + else `stop; `checkd(imm_passes, 4); $assertcontrol(11, 2, 1); - assert (1) imm_passes++; else `stop; + assert (1) imm_passes++; + else `stop; `checkd(imm_passes, 5); $assertcontrol(6, 2, 1); - assert (0) `stop; else imm_fails++; + assert (0) `stop; + else imm_fails++; `checkd(imm_fails, 1); $assertcontrol(1, 2, 1); $assertcontrol(9, 2, 1); - assert (0) `stop; else imm_fails++; + assert (0) `stop; + else imm_fails++; `checkd(imm_fails, 2); $assertcontrol(2, 2, 1); $assertcontrol(9, 2, 1); - assert (0) `stop; else imm_fails++; + assert (0) `stop; + else imm_fails++; `checkd(imm_fails, 2); $assertcontrol(8, 2, 1); - assert (0) `stop; else imm_fails++; + assert (0) `stop; + else imm_fails++; `checkd(imm_fails, 3); assert_ctl_class.assert_off(); diff --git a/test_regress/t/t_assert_ctl_type_runtime_bad.v b/test_regress/t/t_assert_ctl_type_runtime_bad.v index d35421daf..ab48ce35f 100644 --- a/test_regress/t/t_assert_ctl_type_runtime_bad.v +++ b/test_regress/t/t_assert_ctl_type_runtime_bad.v @@ -14,7 +14,7 @@ module t; initial begin - $assertcontrol(100*`IMPURE_ONE); + $assertcontrol(100 * `IMPURE_ONE); $finish; end endmodule diff --git a/test_regress/t/t_assert_disabled.v b/test_regress/t/t_assert_disabled.v index 447253c68..b09690d85 100644 --- a/test_regress/t/t_assert_disabled.v +++ b/test_regress/t/t_assert_disabled.v @@ -16,10 +16,8 @@ module t ( integer action_hits = 0; integer cyc = 0; - assert property (@(posedge clk) ##1 1'b1) - action_hits++; - else - action_hits--; + assert property (@(posedge clk) ##1 1'b1) action_hits++; + else action_hits--; always @(posedge clk) begin cyc++; diff --git a/test_regress/t/t_assertcontrol.v b/test_regress/t/t_assertcontrol.v index 26f9d360b..5088aa280 100644 --- a/test_regress/t/t_assertcontrol.v +++ b/test_regress/t/t_assertcontrol.v @@ -33,13 +33,12 @@ module t; task automatic run_pass(); assert (1) begin pass_count++; - end else - `stop; + end + else `stop; endtask task automatic run_fail(); - assert (0) - `stop; + assert (0) `stop; else begin fail_count++; end diff --git a/test_regress/t/t_class_member_shadow_type.v b/test_regress/t/t_class_member_shadow_type.v index e0d11a0c7..3e56ba5cd 100644 --- a/test_regress/t/t_class_member_shadow_type.v +++ b/test_regress/t/t_class_member_shadow_type.v @@ -21,7 +21,7 @@ class C; endclass class D; - my_t a; // second use of the type name after the shadowing variable... + my_t a; // second use of the type name after the shadowing variable... my_t my_t; // ... is also legal; both resolve to the $unit typedef endclass diff --git a/test_regress/t/t_constraint_dist_foreach_if.v b/test_regress/t/t_constraint_dist_foreach_if.v index 3ae315711..a8eaedb24 100644 --- a/test_regress/t/t_constraint_dist_foreach_if.v +++ b/test_regress/t/t_constraint_dist_foreach_if.v @@ -13,12 +13,15 @@ // foreach (a[i]) if (gate) a[i] dist {...} class ClsIf; - rand bit [3:0] a [4]; + rand bit [3:0] a[4]; bit gate; constraint c { foreach (a[i]) { if (gate == 1'b1) { - a[i] dist { 4'd0 := 3, [4'd1:4'd4] := 1 }; + a[i] dist { + 4'd0 := 3, + [4'd1 : 4'd4] := 1 + }; } } } @@ -26,22 +29,30 @@ endclass // foreach (a[i]) gate -> a[i] dist {...} class ClsImpl; - rand bit [3:0] a [4]; + rand bit [3:0] a[4]; bit gate; constraint c { foreach (a[i]) { - gate -> (a[i] dist { 4'd0 := 3, [4'd1:4'd4] := 1 }); + gate -> + (a[i] dist { + 4'd0 := 3, + [4'd1 : 4'd4] := 1 + }); } } endclass // foreach (a[i]) gateA -> (gateB -> a[i] dist {...}) -- doubly-nested implication class ClsImplChained; - rand bit [3:0] a [4]; + rand bit [3:0] a[4]; bit gateA, gateB; constraint c { foreach (a[i]) { - gateA -> (gateB -> (a[i] dist { 4'd0 := 3, [4'd1:4'd4] := 1 })); + gateA -> + (gateB -> (a[i] dist { + 4'd0 := 3, + [4'd1 : 4'd4] := 1 + })); } } endclass @@ -59,8 +70,8 @@ module t; `checkd(obj.randomize(), 1) foreach (obj.a[i]) begin if (obj.a[i] > 4) begin - $write("%%Error: %s:%0d: if: value out of dist range: %0d\n", - `__FILE__, `__LINE__, obj.a[i]); + $write("%%Error: %s:%0d: if: value out of dist range: %0d\n", `__FILE__, `__LINE__, + obj.a[i]); $stop; end if (obj.a[i] == 0) seen_zero++; @@ -68,8 +79,9 @@ module t; end end if (seen_zero == 0 || seen_nonzero == 0) begin - $write("%%Error: %s:%0d: dist inside foreach+if: not all buckets hit (zero=%0d nonzero=%0d)\n", - `__FILE__, `__LINE__, seen_zero, seen_nonzero); + $write( + "%%Error: %s:%0d: dist inside foreach+if: not all buckets hit (zero=%0d nonzero=%0d)\n", + `__FILE__, `__LINE__, seen_zero, seen_nonzero); $stop; end end @@ -85,8 +97,8 @@ module t; `checkd(obj.randomize(), 1) foreach (obj.a[i]) begin if (obj.a[i] > 4) begin - $write("%%Error: %s:%0d: ->: value out of dist range: %0d\n", - `__FILE__, `__LINE__, obj.a[i]); + $write("%%Error: %s:%0d: ->: value out of dist range: %0d\n", `__FILE__, `__LINE__, + obj.a[i]); $stop; end if (obj.a[i] == 0) seen_zero++; @@ -94,8 +106,9 @@ module t; end end if (seen_zero == 0 || seen_nonzero == 0) begin - $write("%%Error: %s:%0d: dist inside foreach+->: not all buckets hit (zero=%0d nonzero=%0d)\n", - `__FILE__, `__LINE__, seen_zero, seen_nonzero); + $write( + "%%Error: %s:%0d: dist inside foreach+->: not all buckets hit (zero=%0d nonzero=%0d)\n", + `__FILE__, `__LINE__, seen_zero, seen_nonzero); $stop; end end @@ -112,8 +125,8 @@ module t; `checkd(obj.randomize(), 1) foreach (obj.a[i]) begin if (obj.a[i] > 4) begin - $write("%%Error: %s:%0d: ->->: value out of dist range: %0d\n", - `__FILE__, `__LINE__, obj.a[i]); + $write("%%Error: %s:%0d: ->->: value out of dist range: %0d\n", `__FILE__, `__LINE__, + obj.a[i]); $stop; end if (obj.a[i] == 0) seen_zero++; @@ -121,8 +134,9 @@ module t; end end if (seen_zero == 0 || seen_nonzero == 0) begin - $write("%%Error: %s:%0d: dist inside foreach+->->: not all buckets hit (zero=%0d nonzero=%0d)\n", - `__FILE__, `__LINE__, seen_zero, seen_nonzero); + $write( + "%%Error: %s:%0d: dist inside foreach+->->: not all buckets hit (zero=%0d nonzero=%0d)\n", + `__FILE__, `__LINE__, seen_zero, seen_nonzero); $stop; end end diff --git a/test_regress/t/t_constraint_dist_range.v b/test_regress/t/t_constraint_dist_range.v index fbddaf0a1..88ffe3e0b 100644 --- a/test_regress/t/t_constraint_dist_range.v +++ b/test_regress/t/t_constraint_dist_range.v @@ -14,13 +14,20 @@ // Scalar: uniform over [0:9] (10% each) class DistScalarRange; rand bit [3:0] x; - constraint c { x dist {[4'd0:4'd9] := 1}; } + constraint c { + x dist { + [4'd0 : 4'd9] := 1 + }; + } endclass // Array foreach: uniform over [0:4] (20% each per element) class DistForeachUniform; rand bit [2:0] a[5]; - constraint c { foreach (a[i]) a[i] dist {[3'd0:3'd4] := 1}; } + constraint c { + foreach (a[i]) + a[i] dist {[3'd0 : 3'd4] := 1}; + } endclass // Array foreach: mixed single + range @@ -28,32 +35,50 @@ endclass // 0: 5/14 ~= 35.7%, 1..9: 1/14 ~= 7.1% each class DistForeachMixed; rand bit [3:0] a[5]; - constraint c { foreach (a[i]) a[i] dist {4'd0 := 5, [4'd1:4'd9] := 1}; } + constraint c { + foreach (a[i]) + a[i] dist { + 4'd0 := 5, + [4'd1 : 4'd9] := 1 + }; + } endclass // Scalar signed int: uniform over negative range [-9:0] (10% each) class DistNegRange; rand int x; - constraint c { x dist {[-9:0] := 1}; } + constraint c { + x dist { + [-9 : 0] := 1 + }; + } endclass // Non-constant unsigned range bounds: uniform over [lo_val:hi_val] = [2:7] (6 values) class DistVarRangeUnsigned; rand bit [3:0] x; bit [3:0] lo_val = 4'd2, hi_val = 4'd7; - constraint c { x dist {[lo_val:hi_val] := 1}; } + constraint c { + x dist { + [lo_val : hi_val] := 1 + }; + } endclass // Mixed const/non-const bounds: lo is constant, hi is a variable [1:hi_val] = [1:7] class DistMixedBounds; rand bit [3:0] x; bit [3:0] hi_val = 4'd7; - constraint c { x dist {[4'd1:hi_val] := 1}; } + constraint c { + x dist { + [4'd1 : hi_val] := 1 + }; + } endclass module t; - parameter int N = 2000; // randomize() calls per test - parameter int TOL_PCT = 30; // +-% tolerance on expected counts + parameter int N = 2000; // randomize() calls per test + parameter int TOL_PCT = 30; // +-% tolerance on expected counts initial begin @@ -71,8 +96,7 @@ module t; end cnt[obj.x]++; end - foreach (cnt[v]) - `check_tol(cnt[v], N/10) + foreach (cnt[v]) `check_tol(cnt[v], N / 10) end // --- T2: array foreach uniform [0:4], 5 elements * N calls --- @@ -91,8 +115,7 @@ module t; cnt[obj.a[i]]++; end end - foreach (cnt[v]) - `check_tol(cnt[v], N) + foreach (cnt[v]) `check_tol(cnt[v], N) end // --- T3: array foreach mixed {0:=5, [1:9]:=1}, 5 elements * N calls --- @@ -113,9 +136,8 @@ module t; cnt[obj.a[i]]++; end end - `check_tol(cnt[0], N*5*5/14) - for (int v = 1; v <= 9; v++) - `check_tol(cnt[v], N*5*1/14) + `check_tol(cnt[0], N * 5 * 5 / 14) + for (int v = 1; v <= 9; v++) `check_tol(cnt[v], N * 5 * 1 / 14) end // --- T4: signed int, uniform over negative range [-9:0] --- @@ -131,10 +153,9 @@ module t; $write("%%Error: x=%0d outside valid range [-9:0]\n", obj.x); `stop; end - cnt[obj.x + 9]++; + cnt[obj.x+9]++; end - foreach (cnt[v]) - `check_tol(cnt[v], N/10) + foreach (cnt[v]) `check_tol(cnt[v], N / 10) end // --- T5: non-constant unsigned range bounds [lo_val:hi_val] = [2:7] --- @@ -151,8 +172,7 @@ module t; end cnt[obj.x]++; end - for (int v = 2; v <= 7; v++) - `check_tol(cnt[v], N/6) + for (int v = 2; v <= 7; v++) `check_tol(cnt[v], N / 6) end // --- T6: mixed const/non-const bounds [4'd1:hi_val] = [1:7] --- @@ -169,8 +189,7 @@ module t; end cnt[obj.x]++; end - for (int v = 1; v <= 7; v++) - `check_tol(cnt[v], N/7) + for (int v = 1; v <= 7; v++) `check_tol(cnt[v], N / 7) end $write("*-* All Finished *-*\n"); diff --git a/test_regress/t/t_cuse_struct_pkg.v b/test_regress/t/t_cuse_struct_pkg.v index 197bbe62a..2ff97c8b2 100644 --- a/test_regress/t/t_cuse_struct_pkg.v +++ b/test_regress/t/t_cuse_struct_pkg.v @@ -5,9 +5,7 @@ // SPDX-License-Identifier: CC0-1.0 package pkg; - typedef struct { - logic [7:0] value; - } field_t; + typedef struct {logic [7:0] value;} field_t; typedef struct { field_t f0; field_t f1; @@ -19,11 +17,9 @@ package pkg; } hwif_t; endpackage -module t (/*AUTOARG*/ - // Inputs - clk - ); - input clk; +module t ( + input clk +); import pkg::*; diff --git a/test_regress/t/t_flag_main_vpi.v b/test_regress/t/t_flag_main_vpi.v index c688405ca..6ac03e26e 100644 --- a/test_regress/t/t_flag_main_vpi.v +++ b/test_regress/t/t_flag_main_vpi.v @@ -12,8 +12,8 @@ // (requires --public-flat-rw). module t; - reg clk /*verilator public_flat_rw*/; - reg [31:0] count /*verilator public_flat_rw*/; + reg clk /*verilator public_flat_rw*/; + reg [31:0] count /*verilator public_flat_rw*/; initial begin clk = 0; diff --git a/test_regress/t/t_opt_constpool_recache.v b/test_regress/t/t_opt_constpool_recache.v index 35ca38a27..af77d7409 100644 --- a/test_regress/t/t_opt_constpool_recache.v +++ b/test_regress/t/t_opt_constpool_recache.v @@ -62,7 +62,7 @@ module t; // V3Premit extracts this matching wide constant after V3Dead recached the // const-pool contents created by V3Case. logic [31:0] static_word; - assign static_word = TABLE[{idx, 5'b0} +: 32]; + assign static_word = TABLE[{idx, 5'b0}+:32]; always @(posedge clk) begin `checkh(case_word, static_word); diff --git a/test_regress/t/t_opt_inline_cfuncs_args.v b/test_regress/t/t_opt_inline_cfuncs_args.v index d94ac40c4..74c049939 100644 --- a/test_regress/t/t_opt_inline_cfuncs_args.v +++ b/test_regress/t/t_opt_inline_cfuncs_args.v @@ -5,7 +5,7 @@ // SPDX-License-Identifier: CC0-1.0 module t ( - input wire clk + input wire clk ); integer cyc = 0; diff --git a/test_regress/t/t_opt_inline_cfuncs_dup.v b/test_regress/t/t_opt_inline_cfuncs_dup.v index 2a39fa47e..2d93e20fe 100644 --- a/test_regress/t/t_opt_inline_cfuncs_dup.v +++ b/test_regress/t/t_opt_inline_cfuncs_dup.v @@ -5,7 +5,7 @@ // SPDX-License-Identifier: CC0-1.0 module t ( - input wire clk + input wire clk ); integer cyc = 0; diff --git a/test_regress/t/t_virtual_interface_method_sched.v b/test_regress/t/t_virtual_interface_method_sched.v index 48dc01565..b6586f268 100644 --- a/test_regress/t/t_virtual_interface_method_sched.v +++ b/test_regress/t/t_virtual_interface_method_sched.v @@ -20,7 +20,10 @@ package helper_pkg; endfunction endpackage -interface intf(output logic a, output logic b); +interface intf ( + output logic a, + output logic b +); msg m; event e; @@ -34,7 +37,7 @@ interface intf(output logic a, output logic b); // verilator no_inline_task m.set_context("go_helper"); helper_pkg::bump(); - -> e; + ->e; a <= 1; endtask endinterface @@ -56,7 +59,10 @@ module t; wire b; virtual intf vif; - intf i(a, b); + intf i ( + a, + b + ); initial begin driver d; From cf7e3f791a21904c387235de5add20bcf7bae3c5 Mon Sep 17 00:00:00 2001 From: Joshua Leahy <36183+jleahy@users.noreply.github.com> Date: Mon, 29 Jun 2026 15:56:59 +0100 Subject: [PATCH 10/29] Fix covergroups without --coverage (#7848) (#7849) Fixes #7848. --- docs/CONTRIBUTORS | 1 + include/verilated_covergroup.cpp | 9 +++++++-- src/V3EmitCHeaders.cpp | 3 ++- src/V3EmitCModel.cpp | 3 ++- src/V3Global.cpp | 3 ++- .../t/t_covergroup_cross_no_coverage.py | 20 +++++++++++++++++++ .../t/t_covergroup_option_no_coverage.py | 20 +++++++++++++++++++ 7 files changed, 54 insertions(+), 5 deletions(-) create mode 100755 test_regress/t/t_covergroup_cross_no_coverage.py create mode 100755 test_regress/t/t_covergroup_option_no_coverage.py diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index 10db04fcc..f0e8b1c98 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -146,6 +146,7 @@ Jose Loyola Josep Sans Joseph Nwabueze Josh Redford +Joshua Leahy Julian Carrier Julian Daube Julie Schwartz diff --git a/include/verilated_covergroup.cpp b/include/verilated_covergroup.cpp index 6dc7006f1..c872d5557 100644 --- a/include/verilated_covergroup.cpp +++ b/include/verilated_covergroup.cpp @@ -14,7 +14,8 @@ /// \file /// \brief Verilated functional-coverage collection runtime implementation /// -/// Compiled and linked when "verilator --coverage" is used with covergroups. +/// Linked when covergroups are present. The coverage-database registration +/// is compiled only with "verilator --coverage". /// //============================================================================= @@ -22,7 +23,9 @@ #include "verilated_covergroup.h" -#include "verilated_cov.h" +#if VM_COVERAGE +# include "verilated_cov.h" +#endif void VlCoverpoint::init(const char* hier, uint32_t atLeast, int nBins) { m_hier = hier; @@ -54,6 +57,7 @@ std::string VlCoverpoint::binName(int i) const { return name; } +#if VM_COVERAGE void VlCoverpoint::registerBins(VerilatedCovContext* covcontextp, const char* page) { for (int i = 0; i < binCount(); ++i) { const VlCovNamer& nm = namerFor(i); @@ -76,3 +80,4 @@ void VlCoverpoint::registerBins(VerilatedCovContext* covcontextp, const char* pa } } } +#endif // VM_COVERAGE diff --git a/src/V3EmitCHeaders.cpp b/src/V3EmitCHeaders.cpp index 2a3197112..8b2f2add0 100644 --- a/src/V3EmitCHeaders.cpp +++ b/src/V3EmitCHeaders.cpp @@ -683,7 +683,8 @@ class EmitCHeader final : public EmitCConstInit { if (v3Global.opt.mtasks()) puts("#include \"verilated_threads.h\"\n"); if (v3Global.opt.savable()) puts("#include \"verilated_save.h\"\n"); if (v3Global.opt.coverage()) puts("#include \"verilated_cov.h\"\n"); - if (v3Global.opt.coverage()) puts("#include \"verilated_covergroup.h\"\n"); + if (v3Global.opt.coverage() || v3Global.useCovergroup()) + puts("#include \"verilated_covergroup.h\"\n"); if (v3Global.usesTiming()) puts("#include \"verilated_timing.h\"\n"); if (v3Global.useRandomizeMethods()) puts("#include \"verilated_random.h\"\n"); if (v3Global.usesForce()) puts("#include \"verilated_force.h\"\n"); diff --git a/src/V3EmitCModel.cpp b/src/V3EmitCModel.cpp index 6ddd53e77..034b1e807 100644 --- a/src/V3EmitCModel.cpp +++ b/src/V3EmitCModel.cpp @@ -70,7 +70,8 @@ class EmitCModel final : public EmitCFunc { if (v3Global.opt.mtasks()) puts("#include \"verilated_threads.h\"\n"); if (v3Global.opt.savable()) puts("#include \"verilated_save.h\"\n"); if (v3Global.opt.coverage()) puts("#include \"verilated_cov.h\"\n"); - if (v3Global.opt.coverage()) puts("#include \"verilated_covergroup.h\"\n"); + if (v3Global.opt.coverage() || v3Global.useCovergroup()) + puts("#include \"verilated_covergroup.h\"\n"); if (v3Global.dpi()) puts("#include \"svdpi.h\"\n"); // Declare foreign instances up front to make C++ happy diff --git a/src/V3Global.cpp b/src/V3Global.cpp index 2e7c25fc7..3fd207be3 100644 --- a/src/V3Global.cpp +++ b/src/V3Global.cpp @@ -245,7 +245,8 @@ std::vector V3Global::verilatedCppFiles() { if (v3Global.opt.vpi()) result.emplace_back("verilated_vpi.cpp"); if (v3Global.opt.savable()) result.emplace_back("verilated_save.cpp"); if (v3Global.opt.coverage()) result.emplace_back("verilated_cov.cpp"); - if (v3Global.opt.coverage()) result.emplace_back("verilated_covergroup.cpp"); + if (v3Global.opt.coverage() || v3Global.useCovergroup()) + result.emplace_back("verilated_covergroup.cpp"); for (const string& base : v3Global.opt.traceSourceBases()) result.emplace_back(base + "_c.cpp"); if (v3Global.usesProbDist()) result.emplace_back("verilated_probdist.cpp"); diff --git a/test_regress/t/t_covergroup_cross_no_coverage.py b/test_regress/t/t_covergroup_cross_no_coverage.py new file mode 100755 index 000000000..699c061b8 --- /dev/null +++ b/test_regress/t/t_covergroup_cross_no_coverage.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt_all') +test.top_filename = 't/t_covergroup_cross.v' + +# runs without --coverage +test.compile(verilator_flags2=['--Wno-COVERIGN']) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_covergroup_option_no_coverage.py b/test_regress/t/t_covergroup_option_no_coverage.py new file mode 100755 index 000000000..5f3bb6c6d --- /dev/null +++ b/test_regress/t/t_covergroup_option_no_coverage.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt') +test.top_filename = 't/t_covergroup_option.v' + +# runs without --coverage +test.compile(verilator_flags2=['--Wno-COVERIGN']) + +test.execute() + +test.passes() From 514fa120f590c1c7914385f29d3139f6d45a7748 Mon Sep 17 00:00:00 2001 From: github action Date: Mon, 29 Jun 2026 14:58:00 +0000 Subject: [PATCH 11/29] Apply 'make format' [ci skip] --- include/verilated_covergroup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/verilated_covergroup.cpp b/include/verilated_covergroup.cpp index c872d5557..9bf0fc53f 100644 --- a/include/verilated_covergroup.cpp +++ b/include/verilated_covergroup.cpp @@ -24,7 +24,7 @@ #include "verilated_covergroup.h" #if VM_COVERAGE -# include "verilated_cov.h" +#include "verilated_cov.h" #endif void VlCoverpoint::init(const char* hier, uint32_t atLeast, int nBins) { From e80329a57bfdff59331ae37429953bd254dccf8c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2026 11:03:22 -0400 Subject: [PATCH 12/29] CI: Bump actions/cache from 5.0.5 to 6.1.0 in the everything group (#7854) --- .github/workflows/build-test.yml | 2 +- .github/workflows/reusable-build.yml | 2 +- .github/workflows/reusable-rtlmeter-build.yml | 2 +- .github/workflows/reusable-rtlmeter-run.yml | 2 +- .github/workflows/reusable-test.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index d0dfeccb7..7817a3bf6 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -158,7 +158,7 @@ jobs: with: path: repo - name: Cache $CCACHE_DIR - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v5 with: path: ${{ env.CCACHE_DIR }} key: msbuild-msvc-cmake diff --git a/.github/workflows/reusable-build.yml b/.github/workflows/reusable-build.yml index 5d053cadb..87a4052d7 100644 --- a/.github/workflows/reusable-build.yml +++ b/.github/workflows/reusable-build.yml @@ -68,7 +68,7 @@ jobs: fetch-depth: ${{ inputs.dev-gcov && '0' || '1' }} # Coverage flow needs full history - name: Cache $CCACHE_DIR - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v5 env: CACHE_KEY: ${{ env.CACHE_BASE_KEY }}-ccache with: diff --git a/.github/workflows/reusable-rtlmeter-build.yml b/.github/workflows/reusable-rtlmeter-build.yml index cdfee423a..b38ed62cf 100644 --- a/.github/workflows/reusable-rtlmeter-build.yml +++ b/.github/workflows/reusable-rtlmeter-build.yml @@ -50,7 +50,7 @@ jobs: sudo apt install ccache mold help2man libfl-dev libjemalloc-dev libsystemc-dev - name: Use saved ccache - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v5 with: path: ccache key: rtlmeter-build-ccache-${{ inputs.runs-on }}-${{ inputs.cc }}-${{ inputs.sha }}-${{ github.run_id }}-${{ github.run_attempt }} diff --git a/.github/workflows/reusable-rtlmeter-run.yml b/.github/workflows/reusable-rtlmeter-run.yml index 81aaad405..ab66647db 100644 --- a/.github/workflows/reusable-rtlmeter-run.yml +++ b/.github/workflows/reusable-rtlmeter-run.yml @@ -84,7 +84,7 @@ jobs: - name: Use saved ccache if: ${{ env.CCACHE_DISABLE == 0 }} - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v5 with: path: ${{ env.CCACHE_DIR }} key: rtlmeter-run-ccache-${{ inputs.runs-on }}-${{ inputs.cc }}-${{ inputs.cases }}-${{ inputs.compileArgs }}-${{ github.run_id }}-${{ github.run_attempt }} diff --git a/.github/workflows/reusable-test.yml b/.github/workflows/reusable-test.yml index efc9c50fe..ffec26b84 100644 --- a/.github/workflows/reusable-test.yml +++ b/.github/workflows/reusable-test.yml @@ -67,7 +67,7 @@ jobs: ls -lsha - name: Cache $CCACHE_DIR - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v5 env: CACHE_KEY: ${{ env.CACHE_BASE_KEY }}-ccache2 with: From 6b3e2ce971c3d76fc36295a7c3603922e49deb91 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 29 Jun 2026 22:00:10 -0400 Subject: [PATCH 13/29] Commentary: Changes update --- Changes | 1 + test_regress/t/t_config_libmap_inc.py | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Changes b/Changes index 08d60bba0..9428c6eac 100644 --- a/Changes +++ b/Changes @@ -206,6 +206,7 @@ Verilator 5.049 devel * Fix lifetime of expression coverage variable (#7834). [Ryszard Rozak, Antmicro Ltd.] * Fix disable iff ignored when its condition is held continuously true (#7841). [Yilou Wang] * Fix constant pool cache after dead scope removal (#7845). [Nick Brereton] +* Fix covergroups without --coverage (#7848) (#7849). [Joshua Leahy] Verilator 5.048 2026-04-26 diff --git a/test_regress/t/t_config_libmap_inc.py b/test_regress/t/t_config_libmap_inc.py index 10db367a5..bbe991e93 100755 --- a/test_regress/t/t_config_libmap_inc.py +++ b/test_regress/t/t_config_libmap_inc.py @@ -9,7 +9,6 @@ import vltest_bootstrap -test.scenarios('simulator') test.scenarios('linter') test.lint(verilator_flags2=["-libmap t/t_config_libmap_inc.map"], From 1ea10ba71c2e598687c43d571909b0f81418ceba Mon Sep 17 00:00:00 2001 From: Sergey Chusov <44680536+serge0699@users.noreply.github.com> Date: Wed, 1 Jul 2026 22:58:35 +0300 Subject: [PATCH 14/29] Fix class scope '::' reference through an inherited type parameter (#7844) --- docs/CONTRIBUTORS | 1 + src/V3LinkDot.cpp | 17 +++++-- test_regress/t/t_class_extends_param_scope.py | 18 +++++++ test_regress/t/t_class_extends_param_scope.v | 47 +++++++++++++++++++ 4 files changed, 78 insertions(+), 5 deletions(-) create mode 100644 test_regress/t/t_class_extends_param_scope.py create mode 100644 test_regress/t/t_class_extends_param_scope.v diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index f0e8b1c98..763ac8ac0 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -258,6 +258,7 @@ Samuel Riedel Sean Cross Sebastien Van Cauwenberghe Secturion +Sergey Chusov Sergey Fedorov Sergi Granell Seth Pellegrino diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 7dd5fe3ea..33e2d38b5 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -1013,18 +1013,23 @@ public: if (checkUnresolvedRef(VN_CAST(dtypep, RefDType))) return true; } else if (const AstParamTypeDType* const paramTypep = VN_CAST(symp->nodep(), ParamTypeDType)) { - // ParamTypeDType child may be wrapped in RequireDType or unwrapped + // Before V3Param the declared default is in childDTypep (possibly + // wrapped in a RequireDType); after V3Param it is consumed and the + // bound type is the resolved data type, e.g. a type parameter + // inherited from a specialized base class (REQ #(Item) -> class Item). AstNode* childp = paramTypep->childDTypep(); if (const AstRequireDType* const reqp = VN_CAST(childp, RequireDType)) { childp = reqp->lhsp(); } - if (isValidTypeNode(childp)) return true; - if (checkUnresolvedRef(VN_CAST(childp, RefDType))) return true; + const AstNode* const checkp = childp ? childp : paramTypep->skipRefp(); + if (isValidTypeNode(checkp)) return true; + if (checkUnresolvedRef(VN_CAST(checkp, RefDType))) return true; } return false; } VSymEnt* resolveClassOrPackage(VSymEnt* lookSymp, AstClassOrPackageRef* nodep, bool fallback, - bool classOnly, const string& forWhat) { + bool classOnly, const string& forWhat, + bool deferIfUnresolved = false) { if (nodep->classOrPackageSkipp()) return getNodeSym(nodep->classOrPackageSkipp()); VSymEnt* foundp; VSymEnt* searchSymp = lookSymp; @@ -1050,6 +1055,7 @@ public: nodep->classOrPackageNodep(foundp->nodep()); return foundp; } + if (deferIfUnresolved) return nullptr; const string suggest = suggestSymFallback(lookSymp, nodep->name(), LinkNodeMatcherClassOrPackage{}); nodep->v3error((classOnly ? "Class" : "Package/class") @@ -4758,8 +4764,9 @@ class LinkDotResolveVisitor final : public VNVisitor { VL_RESTORER(m_pinSymp); if (!nodep->classOrPackageSkipp() && nodep->name() != "local::") { + const bool deferIfUnresolved = m_statep->forPrimary() && m_insideClassExtParam; m_statep->resolveClassOrPackage(m_ds.m_dotSymp, nodep, m_ds.m_dotPos != DP_PACKAGE, - false, ":: reference"); + false, ":: reference", deferIfUnresolved); } // ClassRef's have pins, so track diff --git a/test_regress/t/t_class_extends_param_scope.py b/test_regress/t/t_class_extends_param_scope.py new file mode 100644 index 000000000..3cc73805c --- /dev/null +++ b/test_regress/t/t_class_extends_param_scope.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2024 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_class_extends_param_scope.v b/test_regress/t/t_class_extends_param_scope.v new file mode 100644 index 000000000..d60ac9381 --- /dev/null +++ b/test_regress/t/t_class_extends_param_scope.v @@ -0,0 +1,47 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2026 Sergey Chusov +// SPDX-License-Identifier: CC0-1.0 + +// A factory-like static method, as used by UVM's type_id::create(). +class registry #(type T = int); + static function T create(); + T r = new; + return r; + endfunction +endclass + +class item; + int val; + typedef registry#(item) type_id; + function new(); + val = 42; + endfunction +endclass + +class seq_base #(type REQ = int, type RSP = REQ); + REQ req; +endclass + +// Non-parameterized class extending a parameterized base. +// REQ is a type parameter inherited from the (specialized) base class and is +// here used as a '::' class scope: REQ::type_id::create(). Resolving REQ in +// this position requires deferring until after V3Param has bound REQ to item. +class seq extends seq_base #(item); + function int make(); + REQ r; + r = REQ::type_id::create(); + return r.val; + endfunction +endclass + +module t; + seq s; + initial begin + s = new; + if (s.make() != 42) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule From 9c655d379a5c2e952573cc3495dc0ee512a4c08a Mon Sep 17 00:00:00 2001 From: github action Date: Wed, 1 Jul 2026 19:59:37 +0000 Subject: [PATCH 15/29] Apply 'make format' [ci skip] --- test_regress/t/t_class_extends_param_scope.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 test_regress/t/t_class_extends_param_scope.py diff --git a/test_regress/t/t_class_extends_param_scope.py b/test_regress/t/t_class_extends_param_scope.py old mode 100644 new mode 100755 From bb9cad507f74feb8f1ac6d07adcfaa076bc8f369 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 1 Jul 2026 18:15:56 -0400 Subject: [PATCH 16/29] Commentary: Changes update --- Changes | 1 + 1 file changed, 1 insertion(+) diff --git a/Changes b/Changes index 9428c6eac..2963deb07 100644 --- a/Changes +++ b/Changes @@ -207,6 +207,7 @@ Verilator 5.049 devel * Fix disable iff ignored when its condition is held continuously true (#7841). [Yilou Wang] * Fix constant pool cache after dead scope removal (#7845). [Nick Brereton] * Fix covergroups without --coverage (#7848) (#7849). [Joshua Leahy] +* Fix class scope '::' reference through an inherited type parameter (#7844). [Sergey Chusov] Verilator 5.048 2026-04-26 From 848d926ebd4addacacd294dc84e35d9d4ae8078c Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 1 Jul 2026 18:17:03 -0400 Subject: [PATCH 17/29] Version bump --- CMakeLists.txt | 2 +- Changes | 2 +- configure.ac | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eb5682e7b..ce2e8beca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.15) cmake_policy(SET CMP0091 NEW) # Use MSVC_RUNTIME_LIBRARY to select the runtime project( Verilator - VERSION 5.049 + VERSION 5.050 HOMEPAGE_URL https://verilator.org LANGUAGES CXX ) diff --git a/Changes b/Changes index 2963deb07..2774b4ad4 100644 --- a/Changes +++ b/Changes @@ -10,7 +10,7 @@ The changes in each Verilator version are described below. The contributors that suggested or implemented a given issue are shown in []. Thanks! -Verilator 5.049 devel +Verilator 5.050 2026-07-01 ========================== **Important:** diff --git a/configure.ac b/configure.ac index 00d8ac713..81329841c 100644 --- a/configure.ac +++ b/configure.ac @@ -12,7 +12,7 @@ # Then 'make maintainer-dist' #AC_INIT([Verilator],[#.### YYYY-MM-DD]) #AC_INIT([Verilator],[#.### devel]) -AC_INIT([Verilator],[5.049 devel], +AC_INIT([Verilator],[5.050 2026-07-01], [https://verilator.org], [verilator],[https://verilator.org]) From ce4be92a6733329ef1077e13c6357f8e5b525a45 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 1 Jul 2026 18:31:23 -0400 Subject: [PATCH 18/29] devel release --- CMakeLists.txt | 2 +- Changes | 6 ++++++ configure.ac | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ce2e8beca..6fa5e2ffc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.15) cmake_policy(SET CMP0091 NEW) # Use MSVC_RUNTIME_LIBRARY to select the runtime project( Verilator - VERSION 5.050 + VERSION 5.051 HOMEPAGE_URL https://verilator.org LANGUAGES CXX ) diff --git a/Changes b/Changes index 2774b4ad4..1edeaf179 100644 --- a/Changes +++ b/Changes @@ -10,6 +10,12 @@ The changes in each Verilator version are described below. The contributors that suggested or implemented a given issue are shown in []. Thanks! +Verilator 5.051 devel +========================== + +**Other:** + + Verilator 5.050 2026-07-01 ========================== diff --git a/configure.ac b/configure.ac index 81329841c..6376593ad 100644 --- a/configure.ac +++ b/configure.ac @@ -12,7 +12,7 @@ # Then 'make maintainer-dist' #AC_INIT([Verilator],[#.### YYYY-MM-DD]) #AC_INIT([Verilator],[#.### devel]) -AC_INIT([Verilator],[5.050 2026-07-01], +AC_INIT([Verilator],[5.051 devel], [https://verilator.org], [verilator],[https://verilator.org]) From 964474837f02728cb60e032b860fa07e39a7399d Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 1 Jul 2026 19:37:12 -0400 Subject: [PATCH 19/29] Commentary --- docs/guide/connecting.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guide/connecting.rst b/docs/guide/connecting.rst index 1d714ce4e..35ec9742b 100644 --- a/docs/guide/connecting.rst +++ b/docs/guide/connecting.rst @@ -179,7 +179,7 @@ DPI Example In the SYSTEMC example above, if you wanted to import C++ functions into Verilog, put in our.v: -.. code-block:: sv +.. code-block:: import "DPI-C" function int add (input int a, input int b); @@ -211,7 +211,7 @@ Verilator extends the DPI format to allow using the same scheme to efficiently add system functions. Use a dollar-sign prefixed system function name for the import, but note it must be escaped. -.. code-block:: sv +.. code-block:: import "DPI-C" function integer \$myRand; From 853ee5df1796354ff24de19cb7b6cba49a0530f7 Mon Sep 17 00:00:00 2001 From: Jakub Michalski <143384197+jmichalski-ant@users.noreply.github.com> Date: Thu, 2 Jul 2026 12:33:38 +0200 Subject: [PATCH 20/29] Fix DFG misoptimizing bound checks (#7755) Signed-off-by: Jakub Michalski --- src/V3Dfg.cpp | 6 ++++++ src/V3Dfg.h | 2 ++ src/V3DfgPeephole.cpp | 24 +++++++++++---------- test_regress/t/t_dfg_oob_array_access.py | 18 ++++++++++++++++ test_regress/t/t_dfg_oob_array_access.v | 27 ++++++++++++++++++++++++ 5 files changed, 66 insertions(+), 11 deletions(-) create mode 100755 test_regress/t/t_dfg_oob_array_access.py create mode 100644 test_regress/t/t_dfg_oob_array_access.v diff --git a/src/V3Dfg.cpp b/src/V3Dfg.cpp index fc6be54ce..2fd5afb95 100644 --- a/src/V3Dfg.cpp +++ b/src/V3Dfg.cpp @@ -620,6 +620,12 @@ DfgVertex::DfgVertex(DfgGraph& dfg, VDfgType type, FileLine* flp, const DfgDataT dfg.addVertex(*this); } +bool DfgVertex::unsafe() const { + if (is()) return true; + if (is()) return !as()->bitp()->is(); + return false; +} + void DfgVertex::typeCheck(const DfgGraph& dfg) const { #define CHECK(cond, msg) \ diff --git a/src/V3Dfg.h b/src/V3Dfg.h index b93c1c716..d80be4d84 100644 --- a/src/V3Dfg.h +++ b/src/V3Dfg.h @@ -195,6 +195,8 @@ public: UASSERT_OBJ(m_dtype.isPacked(), this, "Non packed vertex has no 'width'"); return m_dtype.size(); } + // Has terminating side-effect + bool unsafe() const; // Type check vertex (for debugging) void typeCheck(const DfgGraph& dfg) const; diff --git a/src/V3DfgPeephole.cpp b/src/V3DfgPeephole.cpp index de92790a8..fa29339fe 100644 --- a/src/V3DfgPeephole.cpp +++ b/src/V3DfgPeephole.cpp @@ -2269,7 +2269,7 @@ class V3DfgPeephole final : public DfgVisitor { } void visit(DfgLogAnd* const vtxp) override { - if (binary(vtxp)) return; + if (binary(vtxp) || vtxp->rhsp()->unsafe()) return; DfgVertex* const lhsp = vtxp->lhsp(); DfgVertex* const rhsp = vtxp->rhsp(); @@ -2287,11 +2287,11 @@ class V3DfgPeephole final : public DfgVisitor { } void visit(DfgLogIf* const vtxp) override { - if (binary(vtxp)) return; + if (binary(vtxp) || vtxp->rhsp()->unsafe()) return; } void visit(DfgLogOr* const vtxp) override { - if (binary(vtxp)) return; + if (binary(vtxp) || vtxp->rhsp()->unsafe()) return; DfgVertex* const lhsp = vtxp->lhsp(); DfgVertex* const rhsp = vtxp->rhsp(); @@ -2890,13 +2890,13 @@ class V3DfgPeephole final : public DfgVisitor { } if (vtxp->dtype() == m_bitDType) { - if (isSame(condp, thenp)) { // a ? a : b becomes a | b + if (isSame(condp, thenp) && !elsep->unsafe()) { // a ? a : b becomes a | b APPLYING(REPLACE_COND_WITH_THEN_BRANCH_COND) { replace(make(vtxp, condp, elsep)); return; } } - if (isSame(condp, elsep)) { // a ? b : a becomes a & b + if (isSame(condp, elsep) && !thenp->unsafe()) { // a ? b : a becomes a & b APPLYING(REPLACE_COND_WITH_ELSE_BRANCH_COND) { replace(make(vtxp, condp, thenp)); return; @@ -2905,28 +2905,28 @@ class V3DfgPeephole final : public DfgVisitor { } if (vtxp->width() <= VL_QUADSIZE) { - if (isZero(thenp)) { // a ? 0 : b becomes ~a & b + if (isZero(thenp) && !elsep->unsafe()) { // a ? 0 : b becomes ~a & b APPLYING(REPLACE_COND_WITH_THEN_BRANCH_ZERO) { DfgVertex* const maskp = replicate(vtxp, make(condp, condp)); replace(make(vtxp, maskp, elsep)); return; } } - if (isOnes(thenp)) { // a ? 1 : b becomes a | b + if (isOnes(thenp) && !elsep->unsafe()) { // a ? 1 : b becomes a | b APPLYING(REPLACE_COND_WITH_THEN_BRANCH_ONES) { DfgVertex* const maskp = replicate(vtxp, condp); replace(make(vtxp, maskp, elsep)); return; } } - if (isZero(elsep)) { // a ? b : 0 becomes a & b + if (isZero(elsep) && !thenp->unsafe()) { // a ? b : 0 becomes a & b APPLYING(REPLACE_COND_WITH_ELSE_BRANCH_ZERO) { DfgVertex* const maskp = replicate(vtxp, condp); replace(make(vtxp, maskp, thenp)); return; } } - if (isOnes(elsep)) { // a ? b : 1 becomes ~a | b + if (isOnes(elsep) && !thenp->unsafe()) { // a ? b : 1 becomes ~a | b APPLYING(REPLACE_COND_WITH_ELSE_BRANCH_ONES) { DfgVertex* const maskp = replicate(vtxp, make(condp, condp)); replace(make(vtxp, maskp, thenp)); @@ -2935,7 +2935,8 @@ class V3DfgPeephole final : public DfgVisitor { } if (DfgOr* const tOrp = thenp->cast()) { - if (isSame(tOrp->lhsp(), elsep)) { // a ? b | c : b becomes b | (a & c) + if (isSame(tOrp->lhsp(), elsep) + && !tOrp->rhsp()->unsafe()) { // a ? b | c : b becomes b | (a & c) APPLYING(REPLACE_COND_THEN_OR_LHS) { DfgVertex* const maskp = replicate(vtxp, condp); DfgAnd* const andp = make(vtxp, maskp, tOrp->rhsp()); @@ -2943,7 +2944,8 @@ class V3DfgPeephole final : public DfgVisitor { return; } } - if (isSame(tOrp->rhsp(), elsep)) { // a ? b | c : c becomes c | (a & b) + if (isSame(tOrp->rhsp(), elsep) + && !tOrp->lhsp()->unsafe()) { // a ? b | c : c becomes c | (a & b) APPLYING(REPLACE_COND_THEN_OR_RHS) { DfgVertex* const maskp = replicate(vtxp, condp); DfgAnd* const andp = make(vtxp, maskp, tOrp->lhsp()); diff --git a/test_regress/t/t_dfg_oob_array_access.py b/test_regress/t/t_dfg_oob_array_access.py new file mode 100755 index 000000000..b7bc5e342 --- /dev/null +++ b/test_regress/t/t_dfg_oob_array_access.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile(verilator_flags2=["-runtime-debug"]) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_dfg_oob_array_access.v b/test_regress/t/t_dfg_oob_array_access.v new file mode 100644 index 000000000..39b3f4d17 --- /dev/null +++ b/test_regress/t/t_dfg_oob_array_access.v @@ -0,0 +1,27 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2026 Antmicro +// SPDX-License-Identifier: CC0-1.0 + + +module t ( + input clk +); + wire mem_wire; + bit [15:0] idx = 65535; + bit mem_reg[0:34000]; + assign mem_wire = mem_reg[idx]; + + always @(posedge clk) begin + if (idx < 65533) begin + $display("oob_val %d", mem_wire); + $write("*-* All Finished *-*\n"); + $finish; + end + else begin + idx <= idx - 1; + mem_reg[idx] <= 0; + end + end +endmodule From 506f703da5ec43ae1709d90b952f50fd36bfcd5e Mon Sep 17 00:00:00 2001 From: Jakub Michalski <143384197+jmichalski-ant@users.noreply.github.com> Date: Thu, 2 Jul 2026 13:16:42 +0200 Subject: [PATCH 21/29] Internals: Remove unused variables in verilated_funcs.h (#7862) Signed-off-by: Jakub Michalski --- include/verilated_funcs.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/include/verilated_funcs.h b/include/verilated_funcs.h index 88da40387..16ed18728 100644 --- a/include/verilated_funcs.h +++ b/include/verilated_funcs.h @@ -1025,14 +1025,10 @@ static inline IData VL_EQ_R(int words, VlQueue q, WDataInP const rwp) VL_PURE } else if (sizeof(T) == 4) { for (int i = 0; (i < wordsInQ + 1); ++i) { nequal |= (q.at(wordsInQ - i) ^ rwp[i]); } } else if (sizeof(T) == 8) { - QData temp = 0; int qSize = q.size() - 1; for (int i = 0; (i < qSize); i += 2) { - temp = q.at(qSize - i); nequal |= (static_cast(q.at(qSize - i)) >> 32 ^ rwp[i + 1]); - temp = rwp[i + 1]; nequal |= (static_cast(q.at(qSize - i)) ^ rwp[i]); - temp = rwp[i]; } } return (nequal == 0); @@ -1042,7 +1038,6 @@ template static inline IData VL_EQ_R(int words, const VlQueue>& q, WDataInP const rwp) VL_PURE { EData nequal = 0; - const int wordsInQ = q.size() * N_Words; if ((q.size() * N_Words) != words) { return false; } int count = 0; for (int qIndex = q.size() - 1; qIndex >= 0; qIndex--) { @@ -1953,7 +1948,6 @@ static inline void VL_STREAMR_RRI(int lbits, VlQueue& to_q, const VlQueue>& from_q, IData rd) VL_MT_SAFE { to_q.clear(); - VL_CONSTEXPR_CXX17 size_t otherSize = 4 * N_Words; VL_CONSTEXPR_CXX17 size_t sizeOfThis = sizeof(T_Value); T_Value temp = 0; for (auto val : from_q) { From 1106e89c84de1f6fef6ef39bc2e84e32cf40d8e1 Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Thu, 2 Jul 2026 14:50:55 +0100 Subject: [PATCH 22/29] Optimize random initialization Fetching a thread-local is relatively expensive. Random initializing wides used to do it once or twice per word, and on short runs for large designs can be noticeably expensive, so fetch once per variable instead. Also remove unused VL_RAND_RESET_{Q,W} functions. --- include/verilated.cpp | 47 +++++++++++++++++---------------------- include/verilated_funcs.h | 4 ---- 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/include/verilated.cpp b/include/verilated.cpp index a5fdc91ac..d981f7c0a 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -563,9 +563,10 @@ IData VL_URANDOM_SEEDED_II(IData seed) VL_MT_SAFE { } IData VL_SCOPED_RAND_RESET_I(int obits, uint64_t scopeHash, uint64_t salt) VL_MT_UNSAFE { - if (Verilated::threadContextp()->randReset() == 0) return 0; + const int randReset = Verilated::threadContextp()->randReset(); + if (randReset == 0) return 0; IData data = ~0; - if (Verilated::threadContextp()->randReset() != 1) { // if 2, randomize + if (randReset != 1) { // if 2, randomize VlRNG rng{Verilated::threadContextp()->randSeed() ^ scopeHash ^ salt}; data = rng.rand64(); } @@ -574,9 +575,10 @@ IData VL_SCOPED_RAND_RESET_I(int obits, uint64_t scopeHash, uint64_t salt) VL_MT } QData VL_SCOPED_RAND_RESET_Q(int obits, uint64_t scopeHash, uint64_t salt) VL_MT_UNSAFE { - if (Verilated::threadContextp()->randReset() == 0) return 0; + const int randReset = Verilated::threadContextp()->randReset(); + if (randReset == 0) return 0; QData data = ~0ULL; - if (Verilated::threadContextp()->randReset() != 1) { // if 2, randomize + if (randReset != 1) { // if 2, randomize VlRNG rng{Verilated::threadContextp()->randSeed() ^ scopeHash ^ salt}; data = rng.rand64(); } @@ -586,10 +588,17 @@ QData VL_SCOPED_RAND_RESET_Q(int obits, uint64_t scopeHash, uint64_t salt) VL_MT WDataOutP VL_SCOPED_RAND_RESET_W(int obits, WDataOutP outwp, uint64_t scopeHash, uint64_t salt) VL_MT_UNSAFE { - if (Verilated::threadContextp()->randReset() != 2) { return VL_RAND_RESET_W(obits, outwp); } - VlRNG rng{Verilated::threadContextp()->randSeed() ^ scopeHash ^ salt}; - for (int i = 0; i < VL_WORDS_I(obits) - 1; ++i) outwp[i] = rng.rand64(); - outwp[VL_WORDS_I(obits) - 1] = rng.rand64() & VL_MASK_E(obits); + const int words = VL_WORDS_I(obits); + const int randReset = Verilated::threadContextp()->randReset(); + if (randReset == 0) { + VL_MEMSET_ZERO_W(outwp, words); + } else if (randReset == 1) { + VL_MEMSET_ONES_W(outwp, words); + } else { + VlRNG rng{Verilated::threadContextp()->randSeed() ^ scopeHash ^ salt}; + for (int i = 0; i < words; ++i) outwp[i] = rng.rand64(); + } + outwp[words - 1] &= VL_MASK_E(obits); return outwp; } @@ -614,30 +623,14 @@ WDataOutP VL_SCOPED_RAND_RESET_ASSIGN_W(int obits, WDataOutP outwp, uint64_t sco } IData VL_RAND_RESET_I(int obits) VL_MT_SAFE { - if (Verilated::threadContextp()->randReset() == 0) return 0; + const int randReset = Verilated::threadContextp()->randReset(); + if (randReset == 0) return 0; IData data = ~0; - if (Verilated::threadContextp()->randReset() != 1) { // if 2, randomize - data = VL_RANDOM_I(); - } + if (randReset != 1) data = VL_RANDOM_I(); // if 2, randomize data &= VL_MASK_I(obits); return data; } -QData VL_RAND_RESET_Q(int obits) VL_MT_SAFE { - if (Verilated::threadContextp()->randReset() == 0) return 0; - QData data = ~0ULL; - if (Verilated::threadContextp()->randReset() != 1) { // if 2, randomize - data = VL_RANDOM_Q(); - } - data &= VL_MASK_Q(obits); - return data; -} - -WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE { - for (int i = 0; i < VL_WORDS_I(obits) - 1; ++i) outwp[i] = VL_RAND_RESET_I(32); - outwp[VL_WORDS_I(obits) - 1] = VL_RAND_RESET_I(32) & VL_MASK_E(obits); - return outwp; -} WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE { // Not inlined to speed up compilation of slowpath code return VL_ZERO_W(obits, outwp); diff --git a/include/verilated_funcs.h b/include/verilated_funcs.h index 16ed18728..349fe44da 100644 --- a/include/verilated_funcs.h +++ b/include/verilated_funcs.h @@ -124,10 +124,6 @@ extern WDataOutP VL_SCOPED_RAND_RESET_ASSIGN_W(int obits, WDataOutP outwp, uint6 /// Random reset a signal of given width (init time only) extern IData VL_RAND_RESET_I(int obits) VL_MT_SAFE; -/// Random reset a signal of given width (init time only) -extern QData VL_RAND_RESET_Q(int obits) VL_MT_SAFE; -/// Random reset a signal of given width (init time only) -extern WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE; /// Zero reset a signal (slow - else use VL_ZERO_W) extern WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE; From 0e371d6e5caf16c7f6a8c49c8fd49d3115f104eb Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Thu, 2 Jul 2026 17:47:09 +0100 Subject: [PATCH 23/29] Fix cleaning purity cache after assertions --- src/V3Assert.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/V3Assert.cpp b/src/V3Assert.cpp index 09f6d1126..6c507c22c 100644 --- a/src/V3Assert.cpp +++ b/src/V3Assert.cpp @@ -1180,6 +1180,8 @@ public: V3Stats::addStat("Assertions, $past variables", m_statPastVars); V3Stats::addStat("Assertions, assertOn checks combined", m_statAssertOnCombined); V3Stats::addStat("Assertions, assertOn checks hoisted", m_statAssertOnHoisted); + // Rewrites can change purity, e.g. by compiling out assertion statements with --no-assert + VIsCached::clearCacheTree(); } }; From b97df914ddcbff470c5a37d3c1bd99d9813f4698 Mon Sep 17 00:00:00 2001 From: Pawel Kojma Date: Fri, 3 Jul 2026 12:37:48 +0200 Subject: [PATCH 24/29] Fix clang++ ambiguous overload of '==' operator (#7863) --- include/verilated_types.h | 18 +++++++++++++- test_regress/t/t_clang_overload.py | 16 ++++++++++++ test_regress/t/t_clang_overload.v | 39 ++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100755 test_regress/t/t_clang_overload.py create mode 100644 test_regress/t/t_clang_overload.v diff --git a/include/verilated_types.h b/include/verilated_types.h index 40847b65e..fd0341a2d 100644 --- a/include/verilated_types.h +++ b/include/verilated_types.h @@ -2069,8 +2069,24 @@ struct VlNull final { operator T*() const { return nullptr; } + template + bool operator==(T* rhs) const { + return !rhs; + } + template + bool operator==(const T* rhs) const { + return !rhs; + } }; -inline bool operator==(const void* ptr, VlNull) { return !ptr; } + +template +inline bool operator==(T* lhs, VlNull) { + return !lhs; +} +template +inline bool operator==(const T* lhs, VlNull) { + return !lhs; +} //=================================================================== // Verilog class reference container diff --git a/test_regress/t/t_clang_overload.py b/test_regress/t/t_clang_overload.py new file mode 100755 index 000000000..0f1f5d0a0 --- /dev/null +++ b/test_regress/t/t_clang_overload.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.compile(verilator_flags2=['--binary', '-Wno-WIDTHTRUNC']) + +test.passes() diff --git a/test_regress/t/t_clang_overload.v b/test_regress/t/t_clang_overload.v new file mode 100644 index 000000000..02f67f60f --- /dev/null +++ b/test_regress/t/t_clang_overload.v @@ -0,0 +1,39 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2026 Antmicro +// SPDX-License-Identifier: CC0-1.0 + +interface irq_if ( + input logic clk, + input logic resetn +); + logic irq; + logic te; + logic halted; + logic fault; + logic wfi; + clocking cb @(posedge clk); + default input #1step output #2ns; + output irq; + output te; + input halted; + input fault; + input wfi; + endclocking + modport DUT_IRQ_PORT(input clk, resetn, output halted, fault, wfi); +endinterface +class base_test_class; + function int foo(); + endfunction + virtual irq_if.DUT_IRQ_PORT irq_vif; + function new(string name); + endfunction + virtual function void build_phase(); + if (irq_vif == null) begin + if (foo()) $display(); + end + endfunction +endclass +module tb_top; +endmodule From 58bd13b623dbb1a8db231aba7d68b07baf0f3d4f Mon Sep 17 00:00:00 2001 From: Dragon-Git <42856316+Dragon-Git@users.noreply.github.com> Date: Fri, 3 Jul 2026 18:38:48 +0800 Subject: [PATCH 25/29] Fix heap-use-after-free in `VlRNG::VlRNG()` (#7865) --- docs/CONTRIBUTORS | 1 + include/verilated_types.h | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index 763ac8ac0..81765f325 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -61,6 +61,7 @@ David Turner Dercury Diego Roux Dominick Grochowina +Dragon-Git Don Williamson Drew Ranck Drew Taussig diff --git a/include/verilated_types.h b/include/verilated_types.h index fd0341a2d..a48b99c4c 100644 --- a/include/verilated_types.h +++ b/include/verilated_types.h @@ -337,6 +337,7 @@ public: ~VlProcess() { if (m_parentp) m_parentp->detach(this); + if (t_currentp == this) t_currentp = m_parentp.get(); } void attach(VlProcess* childp) { m_children.insert(childp); } From a64234e897f43d07c752ed6fe025de5c32b5bd48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eryk=20Szpota=C5=84ski?= <129167091+eszpotanski@users.noreply.github.com> Date: Fri, 3 Jul 2026 17:18:29 +0200 Subject: [PATCH 26/29] Add comments as a branch description in coverage .info files (#7843) Signed-off-by: Eryk Szpotanski --- docs/CONTRIBUTORS | 1 + src/VlcTop.cpp | 12 +- test_regress/t/t_cover_line_cc.info.out | 166 ++++----- test_regress/t/t_cover_toggle_min.info.out | 24 +- test_regress/t/t_vlcov_data_e.dat | 1 + test_regress/t/t_vlcov_hier_report.out | 2 +- test_regress/t/t_vlcov_opt_branch.info.out | 128 +++---- test_regress/t/t_vlcov_opt_expr.info.out | 24 +- test_regress/t/t_vlcov_opt_line.info.out | 15 +- test_regress/t/t_vlcov_opt_toggle.info.out | 188 +++++------ test_regress/t/t_vlcov_opt_user.info.out | 300 ++++++++--------- test_regress/t/t_vlcov_opt_wild.info.out | 369 +++++++++++---------- test_regress/t/t_vlcov_summary_typed.out | 2 +- 13 files changed, 621 insertions(+), 611 deletions(-) diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index 81765f325..24e3ced87 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -70,6 +70,7 @@ Edgar E. Iglesias Eric Mejdrich Eric Müller Eric Rippey +Eryk Szpotański Eunseo Song Ethan Sifferman Eyck Jentzsch diff --git a/src/VlcTop.cpp b/src/VlcTop.cpp index ccaec527e..de5160c2d 100644 --- a/src/VlcTop.cpp +++ b/src/VlcTop.cpp @@ -240,7 +240,7 @@ void VlcTop::writeInfo(const string& filename) { // FNF: // FNH: // Branches: - // BRDA:,,, + // BRDA:,,, // BRF: // BRH: // Line counts: @@ -273,8 +273,14 @@ void VlcTop::writeInfo(const string& filename) { for (const VlcPoint* point : infoPoints) { os << "BRDA:" << sc.lineno() << ","; os << "0,"; - os << point_num << ","; - os << point->count() << "\n"; + if (point->comment().empty()) { + os << point_num; + } else { + std::string comment(point->comment()); + std::replace(comment.begin(), comment.end(), ',', '_'); + os << comment; + } + os << "," << point->count() << "\n"; branchesHit += opt.countOk(point->count()); ++point_num; diff --git a/test_regress/t/t_cover_line_cc.info.out b/test_regress/t/t_cover_line_cc.info.out index 6a04c28bf..fbba38865 100644 --- a/test_regress/t/t_cover_line_cc.info.out +++ b/test_regress/t/t_cover_line_cc.info.out @@ -4,32 +4,32 @@ DA:15,1 DA:18,1 DA:55,10 DA:56,10 -BRDA:56,0,0,10 -BRDA:56,0,1,0 +BRDA:56,0,if,10 +BRDA:56,0,else,0 DA:57,10 DA:58,10 DA:60,9 -BRDA:60,0,0,1 -BRDA:60,0,1,9 +BRDA:60,0,if,1 +BRDA:60,0,else,9 DA:61,9 -BRDA:61,0,0,1 -BRDA:61,0,1,9 +BRDA:61,0,if,1 +BRDA:61,0,else,9 DA:62,1 DA:63,1 DA:66,9 -BRDA:66,0,0,1 -BRDA:66,0,1,9 +BRDA:66,0,if,1 +BRDA:66,0,else,9 DA:67,9 -BRDA:67,0,0,1 -BRDA:67,0,1,9 +BRDA:67,0,if,1 +BRDA:67,0,else,9 DA:69,9 DA:70,9 DA:73,9 -BRDA:73,0,0,1 -BRDA:73,0,1,9 +BRDA:73,0,if,1 +BRDA:73,0,else,9 DA:74,9 -BRDA:74,0,0,1 -BRDA:74,0,1,9 +BRDA:74,0,if,1 +BRDA:74,0,else,9 DA:75,1 DA:76,1 DA:79,9 @@ -41,8 +41,8 @@ DA:87,1 DA:88,1 DA:89,1 DA:91,7 -BRDA:91,0,0,1 -BRDA:91,0,1,7 +BRDA:91,0,if,1 +BRDA:91,0,else,7 DA:92,1 DA:93,1 DA:96,7 @@ -52,67 +52,67 @@ DA:101,0 DA:102,0 DA:104,0 DA:105,10 -BRDA:105,0,0,0 -BRDA:105,0,1,10 +BRDA:105,0,block,0 +BRDA:105,0,block,10 DA:106,10 DA:107,10 -BRDA:107,0,0,0 -BRDA:107,0,1,10 +BRDA:107,0,block,0 +BRDA:107,0,block,10 DA:110,1 DA:111,1 DA:113,1 DA:115,1 DA:120,7 -BRDA:120,0,0,1 -BRDA:120,0,1,7 +BRDA:120,0,if,1 +BRDA:120,0,else,7 DA:121,1 DA:122,1 DA:127,1 DA:129,1 DA:140,20 DA:141,18 -BRDA:141,0,0,2 -BRDA:141,0,1,18 +BRDA:141,0,if,2 +BRDA:141,0,else,18 DA:142,2 DA:145,18 DA:164,20 DA:165,20 DA:166,20 -BRDA:166,0,0,0 -BRDA:166,0,1,20 +BRDA:166,0,if,0 +BRDA:166,0,else,20 DA:168,0 DA:170,18 -BRDA:170,0,0,2 -BRDA:170,0,1,18 +BRDA:170,0,if,2 +BRDA:170,0,else,18 DA:172,2 DA:174,18 DA:188,11 DA:189,11 DA:190,11 -BRDA:190,0,0,11 -BRDA:190,0,1,0 +BRDA:190,0,if,11 +BRDA:190,0,else,0 DA:191,11 DA:194,11 DA:195,11 -BRDA:195,0,0,11 -BRDA:195,0,1,0 +BRDA:195,0,if,11 +BRDA:195,0,else,0 DA:196,11 DA:199,11 DA:200,11 -BRDA:200,0,0,11 -BRDA:200,0,1,0 +BRDA:200,0,if,11 +BRDA:200,0,else,0 DA:201,11 DA:215,10 DA:216,10 DA:219,11 DA:221,11 DA:222,10 -BRDA:222,0,0,1 -BRDA:222,0,1,10 +BRDA:222,0,if,1 +BRDA:222,0,else,10 DA:223,1 DA:225,10 -BRDA:225,0,0,1 -BRDA:225,0,1,10 +BRDA:225,0,if,1 +BRDA:225,0,else,10 DA:226,1 DA:229,11 DA:230,11 @@ -121,12 +121,12 @@ DA:232,11 DA:233,11 DA:253,10 DA:254,9 -BRDA:254,0,0,1 -BRDA:254,0,1,9 +BRDA:254,0,if,1 +BRDA:254,0,else,9 DA:256,1 DA:257,1 -BRDA:257,0,0,0 -BRDA:257,0,1,1 +BRDA:257,0,if,0 +BRDA:257,0,else,1 DA:266,10 DA:267,10 DA:268,1 @@ -139,8 +139,8 @@ DA:277,10 DA:278,10 DA:288,0 DA:289,0 -BRDA:289,0,0,0 -BRDA:289,0,1,0 +BRDA:289,0,if,0 +BRDA:289,0,else,0 DA:290,0 DA:292,0 DA:293,0 @@ -157,66 +157,66 @@ DA:328,10 DA:329,10 DA:330,10 DA:333,31 -BRDA:333,0,0,0 -BRDA:333,0,1,31 +BRDA:333,0,cond_then,0 +BRDA:333,0,cond_else,31 DA:334,28 -BRDA:334,0,0,3 -BRDA:334,0,1,28 +BRDA:334,0,cond_then,3 +BRDA:334,0,cond_else,28 DA:335,1 -BRDA:335,0,0,1 -BRDA:335,0,1,0 +BRDA:335,0,cond_then,1 +BRDA:335,0,cond_else,0 DA:336,10 DA:337,10 -BRDA:337,0,0,10 -BRDA:337,0,1,3 -BRDA:337,0,2,7 +BRDA:337,0,block,10 +BRDA:337,0,cond_then,3 +BRDA:337,0,cond_else,7 DA:338,10 -BRDA:338,0,0,10 -BRDA:338,0,1,0 -BRDA:338,0,2,10 +BRDA:338,0,block,10 +BRDA:338,0,cond_then,0 +BRDA:338,0,cond_else,10 DA:340,19 -BRDA:340,0,0,12 -BRDA:340,0,1,19 -BRDA:340,0,2,7 -BRDA:340,0,3,5 +BRDA:340,0,cond_then,12 +BRDA:340,0,cond_else,19 +BRDA:340,0,cond_then,7 +BRDA:340,0,cond_else,5 DA:343,11 -BRDA:343,0,0,11 -BRDA:343,0,1,0 +BRDA:343,0,cond_then,11 +BRDA:343,0,cond_else,0 DA:349,22 -BRDA:349,0,0,20 -BRDA:349,0,1,22 +BRDA:349,0,cond_then,20 +BRDA:349,0,cond_else,22 DA:352,11 DA:353,10 -BRDA:353,0,0,0 -BRDA:353,0,1,1 -BRDA:353,0,2,1 -BRDA:353,0,3,10 +BRDA:353,0,cond_then,0 +BRDA:353,0,cond_else,1 +BRDA:353,0,if,1 +BRDA:353,0,else,10 DA:354,10 DA:356,11 -BRDA:356,0,0,11 -BRDA:356,0,1,1 -BRDA:356,0,2,10 +BRDA:356,0,block,11 +BRDA:356,0,cond_then,1 +BRDA:356,0,cond_else,10 DA:359,55 -BRDA:359,0,0,11 -BRDA:359,0,1,55 +BRDA:359,0,block,11 +BRDA:359,0,block,55 DA:360,55 DA:362,44 -BRDA:362,0,0,11 -BRDA:362,0,1,11 -BRDA:362,0,2,33 -BRDA:362,0,3,44 +BRDA:362,0,block,11 +BRDA:362,0,cond_then,11 +BRDA:362,0,cond_else,33 +BRDA:362,0,block,44 DA:363,44 DA:366,11 -BRDA:366,0,0,0 -BRDA:366,0,1,11 +BRDA:366,0,if,0 +BRDA:366,0,else,11 DA:367,11 DA:370,10 -BRDA:370,0,0,1 -BRDA:370,0,1,10 +BRDA:370,0,cond_then,1 +BRDA:370,0,cond_else,10 DA:373,10 DA:374,9 -BRDA:374,0,0,1 -BRDA:374,0,1,9 +BRDA:374,0,if,1 +BRDA:374,0,else,9 BRF:83 BRH:32 end_of_record diff --git a/test_regress/t/t_cover_toggle_min.info.out b/test_regress/t/t_cover_toggle_min.info.out index 975b502e0..6cdc747be 100644 --- a/test_regress/t/t_cover_toggle_min.info.out +++ b/test_regress/t/t_cover_toggle_min.info.out @@ -1,20 +1,20 @@ TN:verilator_coverage SF:t/t_cover_toggle_min.v DA:10,1 -BRDA:10,0,0,1 -BRDA:10,0,1,0 -BRDA:10,0,2,0 -BRDA:10,0,3,0 +BRDA:10,0,a[0]:0->1,1 +BRDA:10,0,a[0]:1->0,0 +BRDA:10,0,a[1]:0->1,0 +BRDA:10,0,a[1]:1->0,0 DA:11,1 -BRDA:11,0,0,0 -BRDA:11,0,1,0 -BRDA:11,0,2,1 -BRDA:11,0,3,0 +BRDA:11,0,b[0]:0->1,0 +BRDA:11,0,b[0]:1->0,0 +BRDA:11,0,b[1]:0->1,1 +BRDA:11,0,b[1]:1->0,0 DA:12,1 -BRDA:12,0,0,1 -BRDA:12,0,1,1 -BRDA:12,0,2,1 -BRDA:12,0,3,0 +BRDA:12,0,c[0]:0->1,1 +BRDA:12,0,c[0]:1->0,1 +BRDA:12,0,c[1]:0->1,1 +BRDA:12,0,c[1]:1->0,0 BRF:12 BRH:0 end_of_record diff --git a/test_regress/t/t_vlcov_data_e.dat b/test_regress/t/t_vlcov_data_e.dat index 32c705c59..114d03f03 100644 --- a/test_regress/t/t_vlcov_data_e.dat +++ b/test_regress/t/t_vlcov_data_e.dat @@ -224,3 +224,4 @@ C 'ft/t_cover_line.vl83n10tlinepagev_line/toelsifS83-85htop.t' 1 C 'ft/t_cover_line.vl87n15tlinepagev_line/toelsifS87-89htop.t' 1 C 'ft/t_cover_line.vl91n15tlinepagev_line/toifS91-93htop.t' 1 C 'ft/t_cover_line.vl91n16tlinepagev_line/toelseS96-97htop.t' 7 +C 'ft/t_cover_line.vl91n16tlinepagev_line/totest,testS91-91htop.t' 5 diff --git a/test_regress/t/t_vlcov_hier_report.out b/test_regress/t/t_vlcov_hier_report.out index bc70aa8a1..1c37b8e6a 100644 --- a/test_regress/t/t_vlcov_hier_report.out +++ b/test_regress/t/t_vlcov_hier_report.out @@ -1,6 +1,6 @@ $ verilator_coverage --report summary t/t_vlcov_data_e.dat Coverage Summary: - line : 88.6% ( 39/ 44) + line : 88.9% ( 40/ 45) toggle : 33.3% ( 35/105) branch : 78.1% ( 50/ 64) expr : 66.7% ( 8/ 12) diff --git a/test_regress/t/t_vlcov_opt_branch.info.out b/test_regress/t/t_vlcov_opt_branch.info.out index 45d5b4627..f7850b8c9 100644 --- a/test_regress/t/t_vlcov_opt_branch.info.out +++ b/test_regress/t/t_vlcov_opt_branch.info.out @@ -1,32 +1,32 @@ TN:verilator_coverage SF:t/t_cover_line.v DA:56,10 -BRDA:56,0,0,10 -BRDA:56,0,1,0 +BRDA:56,0,if,10 +BRDA:56,0,else,0 DA:57,10 DA:58,10 DA:60,9 -BRDA:60,0,0,1 -BRDA:60,0,1,9 +BRDA:60,0,if,1 +BRDA:60,0,else,9 DA:61,9 -BRDA:61,0,0,1 -BRDA:61,0,1,9 +BRDA:61,0,if,1 +BRDA:61,0,else,9 DA:62,1 DA:63,1 DA:66,9 -BRDA:66,0,0,1 -BRDA:66,0,1,9 +BRDA:66,0,if,1 +BRDA:66,0,else,9 DA:67,9 -BRDA:67,0,0,1 -BRDA:67,0,1,9 +BRDA:67,0,if,1 +BRDA:67,0,else,9 DA:69,9 DA:70,9 DA:73,9 -BRDA:73,0,0,1 -BRDA:73,0,1,9 +BRDA:73,0,if,1 +BRDA:73,0,else,9 DA:74,9 -BRDA:74,0,0,1 -BRDA:74,0,1,9 +BRDA:74,0,if,1 +BRDA:74,0,else,9 DA:75,1 DA:76,1 DA:79,9 @@ -34,93 +34,93 @@ DA:80,9 DA:105,10 DA:106,10 DA:120,7 -BRDA:120,0,0,1 -BRDA:120,0,1,7 +BRDA:120,0,if,1 +BRDA:120,0,else,7 DA:121,1 DA:122,1 DA:141,18 -BRDA:141,0,0,2 -BRDA:141,0,1,18 +BRDA:141,0,if,2 +BRDA:141,0,else,18 DA:142,2 DA:166,20 -BRDA:166,0,0,0 -BRDA:166,0,1,20 +BRDA:166,0,if,0 +BRDA:166,0,else,20 DA:168,0 DA:170,18 -BRDA:170,0,0,2 -BRDA:170,0,1,18 +BRDA:170,0,if,2 +BRDA:170,0,else,18 DA:172,2 DA:190,1 -BRDA:190,0,0,1 -BRDA:190,0,1,0 +BRDA:190,0,if,1 +BRDA:190,0,else,0 DA:191,1 DA:195,11 -BRDA:195,0,0,11 -BRDA:195,0,1,0 +BRDA:195,0,if,11 +BRDA:195,0,else,0 DA:196,11 DA:200,11 -BRDA:200,0,0,11 -BRDA:200,0,1,0 +BRDA:200,0,if,11 +BRDA:200,0,else,0 DA:201,11 DA:222,10 -BRDA:222,0,0,1 -BRDA:222,0,1,10 +BRDA:222,0,if,1 +BRDA:222,0,else,10 DA:223,1 DA:225,10 -BRDA:225,0,0,1 -BRDA:225,0,1,10 +BRDA:225,0,if,1 +BRDA:225,0,else,10 DA:226,1 DA:253,9 -BRDA:253,0,0,1 -BRDA:253,0,1,9 +BRDA:253,0,if,1 +BRDA:253,0,else,9 DA:255,1 DA:256,1 -BRDA:256,0,0,0 -BRDA:256,0,1,1 +BRDA:256,0,if,0 +BRDA:256,0,else,1 DA:288,0 -BRDA:288,0,0,0 -BRDA:288,0,1,0 +BRDA:288,0,if,0 +BRDA:288,0,else,0 DA:289,0 DA:291,0 DA:292,0 DA:327,31 -BRDA:327,0,0,0 -BRDA:327,0,1,31 +BRDA:327,0,cond_then,0 +BRDA:327,0,cond_else,31 DA:328,28 -BRDA:328,0,0,3 -BRDA:328,0,1,28 +BRDA:328,0,cond_then,3 +BRDA:328,0,cond_else,28 DA:329,21 -BRDA:329,0,0,21 -BRDA:329,0,1,0 +BRDA:329,0,cond_then,21 +BRDA:329,0,cond_else,0 DA:331,7 -BRDA:331,0,0,3 -BRDA:331,0,1,7 +BRDA:331,0,cond_then,3 +BRDA:331,0,cond_else,7 DA:332,10 -BRDA:332,0,0,0 -BRDA:332,0,1,10 +BRDA:332,0,cond_then,0 +BRDA:332,0,cond_else,10 DA:334,19 -BRDA:334,0,0,12 -BRDA:334,0,1,19 -BRDA:334,0,2,7 -BRDA:334,0,3,5 +BRDA:334,0,cond_then,12 +BRDA:334,0,cond_else,19 +BRDA:334,0,cond_then,7 +BRDA:334,0,cond_else,5 DA:337,11 -BRDA:337,0,0,11 -BRDA:337,0,1,0 +BRDA:337,0,cond_then,11 +BRDA:337,0,cond_else,0 DA:343,11 -BRDA:343,0,0,10 -BRDA:343,0,1,11 +BRDA:343,0,cond_then,10 +BRDA:343,0,cond_else,11 DA:347,10 -BRDA:347,0,0,0 -BRDA:347,0,1,1 -BRDA:347,0,2,1 -BRDA:347,0,3,10 +BRDA:347,0,cond_then,0 +BRDA:347,0,cond_else,1 +BRDA:347,0,if,1 +BRDA:347,0,else,10 DA:348,10 DA:350,10 -BRDA:350,0,0,1 -BRDA:350,0,1,10 +BRDA:350,0,cond_then,1 +BRDA:350,0,cond_else,10 DA:360,11 -BRDA:360,0,0,0 -BRDA:360,0,1,11 +BRDA:360,0,if,0 +BRDA:360,0,else,11 DA:361,11 BRF:64 BRH:20 diff --git a/test_regress/t/t_vlcov_opt_expr.info.out b/test_regress/t/t_vlcov_opt_expr.info.out index 33c3c1c89..c83249652 100644 --- a/test_regress/t/t_vlcov_opt_expr.info.out +++ b/test_regress/t/t_vlcov_opt_expr.info.out @@ -1,23 +1,23 @@ TN:verilator_coverage SF:t/t_cover_line.v DA:331,7 -BRDA:331,0,0,7 -BRDA:331,0,1,3 +BRDA:331,0,(((cyc %25 32'sh3) == 32'sh0)==0) => 0,7 +BRDA:331,0,(((cyc %25 32'sh3) == 32'sh0)==1) => 1,3 DA:347,1 -BRDA:347,0,0,1 -BRDA:347,0,1,0 +BRDA:347,0,((cyc > 32'sh5)==0) => 0,1 +BRDA:347,0,((cyc > 32'sh5)==1) => 1,0 DA:350,10 -BRDA:350,0,0,10 -BRDA:350,0,1,1 +BRDA:350,0,((cyc == 32'sh2)==0) => 0,10 +BRDA:350,0,((cyc == 32'sh2)==1) => 1,1 DA:353,11 -BRDA:353,0,0,11 -BRDA:353,0,1,0 +BRDA:353,0,((i < 32'sh5)==0) => 0,11 +BRDA:353,0,((i < 32'sh5)==1) => 1,0 DA:356,11 -BRDA:356,0,0,0 -BRDA:356,0,1,11 +BRDA:356,0,((i > 32'sh4)==0) => 0,0 +BRDA:356,0,((i > 32'sh4)==1) => 1,11 DA:360,11 -BRDA:360,0,0,11 -BRDA:360,0,1,0 +BRDA:360,0,(k==0) => 0,11 +BRDA:360,0,(k==1) => 1,0 BRF:12 BRH:4 end_of_record diff --git a/test_regress/t/t_vlcov_opt_line.info.out b/test_regress/t/t_vlcov_opt_line.info.out index eaba1df5d..c744548c6 100644 --- a/test_regress/t/t_vlcov_opt_line.info.out +++ b/test_regress/t/t_vlcov_opt_line.info.out @@ -10,8 +10,9 @@ DA:87,1 DA:88,1 DA:89,1 DA:91,7 -BRDA:91,0,0,1 -BRDA:91,0,1,7 +BRDA:91,0,if,1 +BRDA:91,0,else,7 +BRDA:91,0,test_test,5 DA:92,1 DA:93,1 DA:96,7 @@ -75,13 +76,13 @@ DA:332,10 DA:346,11 DA:350,11 DA:353,55 -BRDA:353,0,0,11 -BRDA:353,0,1,55 +BRDA:353,0,block,11 +BRDA:353,0,block,55 DA:354,55 DA:356,44 -BRDA:356,0,0,11 -BRDA:356,0,1,44 +BRDA:356,0,block,11 +BRDA:356,0,block,44 DA:357,44 -BRF:6 +BRF:7 BRH:4 end_of_record diff --git a/test_regress/t/t_vlcov_opt_toggle.info.out b/test_regress/t/t_vlcov_opt_toggle.info.out index 7740e44dc..e44fbbbbe 100644 --- a/test_regress/t/t_vlcov_opt_toggle.info.out +++ b/test_regress/t/t_vlcov_opt_toggle.info.out @@ -3,14 +3,14 @@ SF:t/t_cover_line.v DA:12,19 DA:14,2 DA:20,11 -BRDA:20,0,0,11 -BRDA:20,0,1,5 -BRDA:20,0,2,2 -BRDA:20,0,3,1 -BRDA:20,0,4,0 -BRDA:20,0,5,0 -BRDA:20,0,6,0 -BRDA:20,0,7,0 +BRDA:20,0,cyc_copy[0],11 +BRDA:20,0,cyc_copy[1],5 +BRDA:20,0,cyc_copy[2],2 +BRDA:20,0,cyc_copy[3],1 +BRDA:20,0,cyc_copy[4],0 +BRDA:20,0,cyc_copy[5],0 +BRDA:20,0,cyc_copy[6],0 +BRDA:20,0,cyc_copy[7],0 DA:138,38 DA:139,4 DA:159,38 @@ -21,96 +21,96 @@ DA:241,19 DA:242,2 DA:261,19 DA:262,10 -BRDA:262,0,0,10 -BRDA:262,0,1,5 -BRDA:262,0,2,2 -BRDA:262,0,3,1 +BRDA:262,0,cyc4[0],10 +BRDA:262,0,cyc4[1],5 +BRDA:262,0,cyc4[2],2 +BRDA:262,0,cyc4[3],1 DA:309,19 -BRDA:309,0,0,19 -BRDA:309,0,1,11 -BRDA:309,0,2,0 -BRDA:309,0,3,0 -BRDA:309,0,4,0 -BRDA:309,0,5,0 -BRDA:309,0,6,0 -BRDA:309,0,7,0 -BRDA:309,0,8,0 -BRDA:309,0,9,0 -BRDA:309,0,10,0 -BRDA:309,0,11,0 -BRDA:309,0,12,5 -BRDA:309,0,13,0 -BRDA:309,0,14,0 -BRDA:309,0,15,0 -BRDA:309,0,16,0 -BRDA:309,0,17,0 -BRDA:309,0,18,0 -BRDA:309,0,19,0 -BRDA:309,0,20,0 -BRDA:309,0,21,0 -BRDA:309,0,22,0 -BRDA:309,0,23,2 -BRDA:309,0,24,0 -BRDA:309,0,25,0 -BRDA:309,0,26,1 -BRDA:309,0,27,0 -BRDA:309,0,28,0 -BRDA:309,0,29,0 -BRDA:309,0,30,0 -BRDA:309,0,31,0 -BRDA:309,0,32,0 +BRDA:309,0,clk,19 +BRDA:309,0,cyc[0],11 +BRDA:309,0,cyc[10],0 +BRDA:309,0,cyc[11],0 +BRDA:309,0,cyc[12],0 +BRDA:309,0,cyc[13],0 +BRDA:309,0,cyc[14],0 +BRDA:309,0,cyc[15],0 +BRDA:309,0,cyc[16],0 +BRDA:309,0,cyc[17],0 +BRDA:309,0,cyc[18],0 +BRDA:309,0,cyc[19],0 +BRDA:309,0,cyc[1],5 +BRDA:309,0,cyc[20],0 +BRDA:309,0,cyc[21],0 +BRDA:309,0,cyc[22],0 +BRDA:309,0,cyc[23],0 +BRDA:309,0,cyc[24],0 +BRDA:309,0,cyc[25],0 +BRDA:309,0,cyc[26],0 +BRDA:309,0,cyc[27],0 +BRDA:309,0,cyc[28],0 +BRDA:309,0,cyc[29],0 +BRDA:309,0,cyc[2],2 +BRDA:309,0,cyc[30],0 +BRDA:309,0,cyc[31],0 +BRDA:309,0,cyc[3],1 +BRDA:309,0,cyc[4],0 +BRDA:309,0,cyc[5],0 +BRDA:309,0,cyc[6],0 +BRDA:309,0,cyc[7],0 +BRDA:309,0,cyc[8],0 +BRDA:309,0,cyc[9],0 DA:310,19 -BRDA:310,0,0,0 -BRDA:310,0,1,2 -BRDA:310,0,2,19 -BRDA:310,0,3,6 -BRDA:310,0,4,7 -BRDA:310,0,5,1 -BRDA:310,0,6,19 -BRDA:310,0,7,3 -BRDA:310,0,8,0 -BRDA:310,0,9,0 -BRDA:310,0,10,0 +BRDA:310,0,a,0 +BRDA:310,0,b,2 +BRDA:310,0,c,19 +BRDA:310,0,d,6 +BRDA:310,0,e,7 +BRDA:310,0,f,1 +BRDA:310,0,g,19 +BRDA:310,0,h,3 +BRDA:310,0,k,0 +BRDA:310,0,l,0 +BRDA:310,0,m,0 DA:311,1 -BRDA:311,0,0,1 -BRDA:311,0,1,1 -BRDA:311,0,2,0 -BRDA:311,0,3,0 -BRDA:311,0,4,0 -BRDA:311,0,5,0 +BRDA:311,0,tab[0],1 +BRDA:311,0,tab[1],1 +BRDA:311,0,tab[2],0 +BRDA:311,0,tab[3],0 +BRDA:311,0,tab[4],0 +BRDA:311,0,tab[5],0 DA:313,2 -BRDA:313,0,0,0 -BRDA:313,0,1,2 -BRDA:313,0,2,0 -BRDA:313,0,3,0 -BRDA:313,0,4,0 -BRDA:313,0,5,0 -BRDA:313,0,6,0 -BRDA:313,0,7,0 -BRDA:313,0,8,2 -BRDA:313,0,9,0 -BRDA:313,0,10,0 -BRDA:313,0,11,0 -BRDA:313,0,12,0 -BRDA:313,0,13,0 -BRDA:313,0,14,0 -BRDA:313,0,15,0 -BRDA:313,0,16,0 -BRDA:313,0,17,0 -BRDA:313,0,18,0 -BRDA:313,0,19,0 -BRDA:313,0,20,0 -BRDA:313,0,21,0 -BRDA:313,0,22,0 -BRDA:313,0,23,0 -BRDA:313,0,24,0 -BRDA:313,0,25,0 -BRDA:313,0,26,0 -BRDA:313,0,27,0 -BRDA:313,0,28,0 -BRDA:313,0,29,0 -BRDA:313,0,30,0 -BRDA:313,0,31,0 +BRDA:313,0,data[0][0][0],0 +BRDA:313,0,data[0][0][1],2 +BRDA:313,0,data[0][0][2],0 +BRDA:313,0,data[0][0][3],0 +BRDA:313,0,data[0][0][4],0 +BRDA:313,0,data[0][0][5],0 +BRDA:313,0,data[0][0][6],0 +BRDA:313,0,data[0][0][7],0 +BRDA:313,0,data[0][1][0],2 +BRDA:313,0,data[0][1][1],0 +BRDA:313,0,data[0][1][2],0 +BRDA:313,0,data[0][1][3],0 +BRDA:313,0,data[0][1][4],0 +BRDA:313,0,data[0][1][5],0 +BRDA:313,0,data[0][1][6],0 +BRDA:313,0,data[0][1][7],0 +BRDA:313,0,data[1][0][0],0 +BRDA:313,0,data[1][0][1],0 +BRDA:313,0,data[1][0][2],0 +BRDA:313,0,data[1][0][3],0 +BRDA:313,0,data[1][0][4],0 +BRDA:313,0,data[1][0][5],0 +BRDA:313,0,data[1][0][6],0 +BRDA:313,0,data[1][0][7],0 +BRDA:313,0,data[1][1][0],0 +BRDA:313,0,data[1][1][1],0 +BRDA:313,0,data[1][1][2],0 +BRDA:313,0,data[1][1][3],0 +BRDA:313,0,data[1][1][4],0 +BRDA:313,0,data[1][1][5],0 +BRDA:313,0,data[1][1][6],0 +BRDA:313,0,data[1][1][7],0 BRF:94 BRH:6 end_of_record diff --git a/test_regress/t/t_vlcov_opt_user.info.out b/test_regress/t/t_vlcov_opt_user.info.out index e1b47061b..45fd8205a 100644 --- a/test_regress/t/t_vlcov_opt_user.info.out +++ b/test_regress/t/t_vlcov_opt_user.info.out @@ -1,180 +1,180 @@ TN:verilator_coverage SF:t/t_assert_ctl_arg.v DA:49,1 -BRDA:49,0,0,1 -BRDA:49,0,1,1 -BRDA:49,0,2,0 -BRDA:49,0,3,0 -BRDA:49,0,4,0 -BRDA:49,0,5,0 +BRDA:49,0,cover_simple_immediate_49,1 +BRDA:49,0,cover_simple_immediate_stmt_49,1 +BRDA:49,0,cover_final_deferred_immediate_49,0 +BRDA:49,0,cover_observed_deferred_immediate_49,0 +BRDA:49,0,cover_final_deferred_immediate_stmt_49,0 +BRDA:49,0,cover_observed_deferred_immediate_stmt_49,0 DA:51,0 -BRDA:51,0,0,0 -BRDA:51,0,1,0 -BRDA:51,0,2,0 -BRDA:51,0,3,0 -BRDA:51,0,4,0 -BRDA:51,0,5,0 +BRDA:51,0,cover_simple_immediate_51,0 +BRDA:51,0,cover_simple_immediate_stmt_51,0 +BRDA:51,0,cover_final_deferred_immediate_51,0 +BRDA:51,0,cover_observed_deferred_immediate_51,0 +BRDA:51,0,cover_final_deferred_immediate_stmt_51,0 +BRDA:51,0,cover_observed_deferred_immediate_stmt_51,0 DA:56,1 -BRDA:56,0,0,0 -BRDA:56,0,1,0 -BRDA:56,0,2,0 -BRDA:56,0,3,1 -BRDA:56,0,4,0 -BRDA:56,0,5,1 +BRDA:56,0,cover_simple_immediate_56,0 +BRDA:56,0,cover_simple_immediate_stmt_56,0 +BRDA:56,0,cover_final_deferred_immediate_56,0 +BRDA:56,0,cover_observed_deferred_immediate_56,1 +BRDA:56,0,cover_final_deferred_immediate_stmt_56,0 +BRDA:56,0,cover_observed_deferred_immediate_stmt_56,1 DA:58,0 -BRDA:58,0,0,0 -BRDA:58,0,1,0 -BRDA:58,0,2,0 -BRDA:58,0,3,0 -BRDA:58,0,4,0 -BRDA:58,0,5,0 +BRDA:58,0,cover_simple_immediate_58,0 +BRDA:58,0,cover_simple_immediate_stmt_58,0 +BRDA:58,0,cover_final_deferred_immediate_58,0 +BRDA:58,0,cover_observed_deferred_immediate_58,0 +BRDA:58,0,cover_final_deferred_immediate_stmt_58,0 +BRDA:58,0,cover_observed_deferred_immediate_stmt_58,0 DA:63,1 -BRDA:63,0,0,0 -BRDA:63,0,1,0 -BRDA:63,0,2,1 -BRDA:63,0,3,0 -BRDA:63,0,4,1 -BRDA:63,0,5,0 +BRDA:63,0,cover_simple_immediate_63,0 +BRDA:63,0,cover_simple_immediate_stmt_63,0 +BRDA:63,0,cover_final_deferred_immediate_63,1 +BRDA:63,0,cover_observed_deferred_immediate_63,0 +BRDA:63,0,cover_final_deferred_immediate_stmt_63,1 +BRDA:63,0,cover_observed_deferred_immediate_stmt_63,0 DA:65,0 -BRDA:65,0,0,0 -BRDA:65,0,1,0 -BRDA:65,0,2,0 -BRDA:65,0,3,0 -BRDA:65,0,4,0 -BRDA:65,0,5,0 +BRDA:65,0,cover_simple_immediate_65,0 +BRDA:65,0,cover_simple_immediate_stmt_65,0 +BRDA:65,0,cover_final_deferred_immediate_65,0 +BRDA:65,0,cover_observed_deferred_immediate_65,0 +BRDA:65,0,cover_final_deferred_immediate_stmt_65,0 +BRDA:65,0,cover_observed_deferred_immediate_stmt_65,0 DA:69,0 -BRDA:69,0,0,0 -BRDA:69,0,1,0 -BRDA:69,0,2,0 -BRDA:69,0,3,0 -BRDA:69,0,4,0 -BRDA:69,0,5,0 +BRDA:69,0,cover_simple_immediate_69,0 +BRDA:69,0,cover_simple_immediate_stmt_69,0 +BRDA:69,0,cover_final_deferred_immediate_69,0 +BRDA:69,0,cover_observed_deferred_immediate_69,0 +BRDA:69,0,cover_final_deferred_immediate_stmt_69,0 +BRDA:69,0,cover_observed_deferred_immediate_stmt_69,0 DA:71,1 -BRDA:71,0,0,1 -BRDA:71,0,1,1 -BRDA:71,0,2,1 -BRDA:71,0,3,1 -BRDA:71,0,4,1 -BRDA:71,0,5,1 +BRDA:71,0,cover_simple_immediate_71,1 +BRDA:71,0,cover_simple_immediate_stmt_71,1 +BRDA:71,0,cover_final_deferred_immediate_71,1 +BRDA:71,0,cover_observed_deferred_immediate_71,1 +BRDA:71,0,cover_final_deferred_immediate_stmt_71,1 +BRDA:71,0,cover_observed_deferred_immediate_stmt_71,1 DA:73,0 -BRDA:73,0,0,0 -BRDA:73,0,1,0 -BRDA:73,0,2,0 -BRDA:73,0,3,0 -BRDA:73,0,4,0 -BRDA:73,0,5,0 +BRDA:73,0,cover_simple_immediate_73,0 +BRDA:73,0,cover_simple_immediate_stmt_73,0 +BRDA:73,0,cover_final_deferred_immediate_73,0 +BRDA:73,0,cover_observed_deferred_immediate_73,0 +BRDA:73,0,cover_final_deferred_immediate_stmt_73,0 +BRDA:73,0,cover_observed_deferred_immediate_stmt_73,0 DA:76,1 -BRDA:76,0,0,1 -BRDA:76,0,1,1 -BRDA:76,0,2,0 -BRDA:76,0,3,1 -BRDA:76,0,4,0 -BRDA:76,0,5,1 +BRDA:76,0,cover_simple_immediate_76,1 +BRDA:76,0,cover_simple_immediate_stmt_76,1 +BRDA:76,0,cover_final_deferred_immediate_76,0 +BRDA:76,0,cover_observed_deferred_immediate_76,1 +BRDA:76,0,cover_final_deferred_immediate_stmt_76,0 +BRDA:76,0,cover_observed_deferred_immediate_stmt_76,1 DA:78,1 -BRDA:78,0,0,1 -BRDA:78,0,1,1 -BRDA:78,0,2,1 -BRDA:78,0,3,1 -BRDA:78,0,4,1 -BRDA:78,0,5,1 +BRDA:78,0,cover_simple_immediate_78,1 +BRDA:78,0,cover_simple_immediate_stmt_78,1 +BRDA:78,0,cover_final_deferred_immediate_78,1 +BRDA:78,0,cover_observed_deferred_immediate_78,1 +BRDA:78,0,cover_final_deferred_immediate_stmt_78,1 +BRDA:78,0,cover_observed_deferred_immediate_stmt_78,1 DA:80,1 -BRDA:80,0,0,1 -BRDA:80,0,1,1 -BRDA:80,0,2,0 -BRDA:80,0,3,0 -BRDA:80,0,4,0 -BRDA:80,0,5,0 +BRDA:80,0,cover_simple_immediate_80,1 +BRDA:80,0,cover_simple_immediate_stmt_80,1 +BRDA:80,0,cover_final_deferred_immediate_80,0 +BRDA:80,0,cover_observed_deferred_immediate_80,0 +BRDA:80,0,cover_final_deferred_immediate_stmt_80,0 +BRDA:80,0,cover_observed_deferred_immediate_stmt_80,0 DA:82,1 -BRDA:82,0,0,1 -BRDA:82,0,1,1 -BRDA:82,0,2,0 -BRDA:82,0,3,0 -BRDA:82,0,4,0 -BRDA:82,0,5,0 +BRDA:82,0,cover_simple_immediate_82,1 +BRDA:82,0,cover_simple_immediate_stmt_82,1 +BRDA:82,0,cover_final_deferred_immediate_82,0 +BRDA:82,0,cover_observed_deferred_immediate_82,0 +BRDA:82,0,cover_final_deferred_immediate_stmt_82,0 +BRDA:82,0,cover_observed_deferred_immediate_stmt_82,0 DA:84,0 -BRDA:84,0,0,0 -BRDA:84,0,1,0 -BRDA:84,0,2,0 -BRDA:84,0,3,0 -BRDA:84,0,4,0 -BRDA:84,0,5,0 +BRDA:84,0,cover_simple_immediate_84,0 +BRDA:84,0,cover_simple_immediate_stmt_84,0 +BRDA:84,0,cover_final_deferred_immediate_84,0 +BRDA:84,0,cover_observed_deferred_immediate_84,0 +BRDA:84,0,cover_final_deferred_immediate_stmt_84,0 +BRDA:84,0,cover_observed_deferred_immediate_stmt_84,0 DA:86,1 -BRDA:86,0,0,1 -BRDA:86,0,1,1 -BRDA:86,0,2,0 -BRDA:86,0,3,0 -BRDA:86,0,4,0 -BRDA:86,0,5,0 +BRDA:86,0,cover_simple_immediate_86,1 +BRDA:86,0,cover_simple_immediate_stmt_86,1 +BRDA:86,0,cover_final_deferred_immediate_86,0 +BRDA:86,0,cover_observed_deferred_immediate_86,0 +BRDA:86,0,cover_final_deferred_immediate_stmt_86,0 +BRDA:86,0,cover_observed_deferred_immediate_stmt_86,0 DA:88,0 -BRDA:88,0,0,0 -BRDA:88,0,1,0 -BRDA:88,0,2,0 -BRDA:88,0,3,0 -BRDA:88,0,4,0 -BRDA:88,0,5,0 +BRDA:88,0,cover_simple_immediate_88,0 +BRDA:88,0,cover_simple_immediate_stmt_88,0 +BRDA:88,0,cover_final_deferred_immediate_88,0 +BRDA:88,0,cover_observed_deferred_immediate_88,0 +BRDA:88,0,cover_final_deferred_immediate_stmt_88,0 +BRDA:88,0,cover_observed_deferred_immediate_stmt_88,0 DA:90,1 -BRDA:90,0,0,1 -BRDA:90,0,1,1 -BRDA:90,0,2,1 -BRDA:90,0,3,1 -BRDA:90,0,4,1 -BRDA:90,0,5,1 +BRDA:90,0,cover_simple_immediate_90,1 +BRDA:90,0,cover_simple_immediate_stmt_90,1 +BRDA:90,0,cover_final_deferred_immediate_90,1 +BRDA:90,0,cover_observed_deferred_immediate_90,1 +BRDA:90,0,cover_final_deferred_immediate_stmt_90,1 +BRDA:90,0,cover_observed_deferred_immediate_stmt_90,1 DA:92,0 -BRDA:92,0,0,0 -BRDA:92,0,1,0 -BRDA:92,0,2,0 -BRDA:92,0,3,0 -BRDA:92,0,4,0 -BRDA:92,0,5,0 +BRDA:92,0,cover_simple_immediate_92,0 +BRDA:92,0,cover_simple_immediate_stmt_92,0 +BRDA:92,0,cover_final_deferred_immediate_92,0 +BRDA:92,0,cover_observed_deferred_immediate_92,0 +BRDA:92,0,cover_final_deferred_immediate_stmt_92,0 +BRDA:92,0,cover_observed_deferred_immediate_stmt_92,0 DA:97,0 -BRDA:97,0,0,0 -BRDA:97,0,1,0 -BRDA:97,0,2,0 -BRDA:97,0,3,0 -BRDA:97,0,4,0 -BRDA:97,0,5,0 +BRDA:97,0,cover_simple_immediate_97,0 +BRDA:97,0,cover_simple_immediate_stmt_97,0 +BRDA:97,0,cover_final_deferred_immediate_97,0 +BRDA:97,0,cover_observed_deferred_immediate_97,0 +BRDA:97,0,cover_final_deferred_immediate_stmt_97,0 +BRDA:97,0,cover_observed_deferred_immediate_stmt_97,0 DA:100,1 -BRDA:100,0,0,1 -BRDA:100,0,1,1 -BRDA:100,0,2,1 -BRDA:100,0,3,1 -BRDA:100,0,4,1 -BRDA:100,0,5,1 +BRDA:100,0,cover_simple_immediate_100,1 +BRDA:100,0,cover_simple_immediate_stmt_100,1 +BRDA:100,0,cover_final_deferred_immediate_100,1 +BRDA:100,0,cover_observed_deferred_immediate_100,1 +BRDA:100,0,cover_final_deferred_immediate_stmt_100,1 +BRDA:100,0,cover_observed_deferred_immediate_stmt_100,1 DA:103,0 -BRDA:103,0,0,0 -BRDA:103,0,1,0 -BRDA:103,0,2,0 -BRDA:103,0,3,0 -BRDA:103,0,4,0 -BRDA:103,0,5,0 +BRDA:103,0,cover_simple_immediate_103,0 +BRDA:103,0,cover_simple_immediate_stmt_103,0 +BRDA:103,0,cover_final_deferred_immediate_103,0 +BRDA:103,0,cover_observed_deferred_immediate_103,0 +BRDA:103,0,cover_final_deferred_immediate_stmt_103,0 +BRDA:103,0,cover_observed_deferred_immediate_stmt_103,0 DA:106,1 -BRDA:106,0,0,1 -BRDA:106,0,1,1 -BRDA:106,0,2,1 -BRDA:106,0,3,1 -BRDA:106,0,4,1 -BRDA:106,0,5,1 +BRDA:106,0,cover_simple_immediate_106,1 +BRDA:106,0,cover_simple_immediate_stmt_106,1 +BRDA:106,0,cover_final_deferred_immediate_106,1 +BRDA:106,0,cover_observed_deferred_immediate_106,1 +BRDA:106,0,cover_final_deferred_immediate_stmt_106,1 +BRDA:106,0,cover_observed_deferred_immediate_stmt_106,1 DA:108,1 -BRDA:108,0,0,1 -BRDA:108,0,1,1 -BRDA:108,0,2,1 -BRDA:108,0,3,1 -BRDA:108,0,4,1 -BRDA:108,0,5,1 +BRDA:108,0,cover_simple_immediate_108,1 +BRDA:108,0,cover_simple_immediate_stmt_108,1 +BRDA:108,0,cover_final_deferred_immediate_108,1 +BRDA:108,0,cover_observed_deferred_immediate_108,1 +BRDA:108,0,cover_final_deferred_immediate_stmt_108,1 +BRDA:108,0,cover_observed_deferred_immediate_stmt_108,1 DA:110,0 -BRDA:110,0,0,0 -BRDA:110,0,1,0 -BRDA:110,0,2,0 -BRDA:110,0,3,0 -BRDA:110,0,4,0 -BRDA:110,0,5,0 +BRDA:110,0,cover_simple_immediate_110,0 +BRDA:110,0,cover_simple_immediate_stmt_110,0 +BRDA:110,0,cover_final_deferred_immediate_110,0 +BRDA:110,0,cover_observed_deferred_immediate_110,0 +BRDA:110,0,cover_final_deferred_immediate_stmt_110,0 +BRDA:110,0,cover_observed_deferred_immediate_stmt_110,0 DA:112,1 -BRDA:112,0,0,1 -BRDA:112,0,1,1 -BRDA:112,0,2,1 -BRDA:112,0,3,0 -BRDA:112,0,4,1 -BRDA:112,0,5,0 +BRDA:112,0,cover_simple_immediate_112,1 +BRDA:112,0,cover_simple_immediate_stmt_112,1 +BRDA:112,0,cover_final_deferred_immediate_112,1 +BRDA:112,0,cover_observed_deferred_immediate_112,0 +BRDA:112,0,cover_final_deferred_immediate_stmt_112,1 +BRDA:112,0,cover_observed_deferred_immediate_stmt_112,0 DA:192,0 DA:193,0 BRF:150 diff --git a/test_regress/t/t_vlcov_opt_wild.info.out b/test_regress/t/t_vlcov_opt_wild.info.out index efcf737f6..8d8af4f6f 100644 --- a/test_regress/t/t_vlcov_opt_wild.info.out +++ b/test_regress/t/t_vlcov_opt_wild.info.out @@ -5,42 +5,42 @@ DA:14,2 DA:15,1 DA:18,1 DA:20,11 -BRDA:20,0,0,11 -BRDA:20,0,1,5 -BRDA:20,0,2,2 -BRDA:20,0,3,1 -BRDA:20,0,4,0 -BRDA:20,0,5,0 -BRDA:20,0,6,0 -BRDA:20,0,7,0 +BRDA:20,0,cyc_copy[0],11 +BRDA:20,0,cyc_copy[1],5 +BRDA:20,0,cyc_copy[2],2 +BRDA:20,0,cyc_copy[3],1 +BRDA:20,0,cyc_copy[4],0 +BRDA:20,0,cyc_copy[5],0 +BRDA:20,0,cyc_copy[6],0 +BRDA:20,0,cyc_copy[7],0 DA:55,10 DA:56,10 -BRDA:56,0,0,10 -BRDA:56,0,1,0 +BRDA:56,0,if,10 +BRDA:56,0,else,0 DA:57,10 DA:58,10 DA:60,9 -BRDA:60,0,0,1 -BRDA:60,0,1,9 +BRDA:60,0,if,1 +BRDA:60,0,else,9 DA:61,9 -BRDA:61,0,0,1 -BRDA:61,0,1,9 +BRDA:61,0,if,1 +BRDA:61,0,else,9 DA:62,1 DA:63,1 DA:66,9 -BRDA:66,0,0,1 -BRDA:66,0,1,9 +BRDA:66,0,if,1 +BRDA:66,0,else,9 DA:67,9 -BRDA:67,0,0,1 -BRDA:67,0,1,9 +BRDA:67,0,if,1 +BRDA:67,0,else,9 DA:69,9 DA:70,9 DA:73,9 -BRDA:73,0,0,1 -BRDA:73,0,1,9 +BRDA:73,0,if,1 +BRDA:73,0,else,9 DA:74,9 -BRDA:74,0,0,1 -BRDA:74,0,1,9 +BRDA:74,0,if,1 +BRDA:74,0,else,9 DA:75,1 DA:76,1 DA:79,9 @@ -52,8 +52,9 @@ DA:87,1 DA:88,1 DA:89,1 DA:91,7 -BRDA:91,0,0,1 -BRDA:91,0,1,7 +BRDA:91,0,if,1 +BRDA:91,0,else,7 +BRDA:91,0,test_test,5 DA:92,1 DA:93,1 DA:96,7 @@ -63,19 +64,19 @@ DA:101,0 DA:102,0 DA:104,0 DA:105,10 -BRDA:105,0,0,0 -BRDA:105,0,1,10 +BRDA:105,0,block,0 +BRDA:105,0,if,10 DA:106,10 -BRDA:106,0,0,0 -BRDA:106,0,1,10 +BRDA:106,0,block,0 +BRDA:106,0,if,10 DA:107,0 DA:110,1 DA:111,1 DA:113,1 DA:115,1 DA:120,7 -BRDA:120,0,0,1 -BRDA:120,0,1,7 +BRDA:120,0,if,1 +BRDA:120,0,else,7 DA:121,1 DA:122,1 DA:127,1 @@ -84,8 +85,8 @@ DA:138,38 DA:139,4 DA:140,20 DA:141,18 -BRDA:141,0,0,2 -BRDA:141,0,1,18 +BRDA:141,0,if,2 +BRDA:141,0,else,18 DA:142,2 DA:145,18 DA:159,38 @@ -93,29 +94,29 @@ DA:160,4 DA:164,20 DA:165,20 DA:166,20 -BRDA:166,0,0,0 -BRDA:166,0,1,20 +BRDA:166,0,if,0 +BRDA:166,0,else,20 DA:168,0 DA:170,18 -BRDA:170,0,0,2 -BRDA:170,0,1,18 +BRDA:170,0,if,2 +BRDA:170,0,else,18 DA:172,2 DA:174,18 DA:188,1 DA:189,1 DA:190,1 -BRDA:190,0,0,1 -BRDA:190,0,1,0 +BRDA:190,0,if,1 +BRDA:190,0,else,0 DA:191,1 DA:194,11 DA:195,11 -BRDA:195,0,0,11 -BRDA:195,0,1,0 +BRDA:195,0,if,11 +BRDA:195,0,else,0 DA:196,11 DA:199,11 DA:200,11 -BRDA:200,0,0,11 -BRDA:200,0,1,0 +BRDA:200,0,if,11 +BRDA:200,0,else,0 DA:201,11 DA:210,19 DA:211,2 @@ -124,12 +125,12 @@ DA:216,10 DA:219,11 DA:221,11 DA:222,10 -BRDA:222,0,0,1 -BRDA:222,0,1,10 +BRDA:222,0,if,1 +BRDA:222,0,else,10 DA:223,1 DA:225,10 -BRDA:225,0,0,1 -BRDA:225,0,1,10 +BRDA:225,0,if,1 +BRDA:225,0,else,10 DA:226,1 DA:229,11 DA:230,1 @@ -139,18 +140,18 @@ DA:241,19 DA:242,2 DA:252,10 DA:253,9 -BRDA:253,0,0,1 -BRDA:253,0,1,9 +BRDA:253,0,if,1 +BRDA:253,0,else,9 DA:255,1 DA:256,1 -BRDA:256,0,0,0 -BRDA:256,0,1,1 +BRDA:256,0,if,0 +BRDA:256,0,else,1 DA:261,19 DA:262,10 -BRDA:262,0,0,10 -BRDA:262,0,1,5 -BRDA:262,0,2,2 -BRDA:262,0,3,1 +BRDA:262,0,cyc4[0],10 +BRDA:262,0,cyc4[1],5 +BRDA:262,0,cyc4[2],2 +BRDA:262,0,cyc4[3],1 DA:265,10 DA:266,10 DA:267,1 @@ -163,8 +164,8 @@ DA:276,10 DA:277,10 DA:287,0 DA:288,0 -BRDA:288,0,0,0 -BRDA:288,0,1,0 +BRDA:288,0,if,0 +BRDA:288,0,else,0 DA:289,0 DA:291,0 DA:292,0 @@ -174,91 +175,91 @@ DA:303,1 DA:304,20 DA:305,20 DA:309,19 -BRDA:309,0,0,19 -BRDA:309,0,1,11 -BRDA:309,0,2,0 -BRDA:309,0,3,0 -BRDA:309,0,4,0 -BRDA:309,0,5,0 -BRDA:309,0,6,0 -BRDA:309,0,7,0 -BRDA:309,0,8,0 -BRDA:309,0,9,0 -BRDA:309,0,10,0 -BRDA:309,0,11,0 -BRDA:309,0,12,5 -BRDA:309,0,13,0 -BRDA:309,0,14,0 -BRDA:309,0,15,0 -BRDA:309,0,16,0 -BRDA:309,0,17,0 -BRDA:309,0,18,0 -BRDA:309,0,19,0 -BRDA:309,0,20,0 -BRDA:309,0,21,0 -BRDA:309,0,22,0 -BRDA:309,0,23,2 -BRDA:309,0,24,0 -BRDA:309,0,25,0 -BRDA:309,0,26,1 -BRDA:309,0,27,0 -BRDA:309,0,28,0 -BRDA:309,0,29,0 -BRDA:309,0,30,0 -BRDA:309,0,31,0 -BRDA:309,0,32,0 +BRDA:309,0,clk,19 +BRDA:309,0,cyc[0],11 +BRDA:309,0,cyc[10],0 +BRDA:309,0,cyc[11],0 +BRDA:309,0,cyc[12],0 +BRDA:309,0,cyc[13],0 +BRDA:309,0,cyc[14],0 +BRDA:309,0,cyc[15],0 +BRDA:309,0,cyc[16],0 +BRDA:309,0,cyc[17],0 +BRDA:309,0,cyc[18],0 +BRDA:309,0,cyc[19],0 +BRDA:309,0,cyc[1],5 +BRDA:309,0,cyc[20],0 +BRDA:309,0,cyc[21],0 +BRDA:309,0,cyc[22],0 +BRDA:309,0,cyc[23],0 +BRDA:309,0,cyc[24],0 +BRDA:309,0,cyc[25],0 +BRDA:309,0,cyc[26],0 +BRDA:309,0,cyc[27],0 +BRDA:309,0,cyc[28],0 +BRDA:309,0,cyc[29],0 +BRDA:309,0,cyc[2],2 +BRDA:309,0,cyc[30],0 +BRDA:309,0,cyc[31],0 +BRDA:309,0,cyc[3],1 +BRDA:309,0,cyc[4],0 +BRDA:309,0,cyc[5],0 +BRDA:309,0,cyc[6],0 +BRDA:309,0,cyc[7],0 +BRDA:309,0,cyc[8],0 +BRDA:309,0,cyc[9],0 DA:310,19 -BRDA:310,0,0,0 -BRDA:310,0,1,2 -BRDA:310,0,2,19 -BRDA:310,0,3,6 -BRDA:310,0,4,7 -BRDA:310,0,5,1 -BRDA:310,0,6,19 -BRDA:310,0,7,3 -BRDA:310,0,8,0 -BRDA:310,0,9,0 -BRDA:310,0,10,0 +BRDA:310,0,a,0 +BRDA:310,0,b,2 +BRDA:310,0,c,19 +BRDA:310,0,d,6 +BRDA:310,0,e,7 +BRDA:310,0,f,1 +BRDA:310,0,g,19 +BRDA:310,0,h,3 +BRDA:310,0,k,0 +BRDA:310,0,l,0 +BRDA:310,0,m,0 DA:311,1 -BRDA:311,0,0,1 -BRDA:311,0,1,1 -BRDA:311,0,2,0 -BRDA:311,0,3,0 -BRDA:311,0,4,0 -BRDA:311,0,5,0 +BRDA:311,0,tab[0],1 +BRDA:311,0,tab[1],1 +BRDA:311,0,tab[2],0 +BRDA:311,0,tab[3],0 +BRDA:311,0,tab[4],0 +BRDA:311,0,tab[5],0 DA:313,2 -BRDA:313,0,0,0 -BRDA:313,0,1,2 -BRDA:313,0,2,0 -BRDA:313,0,3,0 -BRDA:313,0,4,0 -BRDA:313,0,5,0 -BRDA:313,0,6,0 -BRDA:313,0,7,0 -BRDA:313,0,8,2 -BRDA:313,0,9,0 -BRDA:313,0,10,0 -BRDA:313,0,11,0 -BRDA:313,0,12,0 -BRDA:313,0,13,0 -BRDA:313,0,14,0 -BRDA:313,0,15,0 -BRDA:313,0,16,0 -BRDA:313,0,17,0 -BRDA:313,0,18,0 -BRDA:313,0,19,0 -BRDA:313,0,20,0 -BRDA:313,0,21,0 -BRDA:313,0,22,0 -BRDA:313,0,23,0 -BRDA:313,0,24,0 -BRDA:313,0,25,0 -BRDA:313,0,26,0 -BRDA:313,0,27,0 -BRDA:313,0,28,0 -BRDA:313,0,29,0 -BRDA:313,0,30,0 -BRDA:313,0,31,0 +BRDA:313,0,data[0][0][0],0 +BRDA:313,0,data[0][0][1],2 +BRDA:313,0,data[0][0][2],0 +BRDA:313,0,data[0][0][3],0 +BRDA:313,0,data[0][0][4],0 +BRDA:313,0,data[0][0][5],0 +BRDA:313,0,data[0][0][6],0 +BRDA:313,0,data[0][0][7],0 +BRDA:313,0,data[0][1][0],2 +BRDA:313,0,data[0][1][1],0 +BRDA:313,0,data[0][1][2],0 +BRDA:313,0,data[0][1][3],0 +BRDA:313,0,data[0][1][4],0 +BRDA:313,0,data[0][1][5],0 +BRDA:313,0,data[0][1][6],0 +BRDA:313,0,data[0][1][7],0 +BRDA:313,0,data[1][0][0],0 +BRDA:313,0,data[1][0][1],0 +BRDA:313,0,data[1][0][2],0 +BRDA:313,0,data[1][0][3],0 +BRDA:313,0,data[1][0][4],0 +BRDA:313,0,data[1][0][5],0 +BRDA:313,0,data[1][0][6],0 +BRDA:313,0,data[1][0][7],0 +BRDA:313,0,data[1][1][0],0 +BRDA:313,0,data[1][1][1],0 +BRDA:313,0,data[1][1][2],0 +BRDA:313,0,data[1][1][3],0 +BRDA:313,0,data[1][1][4],0 +BRDA:313,0,data[1][1][5],0 +BRDA:313,0,data[1][1][6],0 +BRDA:313,0,data[1][1][7],0 DA:314,1 DA:317,21 DA:318,21 @@ -266,69 +267,69 @@ DA:319,21 DA:322,10 DA:324,10 DA:327,31 -BRDA:327,0,0,0 -BRDA:327,0,1,31 +BRDA:327,0,cond_then,0 +BRDA:327,0,cond_else,31 DA:328,28 -BRDA:328,0,0,3 -BRDA:328,0,1,28 +BRDA:328,0,cond_then,3 +BRDA:328,0,cond_else,28 DA:329,21 -BRDA:329,0,0,21 -BRDA:329,0,1,0 +BRDA:329,0,cond_then,21 +BRDA:329,0,cond_else,0 DA:330,10 DA:331,10 -BRDA:331,0,0,10 -BRDA:331,0,1,7 -BRDA:331,0,2,3 -BRDA:331,0,3,3 -BRDA:331,0,4,7 +BRDA:331,0,block,10 +BRDA:331,0,(((cyc %25 32'sh3) == 32'sh0)==0) => 0,7 +BRDA:331,0,(((cyc %25 32'sh3) == 32'sh0)==1) => 1,3 +BRDA:331,0,cond_then,3 +BRDA:331,0,cond_else,7 DA:332,10 -BRDA:332,0,0,10 -BRDA:332,0,1,0 -BRDA:332,0,2,10 +BRDA:332,0,block,10 +BRDA:332,0,cond_then,0 +BRDA:332,0,cond_else,10 DA:334,19 -BRDA:334,0,0,12 -BRDA:334,0,1,19 -BRDA:334,0,2,7 -BRDA:334,0,3,5 +BRDA:334,0,cond_then,12 +BRDA:334,0,cond_else,19 +BRDA:334,0,cond_then,7 +BRDA:334,0,cond_else,5 DA:337,11 -BRDA:337,0,0,11 -BRDA:337,0,1,0 +BRDA:337,0,cond_then,11 +BRDA:337,0,cond_else,0 DA:343,11 -BRDA:343,0,0,10 -BRDA:343,0,1,11 +BRDA:343,0,cond_then,10 +BRDA:343,0,cond_else,11 DA:346,11 DA:347,10 -BRDA:347,0,0,1 -BRDA:347,0,1,0 -BRDA:347,0,2,0 -BRDA:347,0,3,1 -BRDA:347,0,4,1 -BRDA:347,0,5,10 +BRDA:347,0,((cyc > 32'sh5)==0) => 0,1 +BRDA:347,0,((cyc > 32'sh5)==1) => 1,0 +BRDA:347,0,cond_then,0 +BRDA:347,0,cond_else,1 +BRDA:347,0,if,1 +BRDA:347,0,else,10 DA:348,10 DA:350,11 -BRDA:350,0,0,11 -BRDA:350,0,1,10 -BRDA:350,0,2,1 -BRDA:350,0,3,1 -BRDA:350,0,4,10 +BRDA:350,0,block,11 +BRDA:350,0,((cyc == 32'sh2)==0) => 0,10 +BRDA:350,0,((cyc == 32'sh2)==1) => 1,1 +BRDA:350,0,cond_then,1 +BRDA:350,0,cond_else,10 DA:353,55 -BRDA:353,0,0,11 -BRDA:353,0,1,11 -BRDA:353,0,2,0 -BRDA:353,0,3,55 +BRDA:353,0,block,11 +BRDA:353,0,((i < 32'sh5)==0) => 0,11 +BRDA:353,0,((i < 32'sh5)==1) => 1,0 +BRDA:353,0,block,55 DA:354,55 DA:356,44 -BRDA:356,0,0,11 -BRDA:356,0,1,0 -BRDA:356,0,2,11 -BRDA:356,0,3,44 +BRDA:356,0,block,11 +BRDA:356,0,((i > 32'sh4)==0) => 0,0 +BRDA:356,0,((i > 32'sh4)==1) => 1,11 +BRDA:356,0,block,44 DA:357,44 DA:360,11 -BRDA:360,0,0,11 -BRDA:360,0,1,0 -BRDA:360,0,2,0 -BRDA:360,0,3,11 +BRDA:360,0,(k==0) => 0,11 +BRDA:360,0,(k==1) => 1,0 +BRDA:360,0,if,0 +BRDA:360,0,else,11 DA:361,11 -BRF:183 +BRF:184 BRH:39 end_of_record diff --git a/test_regress/t/t_vlcov_summary_typed.out b/test_regress/t/t_vlcov_summary_typed.out index e4b3d14f6..f9700d96d 100644 --- a/test_regress/t/t_vlcov_summary_typed.out +++ b/test_regress/t/t_vlcov_summary_typed.out @@ -1,5 +1,5 @@ Coverage Summary: - line : 88.6% ( 39/ 44) + line : 88.9% ( 40/ 45) toggle : 33.3% ( 35/105) branch : 78.1% ( 50/ 64) expr : 66.7% ( 8/ 12) From 7ece66d06e19f21d14c38d0946cf2060a19f0544 Mon Sep 17 00:00:00 2001 From: Pawel Klopotek Date: Fri, 3 Jul 2026 18:49:21 +0200 Subject: [PATCH 27/29] Fix unique0 case side effects (#7787) --- src/V3Assert.cpp | 27 +++++++++++++++ test_regress/t/t_case_call_count.py | 3 +- test_regress/t/t_case_inside_call_count.py | 3 +- test_regress/t/t_unique0_case.py | 20 +++++++++++ test_regress/t/t_unique0_case.v | 39 ++++++++++++++++++++++ 5 files changed, 90 insertions(+), 2 deletions(-) create mode 100755 test_regress/t/t_unique0_case.py create mode 100644 test_regress/t/t_unique0_case.v diff --git a/src/V3Assert.cpp b/src/V3Assert.cpp index 6c507c22c..ee18b24b4 100644 --- a/src/V3Assert.cpp +++ b/src/V3Assert.cpp @@ -20,6 +20,7 @@ #include "V3AstUserAllocator.h" #include "V3Stats.h" +#include "V3UniqueNames.h" VL_DEFINE_DEBUG_FUNCTIONS; @@ -228,6 +229,9 @@ class AssertVisitor final : public VNVisitor { AstNode* m_failsp = nullptr; // Current fail statement AstNodeCoverOrAssert* m_assertp = nullptr; // Current assertion AstFinal* m_finalp = nullptr; // Current final block + VDouble0 m_statLiftedCaseExprs; // Count of purified case expressions + AstNodeFTask* m_ftaskp = nullptr; // Current function/task + V3UniqueNames m_caseTempNames{"__VCase"}; // Map from (expression, senTree) to AstAlways that computes delayed values of the expression std::unordered_map, std::unordered_map, AstAlways*>> m_modExpr2Sen2DelayedAlwaysp; @@ -755,6 +759,28 @@ class AssertVisitor final : public VNVisitor { //========== Case assertions void visit(AstCase* nodep) override { + // Introduce temporary variable for AstCase if needed - it is done here and not in V3Case + // because this phase is before V3Scope and V3Case is not. Doing it before V3Scope ensures + // that V3Scope will take care of a scope creation + // We also need to do it before V3Begin, co that pragmas like `unique0` also work correctly + if (!nodep->exprp()->isPure()) { + ++m_statLiftedCaseExprs; + FileLine* const fl = nodep->exprp()->fileline(); + AstVar* const varp = new AstVar{fl, VVarType::BLOCKTEMP, m_caseTempNames.get(nodep), + nodep->exprp()->dtypep()}; + AstNodeExpr* const origp = nodep->exprp()->unlinkFrBack(); + nodep->addHereThisAsNext( + new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE}, origp}); + nodep->exprp(new AstVarRef{fl, varp, VAccess::READ}); + if (m_ftaskp) { + varp->funcLocal(true); + varp->lifetime(VLifetime::AUTOMATIC_EXPLICIT); + m_ftaskp->stmtsp()->addHereThisAsNext(varp); + } else { + m_modp->stmtsp()->addHereThisAsNext(varp); + } + VIsCached::clearCacheTree(); + } iterateChildren(nodep); if (!nodep->user1SetOnce()) { bool has_default = false; @@ -1180,6 +1206,7 @@ public: V3Stats::addStat("Assertions, $past variables", m_statPastVars); V3Stats::addStat("Assertions, assertOn checks combined", m_statAssertOnCombined); V3Stats::addStat("Assertions, assertOn checks hoisted", m_statAssertOnHoisted); + V3Stats::addStat("Assertions, lifted impure case expressions", m_statLiftedCaseExprs); // Rewrites can change purity, e.g. by compiling out assertion statements with --no-assert VIsCached::clearCacheTree(); } diff --git a/test_regress/t/t_case_call_count.py b/test_regress/t/t_case_call_count.py index df91d0e3c..bf14a54dd 100755 --- a/test_regress/t/t_case_call_count.py +++ b/test_regress/t/t_case_call_count.py @@ -15,6 +15,7 @@ test.compile(verilator_flags2=['--stats']) test.execute() -test.file_grep(test.stats, r'LiftExpr, lifted calls\s+(\d+)', 3) +test.file_grep(test.stats, r'LiftExpr, lifted calls\s+(\d+)', 2) +test.file_grep(test.stats, r'Assertions, lifted impure case expressions\s+(\d+)', 2) test.passes() diff --git a/test_regress/t/t_case_inside_call_count.py b/test_regress/t/t_case_inside_call_count.py index df91d0e3c..bf14a54dd 100755 --- a/test_regress/t/t_case_inside_call_count.py +++ b/test_regress/t/t_case_inside_call_count.py @@ -15,6 +15,7 @@ test.compile(verilator_flags2=['--stats']) test.execute() -test.file_grep(test.stats, r'LiftExpr, lifted calls\s+(\d+)', 3) +test.file_grep(test.stats, r'LiftExpr, lifted calls\s+(\d+)', 2) +test.file_grep(test.stats, r'Assertions, lifted impure case expressions\s+(\d+)', 2) test.passes() diff --git a/test_regress/t/t_unique0_case.py b/test_regress/t/t_unique0_case.py new file mode 100755 index 000000000..3626b338d --- /dev/null +++ b/test_regress/t/t_unique0_case.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios("simulator") + +test.compile(verilator_flags2=["--stats"]) + +test.execute() + +test.file_grep(test.stats, r"Assertions, lifted impure case expressions\s+(\d+)", 1) + +test.passes() diff --git a/test_regress/t/t_unique0_case.v b/test_regress/t/t_unique0_case.v new file mode 100644 index 000000000..54cedb901 --- /dev/null +++ b/test_regress/t/t_unique0_case.v @@ -0,0 +1,39 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2026 Antmicro +// SPDX-License-Identifier: CC0-1.0 + +// verilog_format: off +`define stop $stop +`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); +`define checkp(gotv,expv_s) do begin string gotv_s; gotv_s = $sformatf("%p", gotv); if ((gotv_s) != (expv_s)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv_s), (expv_s)); `stop; end end while(0); +// verilog_format: on + +module t; + int x; + int y; + int z; + initial begin + y = 0; + x = 0; + z = 0; + unique0 case(increment_x()) + 1: begin + y = 1; + end + default: begin + z = 1; + end + endcase + `checkh(x, 32'h1); + `checkh(y, 32'h1); + `checkh(z, 32'h0); + $finish; + end + + function automatic integer increment_x(); + x = x + 1; + return x; + endfunction +endmodule From 12fab5d5d75f6b12598ceccba7d075cfebb177eb Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 3 Jul 2026 13:00:23 -0400 Subject: [PATCH 28/29] Tests: Cleanup some cross-simulator test differences --- Changes | 2 +- src/V3Options.cpp | 2 +- test_regress/t/t_array_packed_sysfunct.v | 2 - test_regress/t/t_assert_always_unbounded.v | 12 +- test_regress/t/t_assert_bang_in_seq.v | 12 +- test_regress/t/t_assert_consec_rep.v | 28 +-- test_regress/t/t_assert_consec_rep_large.v | 4 +- test_regress/t/t_assert_ctl_lock.v | 11 +- test_regress/t/t_assert_goto_rep.v | 16 +- test_regress/t/t_assert_nonconsec_rep.v | 8 +- test_regress/t/t_assert_procedural_gated.v | 5 +- test_regress/t/t_assert_seq_clocking.v | 5 +- test_regress/t/t_constraint_dist_foreach_if.v | 3 +- test_regress/t/t_cover_property.v | 19 +- test_regress/t/t_cover_sequence.v | 17 +- test_regress/t/t_forceable_unpacked.v | 3 +- test_regress/t/t_gen_for.v | 4 - test_regress/t/t_gen_intdot.v | 98 ++++++---- test_regress/t/t_inst_signed.v | 6 +- test_regress/t/t_interface2.v | 2 +- test_regress/t/t_interface_array_nocolon.v | 1 - .../t/t_interface_virtual_sub_iface_method.v | 3 +- test_regress/t/t_math_pow.v | 2 - test_regress/t/t_math_pow3.v | 27 ++- test_regress/t/t_math_signed4.v | 6 +- test_regress/t/t_math_signed5.v | 19 +- test_regress/t/t_math_svl2.v | 4 - test_regress/t/t_modport_export_task.v | 3 +- test_regress/t/t_param_first.v | 3 +- test_regress/t/t_prop_always.v | 20 +- test_regress/t/t_prop_followed_by.v | 15 +- test_regress/t/t_property_accept_reject_on.v | 20 +- test_regress/t/t_property_disable_iff_held.v | 16 +- test_regress/t/t_property_until_implication.v | 6 +- test_regress/t/t_randsequence.v | 5 +- test_regress/t/t_randsequence_func.v | 3 +- test_regress/t/t_randsequence_randjoin.v | 5 +- test_regress/t/t_randsequence_svtests.v | 3 +- .../t/t_sequence_intersect_nevermatch.v | 8 +- test_regress/t/t_sequence_intersect_varlen.v | 13 +- test_regress/t/t_sequence_sexpr_throughout.v | 14 +- test_regress/t/t_sequence_within.v | 37 ++-- test_regress/t/t_sv_cpu.py | 33 ++-- test_regress/t/t_sys_file_scan_delay.v | 2 +- test_regress/t/t_tagged_case.out | 184 +++++++++--------- test_regress/t/t_tagged_case.v | 12 +- test_regress/t/t_tagged_if.out | 16 +- test_regress/t/t_tagged_if.v | 14 +- test_regress/t/t_tagged_union.out | 182 ++++++++--------- test_regress/t/t_tagged_union.v | 6 + test_regress/t/t_vpi_force.v | 9 +- 51 files changed, 473 insertions(+), 477 deletions(-) diff --git a/Changes b/Changes index 1edeaf179..3e4174b62 100644 --- a/Changes +++ b/Changes @@ -5744,7 +5744,7 @@ Verilator 3.104 2003-04-30 **Major:** * Indicate direction of ports with VL_IN and VL_OUT. -* Allow $c32, etc, to specify width of the $c statement for VCS. +* Allow $c32, etc, to specify width of the $c statement. * Numerous performance improvements, worth about 25% **Minor:** diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 7a85c848d..f9502e00c 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -542,7 +542,7 @@ bool V3Options::fileStatNormal(const string& filename) { } string V3Options::fileExists(const string& filename) { - // Surprisingly, for VCS and other simulators, this process + // Surprisingly, for some other simulators, this process // is quite slow; presumably because of re-reading each directory // many times. So we read a whole dir at once and cache it diff --git a/test_regress/t/t_array_packed_sysfunct.v b/test_regress/t/t_array_packed_sysfunct.v index e31d38929..c380fa898 100644 --- a/test_regress/t/t_array_packed_sysfunct.v +++ b/test_regress/t/t_array_packed_sysfunct.v @@ -33,9 +33,7 @@ module t ( initial begin `checkh($dimensions (array_unpk), 3); -`ifndef VCS `checkh($unpacked_dimensions (array_unpk), 2); // IEEE 2009 -`endif `checkh($bits (array_unpk), 2*2*2); `checkh($low (array_unpk), 2); `checkh($high (array_unpk), 3); diff --git a/test_regress/t/t_assert_always_unbounded.v b/test_regress/t/t_assert_always_unbounded.v index 9f41a2627..f408c5885 100644 --- a/test_regress/t/t_assert_always_unbounded.v +++ b/test_regress/t/t_assert_always_unbounded.v @@ -35,7 +35,7 @@ module t ( assert property (@(posedge clk) always [2:$] a_low) else low2_fail_q.push_back(cyc); // a_drop is high then drops at cyc 5 and stays low: deterministic single - // transition, so Verilator and Questa agree on the failing ticks exactly. + // transition, so Verilator and others agree on the failing ticks exactly. assert property (@(posedge clk) always [2:$] a_drop) else drop_fail_q.push_back(cyc); always @(posedge clk) begin @@ -43,12 +43,12 @@ module t ( if (cyc >= 4) a_drop <= 1'b0; if (cyc == 19) begin // Counts pinned to Verilator (NFA per-cycle reject). For all-fail windows - // Questa is one lower (it does not fire the end-of-sim tick); see the sva + // others are one lower (it does not fire the end-of-sim tick); see the sva // lessons "multi-cycle end-of-simulation offset" note. - `checkd(high_fail_q.size(), 0); // Questa: 0 - `checkd(low0_fail_q.size(), 20); // Questa: 19 - `checkd(low2_fail_q.size(), 18); // Questa: 17 - `checkd(drop_fail_q[0], 5); // first fail tick: a_drop sampled low from cyc 5 + `checkd(high_fail_q.size(), 0); + `checkd(low0_fail_q.size(), 20); // All others: 19 + `checkd(low2_fail_q.size(), 18); // All others: 17 + `checkd(drop_fail_q[0], 5); // All others: 6; first fail tick: a_drop sampled low from cyc 5 $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_assert_bang_in_seq.v b/test_regress/t/t_assert_bang_in_seq.v index b0c831229..784dd338a 100644 --- a/test_regress/t/t_assert_bang_in_seq.v +++ b/test_regress/t/t_assert_bang_in_seq.v @@ -66,12 +66,12 @@ module t ( end else if (cyc == 99) begin `checkh(crc, 64'hc77bb9b3784ea091); - `checkd(count_fail1, 66); // Questa: 66 - `checkd(count_fail2, 69); // Questa: 69 - `checkd(count_fail3, 26); // Questa: 26 - `checkd(count_fail4, 66); // Questa: 66 - `checkd(count_fail5, 80); // Questa: 80 - `checkd(count_fail6, 27); // Questa: 27 + `checkd(count_fail1, 66); + `checkd(count_fail2, 69); + `checkd(count_fail3, 26); + `checkd(count_fail4, 66); + `checkd(count_fail5, 80); + `checkd(count_fail6, 27); $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_assert_consec_rep.v b/test_regress/t/t_assert_consec_rep.v index 8a4d87040..206b49886 100644 --- a/test_regress/t/t_assert_consec_rep.v +++ b/test_regress/t/t_assert_consec_rep.v @@ -95,23 +95,23 @@ module t ( end else if (cyc == 99) begin `checkh(crc, 64'hc77bb9b3784ea091); - `checkd(count_fail1, 5); // Questa: 5 - `checkd(count_fail2, 25); // Questa: 25 - `checkd(count_fail3, 9); // Questa: 9 - `checkd(count_fail4, 49); // Questa: 49 - `checkd(count_fail5, 0); // Questa: 0 - // NFA merge-node range [*M:N] over-counts rejects (Questa: 51); match + `checkd(count_fail1, 5); + `checkd(count_fail2, 25); // One other sim: 19 + `checkd(count_fail3, 9); + `checkd(count_fail4, 49); + `checkd(count_fail5, 0); + // NFA merge-node range [*M:N] over-counts rejects; match // detection is correct, only reject counting is imprecise - `checkd(count_fail6, 59); - `checkd(count_fail7, 51); // Questa: 51 - `checkd(count_fail8, 20); // Questa: 20 + `checkd(count_fail6, 59); // All other sims: 51 + `checkd(count_fail7, 51); + `checkd(count_fail8, 20); // IEEE 1800-2023 16.9.2 permits empty match of [*0]; NFA reports - // rejects on each tick while Questa suppresses (Questa: 20) - `checkd(count_fail9, 49); - `checkd(count_fail10, 59); // Questa: 59 + // rejects on each tick while others suppress + `checkd(count_fail9, 49); // Most others: 20, one other 49 + `checkd(count_fail10, 59); // a[*] ##1 b: NFA treats unbounded [*] as liveness (no reject); - // Questa treats as definite antecedent (Questa: 29) - `checkd(count_fail11, 0); + // Should be definite antecedent + `checkd(count_fail11, 0); // All other sims: 29 $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_assert_consec_rep_large.v b/test_regress/t/t_assert_consec_rep_large.v index 359537ce7..4df36f7bc 100644 --- a/test_regress/t/t_assert_consec_rep_large.v +++ b/test_regress/t/t_assert_consec_rep_large.v @@ -40,8 +40,8 @@ module t ( else if (cyc == 99) begin `checkh(crc, 64'hc77bb9b3784ea091); `checkd(count_fail_257, 0); - // Questa: 31 -- pre-existing ~26.5% NFA reject gap on |-> ##1 [*N] - `checkd(count_fail_513, 23); + // Mismatch due to pre-existing ~26.5% NFA reject gap on |-> ##1 [*N] + `checkd(count_fail_513, 23); // All other sims: 31 $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_assert_ctl_lock.v b/test_regress/t/t_assert_ctl_lock.v index 59c98a006..c47e3b341 100644 --- a/test_regress/t/t_assert_ctl_lock.v +++ b/test_regress/t/t_assert_ctl_lock.v @@ -5,6 +5,8 @@ // SPDX-License-Identifier: CC0-1.0 // verilog_format: off +`define stop $stop +`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); `ifdef verilator `define no_optimize(v) $c(v) `else @@ -12,7 +14,7 @@ `endif // verilog_format: on -module t ( /*AUTOARG*/); +module t; logic clk = 0; int imm_fails = 0, conc_fails = 0; logic a = 1'b1; // antecedent always true @@ -58,11 +60,8 @@ module t ( /*AUTOARG*/); end final begin - // Concrete counts cross-checked against Questa 2022.3: imm_fails=5 conc_fails=7. - if (imm_fails != 5 || conc_fails != 7) begin - $display("%%Error: imm_fails=%0d (exp 5) conc_fails=%0d (exp 7)", imm_fails, conc_fails); - $stop; - end + `checkd(imm_fails, 5); + `checkd(conc_fails, 7); // Other sims: 7 or 1 $write("*-* All Finished *-*\n"); end endmodule diff --git a/test_regress/t/t_assert_goto_rep.v b/test_regress/t/t_assert_goto_rep.v index f926a3b5b..1a209444b 100644 --- a/test_regress/t/t_assert_goto_rep.v +++ b/test_regress/t/t_assert_goto_rep.v @@ -75,14 +75,14 @@ module t ( end else if (cyc == 99) begin `checkh(crc, 64'hc77bb9b3784ea091); - `checkd(count_fail1, 20); // Questa: 20 - `checkd(count_fail2, 25); // Questa: 25 - `checkd(count_fail3, 19); // Questa: 19 - `checkd(count_fail4, 0); // Questa: 0 - `checkd(count_fail5, 20); // Questa: 20 - `checkd(count_fail6, 25); // Questa: 25 - `checkd(count_fail7, 20); // Questa: 20 - `checkd(count_fail8, 20); // Questa: 20 + `checkd(count_fail1, 20); + `checkd(count_fail2, 25); + `checkd(count_fail3, 19); + `checkd(count_fail4, 0); + `checkd(count_fail5, 20); + `checkd(count_fail6, 25); + `checkd(count_fail7, 20); + `checkd(count_fail8, 20); $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_assert_nonconsec_rep.v b/test_regress/t/t_assert_nonconsec_rep.v index 6d759b9c2..c69db8bf9 100644 --- a/test_regress/t/t_assert_nonconsec_rep.v +++ b/test_regress/t/t_assert_nonconsec_rep.v @@ -56,10 +56,10 @@ module t ( end else if (cyc == 99) begin `checkh(crc, 64'hc77bb9b3784ea091); - `checkd(count_fail1, 34); // Questa: 29 - `checkd(count_fail2, 27); // Questa: 32 - `checkd(count_fail3, 25); // Questa: 29 - `checkd(count_fail4, 0); // Questa: 0 + `checkd(count_fail1, 34); // Other sims: 29, one other: 20 + `checkd(count_fail2, 27); // Other sims: 32, one other: 25 + `checkd(count_fail3, 25); // Other sims: 29, one other: 25 + `checkd(count_fail4, 0); $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_assert_procedural_gated.v b/test_regress/t/t_assert_procedural_gated.v index 9ed88121f..56e38ed41 100644 --- a/test_regress/t/t_assert_procedural_gated.v +++ b/test_regress/t/t_assert_procedural_gated.v @@ -57,9 +57,8 @@ module t ( end else if (cyc == 99) begin `checkh(crc, 64'hc77bb9b3784ea091); - // Questa 2022.3 golden: count_gated=5, count_ref=12. - `checkd(count_gated, 5); - `checkd(count_ref, 12); + `checkd(count_gated, 5); // Other sims same, one other: 4 + `checkd(count_ref, 12); // Other sims same, one other: 10 $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_assert_seq_clocking.v b/test_regress/t/t_assert_seq_clocking.v index b835acb85..9c59d7287 100644 --- a/test_regress/t/t_assert_seq_clocking.v +++ b/test_regress/t/t_assert_seq_clocking.v @@ -44,10 +44,9 @@ module t ( end // Counts read in final (Postponed) to avoid same-timestep races. - // Concrete Verilator counts; Questa: fails_single=17 fails_multi=17 final begin - `checkd(fails_single, 17); - `checkd(fails_multi, 17); + `checkd(fails_single, 17); // Other sims: 0 + `checkd(fails_multi, 17); // Other sims: 0 $write("*-* All Finished *-*\n"); end endmodule diff --git a/test_regress/t/t_constraint_dist_foreach_if.v b/test_regress/t/t_constraint_dist_foreach_if.v index a8eaedb24..5d6f1b2ec 100644 --- a/test_regress/t/t_constraint_dist_foreach_if.v +++ b/test_regress/t/t_constraint_dist_foreach_if.v @@ -8,7 +8,8 @@ // values only within the declared distribution and cover all buckets. // verilog_format: off -`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); +`define stop $stop +`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); // verilog_format: on // foreach (a[i]) if (gate) a[i] dist {...} diff --git a/test_regress/t/t_cover_property.v b/test_regress/t/t_cover_property.v index 40089451c..d68118d96 100644 --- a/test_regress/t/t_cover_property.v +++ b/test_regress/t/t_cover_property.v @@ -60,18 +60,17 @@ module t ( // A cover of an implication counts only non-vacuous matches (IEEE // 1800-2023 16.15.2): the antecedent must match. So it is identical to the // corresponding sequence cover, not the vacuous implication value. - `checkd(n_imp_no, n_seq) - `checkd(n_imp_ov, n_seq0) + `checkd(n_imp_no, n_seq); // Other sims: pass, 73 + `checkd(n_imp_ov, n_seq0); // Other sims: pass, 45 // A named-property cover lowers the same implication, so it also counts // non-vacuously (regression guard for the property-inlining path). - `checkd(n_named, n_imp_no) - // Pinned Verilator counts; Questa golden cross-checked. - `checkd(n_imp_no, 28) // Questa: 28 - `checkd(n_imp_ov, 27) // Questa: 27 - `checkd(n_seq, 28) // Questa: 28 - `checkd(n_seq0, 27) // Questa: 27 - `checkd(n_bool, 55) // Questa: 54 - `checkd(n_named, 28) // Questa: 28 + `checkd(n_named, n_imp_no); + `checkd(n_imp_no, 28); + `checkd(n_imp_ov, 27); // Other sims: pass, 73 + `checkd(n_seq, 28); // Other sims: 45, 27 + `checkd(n_seq0, 27); + `checkd(n_bool, 55); // Other sims: pass, 25 + `checkd(n_named, 28); // Other sims: 73, 54, 54 end endmodule diff --git a/test_regress/t/t_cover_sequence.v b/test_regress/t/t_cover_sequence.v index 42f39949e..79516a81c 100644 --- a/test_regress/t/t_cover_sequence.v +++ b/test_regress/t/t_cover_sequence.v @@ -69,22 +69,21 @@ module t ( // Read the counters in 'final', not the clocked block: a same-cycle read of a // cover counter races the cover's increment under --threads (vltmt). Verilator - // counts one more end-of-match than Questa 2022.3 on some forms at the - // simulation boundary; the Questa value is noted per check. + // counts one more end-of-match than others on some forms. final begin `ifdef TEST_VERBOSE $write("simple=%0d clocked=%0d clk_dis=%0d def_dis=%0d range=%0d 2=%0d 3=%0d\n", hit_simple, hit_clocked, hit_clocked_disable, hit_default_disable, hit_consrep_range, hit_consrep_2, hit_consrep_3); `endif - `checkd(hit_simple, 96); // Questa: 95 - `checkd(hit_clocked, 149); // Questa: 149 - `checkd(hit_clocked_disable, 27); // Questa: 27 - `checkd(hit_default_disable, 30); // Questa: 30 - `checkd(hit_consrep_2, 30); // Questa: 29 - `checkd(hit_consrep_3, 14); // Questa: 13 + `checkd(hit_simple, 96); // Other sims: 5, 95 + `checkd(hit_clocked, 149); + `checkd(hit_clocked_disable, 27); + `checkd(hit_default_disable, 30); + `checkd(hit_consrep_2, 30); // Other sims: 29 + `checkd(hit_consrep_3, 14); // Other sims: 13 // a[*2:3] == a[*2] or a[*3] (IEEE 1800-2023 16.9.2) - `checkd(hit_consrep_range, hit_consrep_2 + hit_consrep_3); // 44; Questa: 42 + `checkd(hit_consrep_range, hit_consrep_2 + hit_consrep_3); $write("*-* All Finished *-*\n"); end endmodule diff --git a/test_regress/t/t_forceable_unpacked.v b/test_regress/t/t_forceable_unpacked.v index 5e0048563..3b3cd23a0 100644 --- a/test_regress/t/t_forceable_unpacked.v +++ b/test_regress/t/t_forceable_unpacked.v @@ -5,7 +5,8 @@ // SPDX-License-Identifier: CC0-1.0 // verilog_format: off -`define checkh(g,e) do if ((g) !==(e)) begin $write("%%Error: %s:%0d: got=%x exp=%x\n", `__FILE__,`__LINE__, (g),(e)); $stop; end while(0) +`define stop $stop +`define checkh(g,e) do if ((g) !==(e)) begin $write("%%Error: %s:%0d: got=%x exp=%x\n", `__FILE__,`__LINE__, (g),(e)); `stop; end while(0) `ifdef CMT `define FORCEABLE /*verilator forceable*/ diff --git a/test_regress/t/t_gen_for.v b/test_regress/t/t_gen_for.v index 47d7ba1a7..006b9f83a 100644 --- a/test_regress/t/t_gen_for.v +++ b/test_regress/t/t_gen_for.v @@ -97,8 +97,6 @@ module paramed ( /*AUTOARG*/ // No else endgenerate -`ifndef NC // for(genvar) unsupported -`ifndef ATSIM // for(genvar) unsupported generate // Empty loop body, local genvar for (genvar j = 0; j < 3; j = j + 1) begin @@ -107,8 +105,6 @@ module paramed ( /*AUTOARG*/ for (genvar j = 0; j < 5; j = j + 1) begin end endgenerate -`endif -`endif generate endgenerate diff --git a/test_regress/t/t_gen_intdot.v b/test_regress/t/t_gen_intdot.v index d00c7028a..248616e8e 100644 --- a/test_regress/t/t_gen_intdot.v +++ b/test_regress/t/t_gen_intdot.v @@ -10,30 +10,34 @@ module t ( input clk ); - integer cyc = 0; + integer cyc = 0; - wire out; - reg in; + wire out; + reg in; - Genit g (.clk(clk), .value(in), .result(out)); + Genit g ( + .clk(clk), + .value(in), + .result(out) + ); - always @ (posedge clk) begin + always @(posedge clk) begin //$write("[%0t] cyc==%0d %x %x\n", $time, cyc, in, out); cyc <= cyc + 1; - if (cyc==0) begin + if (cyc == 0) begin // Setup in <= 1'b1; end - else if (cyc==1) begin + else if (cyc == 1) begin in <= 1'b0; end - else if (cyc==2) begin + else if (cyc == 2) begin if (out != 1'b1) $stop; end - else if (cyc==3) begin + else if (cyc == 3) begin if (out != 1'b0) $stop; end - else if (cyc==9) begin + else if (cyc == 9) begin $write("*-* All Finished *-*\n"); $finish; end @@ -41,7 +45,11 @@ module t ( endmodule -module Generate (clk, value, result); +module Generate ( + clk, + value, + result +); input clk; input value; output result; @@ -50,63 +58,73 @@ module Generate (clk, value, result); assign result = Internal; - always @(posedge clk) - Internal <= value; + always @(posedge clk) Internal <= value; endmodule -module Checker (clk, value); +module Checker ( + clk, + value +); input clk, value; always @(posedge clk) begin - $write ("[%0t] value=%h\n", $time, value); + $write("[%0t] value=%h\n", $time, value); end endmodule -module Test (clk, value, result); +module Test ( + clk, + value, + result +); input clk; input value; output result; - Generate gen (clk, value, result); - Checker chk (clk, gen.Internal); + Generate gen ( + clk, + value, + result + ); + Checker chk ( + clk, + gen.Internal + ); endmodule -module Genit (clk, value, result); +module Genit ( + clk, + value, + result +); input clk; input value; output result; -`ifndef ATSIM // else unsupported - `ifndef NC // else unsupported - `ifndef IVERILOG // else unsupported - `define WITH_FOR_GENVAR - `endif - `endif -`endif - -`define WITH_GENERATE + `define WITH_GENERATE `ifdef WITH_GENERATE - `ifndef WITH_FOR_GENVAR genvar i; - `endif generate - for ( - `ifdef WITH_FOR_GENVAR - genvar - `endif - i = 0; i < 1; i = i + 1) - begin : foo - Test tt (clk, value, result); - end + for (genvar i = 0; i < 1; i = i + 1) begin : foo + Test tt ( + clk, + value, + result + ); + end endgenerate `else - Test tt (clk, value, result); + Test tt ( + clk, + value, + result + ); `endif wire Result2 = t.g.foo[0].tt.gen.Internal; // Works - Do not change! - always @ (posedge clk) begin + always @(posedge clk) begin $write("[%0t] Result2 = %x\n", $time, Result2); end diff --git a/test_regress/t/t_inst_signed.v b/test_regress/t/t_inst_signed.v index bd46592dd..bfb24f007 100644 --- a/test_regress/t/t_inst_signed.v +++ b/test_regress/t/t_inst_signed.v @@ -34,9 +34,9 @@ module t ( if (sgn_wide[2:0] != 3'sh7) $stop; if (unsgn_wide[2:0] != 3'h7) $stop; // Simulators differ here. - if (sgn_wide !== 8'sbzzzzz111 // z-extension - NC - && sgn_wide !== 8'sb11111111) - $stop; // sign extension - VCS + if (sgn_wide !== 8'sbzzzzz111 // z-extension - some others + && sgn_wide !== 8'sb11111111) // sign extension - some others + $stop; if (unsgn_wide !== 8'sbzzzzz111 && unsgn_wide !== 8'sb00000111) $stop; cyc <= cyc + 1; if (cyc == 3) begin diff --git a/test_regress/t/t_interface2.v b/test_regress/t/t_interface2.v index e11f71b1f..52c3ac79e 100644 --- a/test_regress/t/t_interface2.v +++ b/test_regress/t/t_interface2.v @@ -12,7 +12,7 @@ module t ( counter_io c1_data(); counter_io c2_data(); - //counter_io c3_data; // IEEE illegal, and VCS doesn't allow non-() as it does with cells + // counter_io c3_data; // IEEE illegal counter_io c3_data(); counter_ansi c1 (.clkm(clk), diff --git a/test_regress/t/t_interface_array_nocolon.v b/test_regress/t/t_interface_array_nocolon.v index a5af54af4..c8015b005 100644 --- a/test_regress/t/t_interface_array_nocolon.v +++ b/test_regress/t/t_interface_array_nocolon.v @@ -37,7 +37,6 @@ module t; initial begin // Check numbering with 0 first - // NC has a bug here if (foos[0].x !== 1'b1) $stop; if (foos[1].x !== 1'b1) $stop; if (foos[2].x !== 1'b0) $stop; diff --git a/test_regress/t/t_interface_virtual_sub_iface_method.v b/test_regress/t/t_interface_virtual_sub_iface_method.v index 6cf486f5b..d5d9a59fe 100644 --- a/test_regress/t/t_interface_virtual_sub_iface_method.v +++ b/test_regress/t/t_interface_virtual_sub_iface_method.v @@ -4,7 +4,8 @@ // SPDX-FileCopyrightText: 2026 PlanV GmbH // SPDX-License-Identifier: CC0-1.0 // verilog_format: off -`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); +`define stop $stop +`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); // verilog_format: on interface inner_if; diff --git a/test_regress/t/t_math_pow.v b/test_regress/t/t_math_pow.v index 72a617697..35aab1cb3 100644 --- a/test_regress/t/t_math_pow.v +++ b/test_regress/t/t_math_pow.v @@ -244,9 +244,7 @@ module t ( `checkh(67'h0 ** 21'h0, 67'h1); `checkh(67'sh0 ** 21'sh0, 67'sh1); `checkh(67'h10 ** 21'h0, 67'h1); -`ifndef VCS `checkh(61'h7ab3811219 ** 21'ha6e30, 61'h01ea58c703687e81); -`endif if (cyc==0) begin end else if (cyc==1) begin a <= 67'h0; b <= 67'h0; end else if (cyc==2) begin a <= 67'h0; b <= 67'h3; end diff --git a/test_regress/t/t_math_pow3.v b/test_regress/t/t_math_pow3.v index b591618b3..f0c18f8b6 100644 --- a/test_regress/t/t_math_pow3.v +++ b/test_regress/t/t_math_pow3.v @@ -16,22 +16,21 @@ module t; // verilog_format: off initial begin - // NC=67b6cfc1b29a21 VCS=c1b29a20(wrong) IV=67b6cfc1b29a21 Verilator=67b6cfc1b29a21 $display("15 ** 14 = %0x expect 67b6cfc1b29a21", 64'b1111 ** 64'b1110); - // NC=1 VCS=0 IV=0 Verilator=1 (wrong,fixed) $display("15 **-4'sd2 = %0x expect 0 (per IEEE negative power)", ((-4'd1 ** -4'sd2))); - // NC=1 VCS=0 IV=67b6cfc1b29a21(wrong) Verilator=1 $display("15 ** 14 = %0x expect 1 (LSB 4-bits of 67b6cfc1b29a21)", ((-4'd1 ** -4'd2))); - // NC=1 VCS=0 IV=67b6cfc1b29a21(wrong) Verilator=1 $display("15 ** 14 = %0x expect 1 (LSB 4-bits of 67b6cfc1b29a21)", ((4'd15 ** 4'd14))); - // NC=8765432187654321 VCS=8765432187654000(wrong) IV=8765432187654321 Verilator=8765432187654321 $display("64'big ** 1 = %0x expect %0x", 64'h8765432187654321 ** 1, 64'h8765432187654321); $display("\n"); `checkh( (64'b1111 ** 64'b1110), 64'h67b6cfc1b29a21); +`ifndef NC `checkh( (-4'd1 ** -4'sd2), 4'h0); //bug730 +`endif +`ifndef VCS `checkh( (-4'd1 ** -4'd2), 4'h1); `checkh( (4'd15 ** 4'd14), 4'h1); +`endif `checkh( (64'h8765432187654321 ** 4'h1), 64'h8765432187654321); `checkh((-8'sh3 ** 8'h3) , 8'he5 ); // a**b (-27) @@ -70,13 +69,23 @@ module t; `checkh(( 8'h3 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh(( 8'sh3 ** -8'sh0), 8'h1 ); // a**0 always 1 - `checkh((-8'sh3 ** -8'sh3), 8'h0 ); // 0 (a<-1) // NCVERILOG bug +`ifndef NC + `checkh((-8'sh3 ** -8'sh3), 8'h0 ); // 0 (a<-1) +`endif +`ifndef IVERILOG +`ifndef QUESTA +`ifndef VCS `checkh((-8'sh1 ** -8'sh2), 8'h1 ); // -1^odd=-1, -1^even=1 `checkh((-8'sh1 ** -8'sh3), 8'hff); // -1^odd=-1, -1^even=1 -// `checkh(( 8'h0 ** -8'sh3), 8'hx ); // x // NCVERILOG bug +`endif +`endif +`endif +// `checkh(( 8'h0 ** -8'sh3), 8'hx ); // x `checkh(( 8'h1 ** -8'sh3), 8'h1 ); // 1**b always 1 - `checkh(( 8'h3 ** -8'sh3), 8'h0 ); // 0 // NCVERILOG bug - `checkh(( 8'sh3 ** -8'sh3), 8'h0 ); // 0 // NCVERILOG bug +`ifndef NC + `checkh(( 8'h3 ** -8'sh3), 8'h0 ); // 0 + `checkh(( 8'sh3 ** -8'sh3), 8'h0 ); // 0 +`endif if (fail) $stop; diff --git a/test_regress/t/t_math_signed4.v b/test_regress/t/t_math_signed4.v index bb5d83602..05b7e6f7c 100644 --- a/test_regress/t/t_math_signed4.v +++ b/test_regress/t/t_math_signed4.v @@ -97,11 +97,7 @@ module t; // bug754 w5_u = 4'sb0010 << -2'sd1; // << 3 -`ifdef VCS - `checkh(w5_u, 5'b00000); // VCS E-2014.03 bug -`else - `checkh(w5_u, 5'b10000); // VCS E-2014.03 bug -`endif + `checkh(w5_u, 5'b10000); w5_u = 4'sb1000 << 0; // Sign extends `checkh(w5_u, 5'b11000); diff --git a/test_regress/t/t_math_signed5.v b/test_regress/t/t_math_signed5.v index b87b854f2..aa9a68d79 100644 --- a/test_regress/t/t_math_signed5.v +++ b/test_regress/t/t_math_signed5.v @@ -47,11 +47,7 @@ module t ( /*AUTOARG*/ initial begin // verilator lint_off STMTDLY #1; -`ifdef VCS // I-2014.03 - `checkh({a, b, c, d, e, f, g}, 7'b1101111); -`else `checkh({a, b, c, d, e, f, g}, 7'b1101011); -`endif //====================================================================== @@ -76,20 +72,11 @@ module t ( /*AUTOARG*/ w4_u = ((5'b0 == (5'sb11111 >>> 3'd7))); // Exp 0 Vlt 0 `checkh(w4_u, 4'b0001); w4_u = ((5'b01111 == (5'sb11111 / 5'sd2))); // Strength-reduces to >>> -`ifdef VCS // I-2014.03 - `checkh(w4_u, 4'b0000); // Wrong, gets 5'b0==..., unsigned does not propagate -`else - `checkh(w4_u, 4'b0001); // NC-Verilog, Modelsim, XSim, ... -`endif + `checkh(w4_u, 4'b0001); - // Does == sign propagate from lhs to rhs? Yes, but not in VCS + // Does == sign propagate from lhs to rhs? w4_u = ((5'b01010 == (5'sb11111 / 5'sd3))); // Exp 0 Vlt 0 // Must be signed result (-1/3) to make this result zero -`ifdef VCS // I-2014.03 - `checkh(w4_u, 4'b0000); // Wrong, gets 5'b0==..., unsigned does not propagate - // Somewhat questionable, as spec says division signed depends on only LHS and RHS, however differs from others -`else - `checkh(w4_u, 4'b0001); // NC-Verilog, Modelsim, XSim, ... -`endif + `checkh(w4_u, 4'b0001); w4_u = (1'b0+(5'sb11111 >>> 3'd7)); // Exp 00000 Vlt 000000 Actually the signedness of result does NOT matter `checkh(w4_u, 4'b0000); diff --git a/test_regress/t/t_math_svl2.v b/test_regress/t/t_math_svl2.v index b6049d112..1d62f7006 100644 --- a/test_regress/t/t_math_svl2.v +++ b/test_regress/t/t_math_svl2.v @@ -19,15 +19,11 @@ module t ( if ('1 !== {66{1'b1}}) $stop; if ('x !== {66{1'bx}}) $stop; if ('z !== {66{1'bz}}) $stop; -`ifndef NC // NC-Verilog 5.50-s09 chokes on this test if ("\v" != 8'd11) $stop; if ("\f" != 8'd12) $stop; if ("\a" != 8'd7) $stop; if ("\x9a" != 8'h9a) $stop; if ("\xf1" != 8'hf1) $stop; -`endif - end - if (cyc == 8) begin end if (cyc == 9) begin $write("*-* All Finished *-*\n"); diff --git a/test_regress/t/t_modport_export_task.v b/test_regress/t/t_modport_export_task.v index 848c05ccf..0016f7a3d 100644 --- a/test_regress/t/t_modport_export_task.v +++ b/test_regress/t/t_modport_export_task.v @@ -5,7 +5,8 @@ // SPDX-License-Identifier: CC0-1.0 // verilog_format: off -`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0) +`define stop $stop +`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0) // verilog_format: on interface bus_if; diff --git a/test_regress/t/t_param_first.v b/test_regress/t/t_param_first.v index eea84e2c3..6ded92a93 100644 --- a/test_regress/t/t_param_first.v +++ b/test_regress/t/t_param_first.v @@ -63,12 +63,11 @@ module t ( parameter THREE_2WIDE = 2'b11; parameter ALSO_THREE_WIDE = THREE_BITS_WIDE; parameter THREEPP_32_WIDE = 2 * 8 * 2 + 3; - parameter THREEPP_3_WIDE = 3'd4 * 3'd4 * 3'd2 + 3'd3; // Yes folks VCS says 3 bits wide + parameter THREEPP_3_WIDE = 3'd4 * 3'd4 * 3'd2 + 3'd3; // Width propagation doesn't care about LHS vs RHS // But the width of a RHS/LHS on a upper node does affect lower nodes; // Thus must double-descend in width analysis. - // VCS 7.0.1 is broken on this test! parameter T10 = (3'h7 + 3'h7) + 4'h0; //initial if (T10!==4'd14) $stop; parameter T11 = 4'h0 + (3'h7 + 3'h7); //initial if (T11!==4'd14) $stop; diff --git a/test_regress/t/t_prop_always.v b/test_regress/t/t_prop_always.v index 52cfea02c..f389a3a8c 100644 --- a/test_regress/t/t_prop_always.v +++ b/test_regress/t/t_prop_always.v @@ -43,11 +43,9 @@ module t ( // Constant-false: every attempt fails. assert property (@(posedge clk) always [0:3] a_low) - ; else low_bounded_fail_q.push_back(cyc); assert property (@(posedge clk) always [0:0] a_low) - ; else low_degenerate_fail_q.push_back(cyc); // CRC-driven random input: window [cyc..cyc+3] of a_rand. @@ -76,21 +74,21 @@ module t ( crc <= {crc[62:0], crc[63] ^ crc[2] ^ crc[0]}; if (cyc == 19) begin // Constant-true window [0:3]: K=0..16 succeed at cyc K+3 = 3..19. - `checkd(high_bounded_pass_q.size(), 17); - `checkd(high_bounded_pass_q[0], 3); + `checkd(high_bounded_pass_q.size(), 17); // Other sims: 16 + `checkd(high_bounded_pass_q[0], 3); // Other sims: 4 `checkd(high_bounded_pass_q[$], 19); // Degenerate [0:0]: K=0..19 succeed at cyc K = 0..19. - `checkd(high_degenerate_pass_q.size(), 20); - `checkd(high_degenerate_pass_q[0], 0); + `checkd(high_degenerate_pass_q.size(), 20); // Other sims: 19 + `checkd(high_degenerate_pass_q[0], 0); // Other sims: 0, 1 `checkd(high_degenerate_pass_q[$], 19); // Constant-false: every attempt fails immediately. - `checkd(low_bounded_fail_q.size(), 20); - `checkd(low_degenerate_fail_q.size(), 20); - // CRC + disable streams: counts pinned (cross-checked against Questa). + `checkd(low_bounded_fail_q.size(), 20); // Other sims: 19 + `checkd(low_degenerate_fail_q.size(), 20); // Other sims: 19 + // CRC + disable streams `checkd(rand_bounded_pass_q.size(), 0); - `checkd(rand_bounded_fail_q.size(), 20); + `checkd(rand_bounded_fail_q.size(), 20); // Other sims: 19, 11 `checkd(disable_bounded_pass_q.size(), 0); - `checkd(disable_bounded_fail_q.size(), 13); + `checkd(disable_bounded_fail_q.size(), 13); // Other sims: 5, 6 $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_prop_followed_by.v b/test_regress/t/t_prop_followed_by.v index c1e5778a6..6cc11045a 100644 --- a/test_regress/t/t_prop_followed_by.v +++ b/test_regress/t/t_prop_followed_by.v @@ -4,11 +4,10 @@ // SPDX-FileCopyrightText: 2026 PlanV GmbH // SPDX-License-Identifier: CC0-1.0 -`define checkd(gotv, expv) \ - do if ((gotv) !== (expv)) begin \ - $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__, `__LINE__, (gotv), (expv)); \ - $stop; \ - end while (0); +// verilog_format: off +`define stop $stop +`define checkd(gotv, expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); +// verilog_format: on module t ( input clk @@ -54,13 +53,11 @@ module t ( cyc <= cyc + 1; crc <= {crc[62:0], crc[63] ^ crc[2] ^ crc[0]}; if (cyc == 32) begin - // Counts are deterministic for this CRC seed. Questa reference run - // (IEEE 1800-2023 16.12.9) reports ovl=28, novl=19, impl=9, nimp=0; the // ovl/novl deltas vs Verilator are 1-cycle preponed-sampling differences. $display("ovl=%0d novl=%0d impl=%0d nimp=%0d wide=%0d", ovl_f, novl_f, impl_f, nimp_f, wide_f); - `checkd(ovl_f, 29); - `checkd(novl_f, 20); + `checkd(ovl_f, 29); // Other sims: 28, one other sim: 5 + `checkd(novl_f, 20); // Other sims: 19 `checkd(impl_f, 9); `checkd(nimp_f, 0); `checkd(wide_f, 0); diff --git a/test_regress/t/t_property_accept_reject_on.v b/test_regress/t/t_property_accept_reject_on.v index 1affe217c..080af892c 100644 --- a/test_regress/t/t_property_accept_reject_on.v +++ b/test_regress/t/t_property_accept_reject_on.v @@ -94,16 +94,16 @@ module t ( end else if (cyc == 99) begin `checkh(crc, 64'hc77bb9b3784ea091); - `checkd(count_fail1, 28); // Questa: 14 - `checkd(count_fail2, 64); // Questa: 64 - `checkd(count_fail3, 28); // Questa: 14 - `checkd(count_fail4, 64); // Questa: 64 - `checkd(count_fail5, 45); // Questa: 31 - `checkd(count_fail6, 64); // Questa: 59 - `checkd(count_fail7, 28); // Questa: 14 - `checkd(count_fail8, 13); // Questa: 10 - `checkd(count_fail9, 28); // Questa: 14 - `checkd(count_fail10, 28); // Questa: 14 + `checkd(count_fail1, 28); // Other sims: 14, one other: 15 + `checkd(count_fail2, 64); // One other sim: 66 + `checkd(count_fail3, 28); // Other sims: 14 + `checkd(count_fail4, 64); + `checkd(count_fail5, 45); // Other sims: 31, one other: 32 + `checkd(count_fail6, 64); // Other sims: 59, one other: 60 + `checkd(count_fail7, 28); // Other sims: 14, one other: 15 + `checkd(count_fail8, 13); // Other sims: 10 + `checkd(count_fail9, 28); // Other sims: 14, one other: 15 + `checkd(count_fail10, 28); // Other sims: 14 $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_property_disable_iff_held.v b/test_regress/t/t_property_disable_iff_held.v index 04530fc6e..37fa06461 100644 --- a/test_regress/t/t_property_disable_iff_held.v +++ b/test_regress/t/t_property_disable_iff_held.v @@ -46,20 +46,12 @@ module t ( cyc <= cyc + 1; crc <= {crc[62:0], crc[63] ^ crc[2] ^ crc[0]}; if (cyc == 99) begin - `checkd(n_held_assert, 0); // Questa: 0 - `checkd(n_held_cover, 0); // Questa: 0 - `checkd(n_ctrl_assert, 58); // Questa: 58 - `checkd(n_ctrl_cover, 26); // Questa: 26 + `checkd(n_held_assert, 0); + `checkd(n_held_cover, 0); + `checkd(n_ctrl_assert, 58); + `checkd(n_ctrl_cover, 26); // Others: 26, One other: 0 $write("*-* All Finished *-*\n"); $finish; end end endmodule - -`ifndef VERILATOR -module wrap; - logic clk = 0; - always #5 clk = ~clk; - t inst (.clk(clk)); -endmodule -`endif diff --git a/test_regress/t/t_property_until_implication.v b/test_regress/t/t_property_until_implication.v index 6023ac501..2f345677f 100644 --- a/test_regress/t/t_property_until_implication.v +++ b/test_regress/t/t_property_until_implication.v @@ -50,12 +50,12 @@ module t ( crc <= 64'h5aef0c8d_d70a4497; end else if (cyc == 99) begin - // Counts reflect NFA per-cycle reject aggregation, not Questa's + // Counts reflect NFA per-cycle reject aggregation, not some other sim's // per-attempt action_block firing; the two differ by a small constant // (see PR description for the model gap). Test is a regression for // "no internal error on `until` as |=> consequent" (issue #7548). - `checkd(fail_nonoverlap, 7); - `checkd(fail_overlap, 22); + `checkd(fail_nonoverlap, 7); // Other sims: 8, one other: 7 + `checkd(fail_overlap, 22); // Other sims: 24, one other: 22 $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_randsequence.v b/test_regress/t/t_randsequence.v index 739178d02..7d00d9e15 100644 --- a/test_regress/t/t_randsequence.v +++ b/test_regress/t/t_randsequence.v @@ -7,8 +7,9 @@ // SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 // verilog_format: off -`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); -`define check_range(gotv,minv,maxv) do if ((gotv) < (minv) || (gotv) > (maxv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d-%0d\n", `__FILE__,`__LINE__, (gotv), (minv), (maxv)); $stop; end while(0); +`define stop $stop +`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); +`define check_range(gotv,minv,maxv) do if ((gotv) < (minv) || (gotv) > (maxv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d-%0d\n", `__FILE__,`__LINE__, (gotv), (minv), (maxv)); `stop; end while(0); `define check_within_30_percent(gotv,val) `check_range((gotv), (val) * 70 / 100, (val) * 130 / 100) // verilog_format: on diff --git a/test_regress/t/t_randsequence_func.v b/test_regress/t/t_randsequence_func.v index ac06220bc..2374251af 100644 --- a/test_regress/t/t_randsequence_func.v +++ b/test_regress/t/t_randsequence_func.v @@ -7,7 +7,8 @@ // SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 // verilog_format: off -`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); +`define stop $stop +`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); // verilog_format: on module t; diff --git a/test_regress/t/t_randsequence_randjoin.v b/test_regress/t/t_randsequence_randjoin.v index 47bd297c2..d0d2febcd 100644 --- a/test_regress/t/t_randsequence_randjoin.v +++ b/test_regress/t/t_randsequence_randjoin.v @@ -7,8 +7,9 @@ // SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 // verilog_format: off -`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); -`define check_range(gotv,minv,maxv) do if ((gotv) < (minv) || (gotv) > (maxv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d-%0d\n", `__FILE__,`__LINE__, (gotv), (minv), (maxv)); $stop; end while(0); +`define stop $stop +`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); +`define check_range(gotv,minv,maxv) do if ((gotv) < (minv) || (gotv) > (maxv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d-%0d\n", `__FILE__,`__LINE__, (gotv), (minv), (maxv)); `stop; end while(0); `define check_within_30_percent(gotv,val) `check_range((gotv), (val) * 70 / 100, (val) * 130 / 100) // verilog_format: on diff --git a/test_regress/t/t_randsequence_svtests.v b/test_regress/t/t_randsequence_svtests.v index dd087d63b..b4c549148 100644 --- a/test_regress/t/t_randsequence_svtests.v +++ b/test_regress/t/t_randsequence_svtests.v @@ -4,7 +4,8 @@ // SPDX-License-Identifier: ISC // verilog_format: off -`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); +`define stop $stop +`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); // verilog_format: on module t; diff --git a/test_regress/t/t_sequence_intersect_nevermatch.v b/test_regress/t/t_sequence_intersect_nevermatch.v index 17887e184..38abde53a 100644 --- a/test_regress/t/t_sequence_intersect_nevermatch.v +++ b/test_regress/t/t_sequence_intersect_nevermatch.v @@ -5,7 +5,8 @@ // SPDX-License-Identifier: CC0-1.0 // verilog_format: off -`define checkd(gotv, expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); +`define stop $stop +`define checkd(gotv, expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); // verilog_format: on module t ( @@ -51,7 +52,8 @@ module t ( else f_dis <= f_dis + 1; final begin - `checkd(f_fix, 0); // Questa: 0 - `checkd(f_dis, 0); // Questa: 0 + // TODO need better non-zero test + `checkd(f_fix, 0); + `checkd(f_dis, 0); end endmodule diff --git a/test_regress/t/t_sequence_intersect_varlen.v b/test_regress/t/t_sequence_intersect_varlen.v index 402560af3..72eaa8601 100644 --- a/test_regress/t/t_sequence_intersect_varlen.v +++ b/test_regress/t/t_sequence_intersect_varlen.v @@ -5,7 +5,8 @@ // SPDX-License-Identifier: CC0-1.0 // verilog_format: off -`define checkd(gotv, expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); +`define stop $stop +`define checkd(gotv, expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); // verilog_format: on module t ( @@ -25,7 +26,7 @@ module t ( int f_collapse = 0; int f_over = 0; - always_ff @(posedge clk) begin + always @(posedge clk) begin cyc <= cyc + 1; crc <= {crc[62:0], crc[63] ^ crc[2] ^ crc[0]}; if (cyc == 99) begin @@ -63,9 +64,9 @@ module t ( else f_over <= f_over + 1; final begin - `checkd(f_var, 7); // Questa: 7 - `checkd(f_ieee, 41); // Questa: 41 - `checkd(f_collapse, 0); // Questa: 0 - `checkd(f_over, 84); // Questa: 84 + `checkd(f_var, 7); + `checkd(f_ieee, 41); + `checkd(f_collapse, 0); + `checkd(f_over, 84); end endmodule diff --git a/test_regress/t/t_sequence_sexpr_throughout.v b/test_regress/t/t_sequence_sexpr_throughout.v index a2b17ef46..8b9fe3cfa 100644 --- a/test_regress/t/t_sequence_sexpr_throughout.v +++ b/test_regress/t/t_sequence_sexpr_throughout.v @@ -74,7 +74,7 @@ module t ( // by the throughout-drop check. cover property (@(posedge clk) a throughout (b ##1 c)); - always_ff @(posedge clk) begin + always @(posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x cond=%b a=%b b=%b c=%b\n", $time, cyc, crc, cond, a, b, c); @@ -85,15 +85,15 @@ module t ( crc <= 64'h5aef0c8d_d70a4497; end else if (cyc == 99) begin `checkh(crc, 64'hc77bb9b3784ea091); - `checkd(count_fail1, 28); // Questa: 28 - `checkd(count_fail2, 33); // Questa: 33 - `checkd(count_fail3, 31); // Questa: 31 - `checkd(count_fail4, 35); // Questa: 35 + `checkd(count_fail1, 28); + `checkd(count_fail2, 33); + `checkd(count_fail3, 31); + `checkd(count_fail4, 35); // count_fail5: NFA undercounts by 12; throughout+temporal-and first-step // rejection is a known limitation of the SAnd combiner architecture // (propagating isTopLevelStep causes double-counting; fix is future work). - `checkd(count_fail5, 25); // Questa: 36 - `checkd(count_fail6, 33); // Questa: 33 + `checkd(count_fail5, 25); // All other sims: 36 + `checkd(count_fail6, 33); $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_sequence_within.v b/test_regress/t/t_sequence_within.v index dcffaae56..e8d73ad61 100644 --- a/test_regress/t/t_sequence_within.v +++ b/test_regress/t/t_sequence_within.v @@ -11,9 +11,6 @@ // verilog_format: on // IEEE 1800-2023 16.9.10: seq1 within seq2 -// CRC-driven random stimulus. Each property has a counter; at cyc==99 we -// `checkd` against Verilator's actual count and record the Questa golden -// value in a trailing comment for cross-simulator reference. module t ( input clk @@ -93,7 +90,7 @@ module t ( initial $assertvacuousoff; - always_ff @(posedge clk) begin + always @(posedge clk) begin cyc <= cyc + 1; crc <= {crc[62:0], crc[63] ^ crc[2] ^ crc[0]}; @@ -103,30 +100,20 @@ module t ( else if (cyc == 99) begin `checkh(crc, 64'hc77bb9b3784ea091); // p1/p2/p5 use |->; the NFA currently fires the pass action on - // vacuous passes too, so counts are inflated vs. Questa. Pre-existing + // vacuous passes too, so counts are inflated vs. others. Pre-existing // engine-wide behavior, not within-specific. - `checkd(count_p1, 23); // Questa: 23 - `checkd(count_p2, 44); // Questa: 44 - `checkd(count_p3, 25); // Questa: 20 - `checkd(count_p4, 23); // Questa: 22 - `checkd(count_p5, 26); // Questa: 26 - `checkd(count_p6, 21); // Questa: 16 - `checkd(count_p7, 15); // Questa: 9 - `checkd(count_p8, 15); // Questa: 4 - `checkd(count_p9, 15); // Questa: 10 - `checkd(count_p10, 23); // Questa: 15 + `checkd(count_p1, 23); // Other sims: 23, or 16 + `checkd(count_p2, 44); // Other sims: 44, or 21 + `checkd(count_p3, 25); // Other sims: 20 + `checkd(count_p4, 23); // Other sims: 22 + `checkd(count_p5, 26); + `checkd(count_p6, 21); // Other sims: 16 + `checkd(count_p7, 15); // Other sims: 9 + `checkd(count_p8, 15); // Other sims: 4 + `checkd(count_p9, 15); // Other sims: 10 + `checkd(count_p10, 23); // Other sims: 15 $write("*-* All Finished *-*\n"); $finish; end end endmodule - -// Harness for stand-alone simulators (e.g. QuestaSim). Verilator uses -// test_regress's built-in clock shell and ignores this module. -`ifndef VERILATOR -module wrap; - logic clk = 0; - always #5 clk = ~clk; - t inst (.clk(clk)); -endmodule -`endif diff --git a/test_regress/t/t_sv_cpu.py b/test_regress/t/t_sv_cpu.py index dcc41dab2..0eb062f2a 100755 --- a/test_regress/t/t_sv_cpu.py +++ b/test_regress/t/t_sv_cpu.py @@ -14,23 +14,22 @@ test.scenarios('simulator') # 22-Mar-2012: Modifications for this test contributed by Jeremy Bennett, # Embecosm. -test.compile( - # Taken from the original VCS command line. - v_flags2=[ - "t/t_sv_cpu_code/timescale.sv", "t/t_sv_cpu_code/program_h.sv", - "t/t_sv_cpu_code/pads_h.sv", "t/t_sv_cpu_code/ports_h.sv", "t/t_sv_cpu_code/pinout_h.sv", - "t/t_sv_cpu_code/genbus_if.sv", "t/t_sv_cpu_code/pads_if.sv", "t/t_sv_cpu_code/adrdec.sv", - "t/t_sv_cpu_code/pad_gpio.sv", "t/t_sv_cpu_code/pad_vdd.sv", "t/t_sv_cpu_code/pad_gnd.sv", - "t/t_sv_cpu_code/pads.sv", "t/t_sv_cpu_code/ports.sv", "t/t_sv_cpu_code/ac_dig.sv", - "t/t_sv_cpu_code/ac_ana.sv", "t/t_sv_cpu_code/ac.sv", "t/t_sv_cpu_code/cpu.sv", - "t/t_sv_cpu_code/chip.sv" - ], - vcs_flags2=["-R -sverilog +memcbk -y t/t_sv_cpu_code +libext+.sv+ +incdir+t/t_sv_cpu_code"], - verilator_flags2=[ - "-y t/t_sv_cpu_code +libext+.sv+ +incdir+t/t_sv_cpu_code --top-module t", - "--timescale-override 1ns/1ps" - ], - iv_flags2=["-yt/t_sv_cpu_code -It/t_sv_cpu_code -Y.sv"]) +test.compile(v_flags2=[ + "t/t_sv_cpu_code/timescale.sv", "t/t_sv_cpu_code/program_h.sv", "t/t_sv_cpu_code/pads_h.sv", + "t/t_sv_cpu_code/ports_h.sv", "t/t_sv_cpu_code/pinout_h.sv", "t/t_sv_cpu_code/genbus_if.sv", + "t/t_sv_cpu_code/pads_if.sv", "t/t_sv_cpu_code/adrdec.sv", "t/t_sv_cpu_code/pad_gpio.sv", + "t/t_sv_cpu_code/pad_vdd.sv", "t/t_sv_cpu_code/pad_gnd.sv", "t/t_sv_cpu_code/pads.sv", + "t/t_sv_cpu_code/ports.sv", "t/t_sv_cpu_code/ac_dig.sv", "t/t_sv_cpu_code/ac_ana.sv", + "t/t_sv_cpu_code/ac.sv", "t/t_sv_cpu_code/cpu.sv", "t/t_sv_cpu_code/chip.sv" +], + vcs_flags2=[ + "-R -sverilog +memcbk -y t/t_sv_cpu_code +libext+.sv+ +incdir+t/t_sv_cpu_code" + ], + verilator_flags2=[ + "-y t/t_sv_cpu_code +libext+.sv+ +incdir+t/t_sv_cpu_code --top-module t", + "--timescale-override 1ns/1ps" + ], + iv_flags2=["-yt/t_sv_cpu_code -It/t_sv_cpu_code -Y.sv"]) test.execute() diff --git a/test_regress/t/t_sys_file_scan_delay.v b/test_regress/t/t_sys_file_scan_delay.v index f1db0a34e..efb4e4659 100644 --- a/test_regress/t/t_sys_file_scan_delay.v +++ b/test_regress/t/t_sys_file_scan_delay.v @@ -6,7 +6,7 @@ // verilog_format: off `define stop $stop -`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); +`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); // verilog_format: on module t; diff --git a/test_regress/t/t_tagged_case.out b/test_regress/t/t_tagged_case.out index e7965a85d..edec504d1 100644 --- a/test_regress/t/t_tagged_case.out +++ b/test_regress/t/t_tagged_case.out @@ -11,142 +11,142 @@ %Error-UNSUPPORTED: t/t_tagged_case.v:65:5: Unsupported: void (for tagged unions) 65 | void Invalid; | ^~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:71:5: Unsupported: void (for tagged unions) - 71 | void Invalid; +%Error-UNSUPPORTED: t/t_tagged_case.v:73:5: Unsupported: void (for tagged unions) + 73 | void Invalid; | ^~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:80:5: Unsupported: void (for tagged unions) - 80 | void Invalid; +%Error-UNSUPPORTED: t/t_tagged_case.v:82:5: Unsupported: void (for tagged unions) + 82 | void Invalid; | ^~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:87:5: Unsupported: void (for tagged unions) - 87 | void Invalid; +%Error-UNSUPPORTED: t/t_tagged_case.v:89:5: Unsupported: void (for tagged unions) + 89 | void Invalid; | ^~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:93:5: Unsupported: void (for tagged unions) - 93 | void Invalid; +%Error-UNSUPPORTED: t/t_tagged_case.v:95:5: Unsupported: void (for tagged unions) + 95 | void Invalid; | ^~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:102:5: Unsupported: void (for tagged unions) - 102 | void Invalid; +%Error-UNSUPPORTED: t/t_tagged_case.v:104:5: Unsupported: void (for tagged unions) + 104 | void Invalid; | ^~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:126:9: Unsupported: tagged union - 126 | v = tagged Invalid; +%Error-UNSUPPORTED: t/t_tagged_case.v:128:9: Unsupported: tagged union + 128 | v = tagged Invalid; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:128:5: Unsupported: case matches (for tagged union) - 128 | case (v) matches +%Error-UNSUPPORTED: t/t_tagged_case.v:130:5: Unsupported: case matches (for tagged union) + 130 | case (v) matches | ^~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:129:7: Unsupported: tagged union - 129 | tagged Invalid : result = 1; +%Error-UNSUPPORTED: t/t_tagged_case.v:131:7: Unsupported: tagged union + 131 | tagged Invalid : result = 1; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:130:7: Unsupported: tagged pattern - 130 | tagged Valid .n : result = n; +%Error-UNSUPPORTED: t/t_tagged_case.v:132:7: Unsupported: tagged pattern + 132 | tagged Valid .n : result = n; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:130:20: Unsupported: pattern variable - 130 | tagged Valid .n : result = n; +%Error-UNSUPPORTED: t/t_tagged_case.v:132:20: Unsupported: pattern variable + 132 | tagged Valid .n : result = n; | ^ -%Error-UNSUPPORTED: t/t_tagged_case.v:135:9: Unsupported: tagged union - 135 | v = tagged Valid (123); +%Error-UNSUPPORTED: t/t_tagged_case.v:137:9: Unsupported: tagged union + 137 | v = tagged Valid (123); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:137:5: Unsupported: case matches (for tagged union) - 137 | case (v) matches +%Error-UNSUPPORTED: t/t_tagged_case.v:139:5: Unsupported: case matches (for tagged union) + 139 | case (v) matches | ^~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:138:7: Unsupported: tagged union - 138 | tagged Invalid : result = -1; +%Error-UNSUPPORTED: t/t_tagged_case.v:140:7: Unsupported: tagged union + 140 | tagged Invalid : result = -1; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:139:7: Unsupported: tagged pattern - 139 | tagged Valid .n : result = n; +%Error-UNSUPPORTED: t/t_tagged_case.v:141:7: Unsupported: tagged pattern + 141 | tagged Valid .n : result = n; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:139:20: Unsupported: pattern variable - 139 | tagged Valid .n : result = n; +%Error-UNSUPPORTED: t/t_tagged_case.v:141:20: Unsupported: pattern variable + 141 | tagged Valid .n : result = n; | ^ -%Error-UNSUPPORTED: t/t_tagged_case.v:144:10: Unsupported: tagged union - 144 | wt = tagged Wide60 (60'hFEDCBA987654321); +%Error-UNSUPPORTED: t/t_tagged_case.v:146:10: Unsupported: tagged union + 146 | wt = tagged Wide60 (60'hFEDCBA987654321); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:146:5: Unsupported: case matches (for tagged union) - 146 | case (wt) matches +%Error-UNSUPPORTED: t/t_tagged_case.v:148:5: Unsupported: case matches (for tagged union) + 148 | case (wt) matches | ^~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:147:7: Unsupported: tagged union - 147 | tagged Invalid : wide60_result = 0; +%Error-UNSUPPORTED: t/t_tagged_case.v:149:7: Unsupported: tagged union + 149 | tagged Invalid : wide60_result = 0; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:148:7: Unsupported: tagged pattern - 148 | tagged Wide60 .w : wide60_result = w; +%Error-UNSUPPORTED: t/t_tagged_case.v:150:7: Unsupported: tagged pattern + 150 | tagged Wide60 .w : wide60_result = w; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:148:21: Unsupported: pattern variable - 148 | tagged Wide60 .w : wide60_result = w; +%Error-UNSUPPORTED: t/t_tagged_case.v:150:21: Unsupported: pattern variable + 150 | tagged Wide60 .w : wide60_result = w; | ^ -%Error-UNSUPPORTED: t/t_tagged_case.v:154:10: Unsupported: tagged union - 154 | wt = tagged Wide90 (90'hDE_ADBEEFCA_FEBABE12_3456); +%Error-UNSUPPORTED: t/t_tagged_case.v:158:10: Unsupported: tagged union + 158 | wt = tagged Wide90 (90'hDE_ADBEEFCA_FEBABE12_3456); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:156:5: Unsupported: case matches (for tagged union) - 156 | case (wt) matches +%Error-UNSUPPORTED: t/t_tagged_case.v:160:5: Unsupported: case matches (for tagged union) + 160 | case (wt) matches | ^~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:157:7: Unsupported: tagged union - 157 | tagged Invalid : wide90_result = 0; +%Error-UNSUPPORTED: t/t_tagged_case.v:161:7: Unsupported: tagged union + 161 | tagged Invalid : wide90_result = 0; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:158:7: Unsupported: tagged pattern - 158 | tagged Wide90 .w : wide90_result = w; +%Error-UNSUPPORTED: t/t_tagged_case.v:162:7: Unsupported: tagged pattern + 162 | tagged Wide90 .w : wide90_result = w; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:158:21: Unsupported: pattern variable - 158 | tagged Wide90 .w : wide90_result = w; +%Error-UNSUPPORTED: t/t_tagged_case.v:162:21: Unsupported: pattern variable + 162 | tagged Wide90 .w : wide90_result = w; | ^ -%Error-UNSUPPORTED: t/t_tagged_case.v:164:10: Unsupported: tagged union - 164 | wt = tagged Byte8NonZeroLSB (8'hA5); +%Error-UNSUPPORTED: t/t_tagged_case.v:170:10: Unsupported: tagged union + 170 | wt = tagged Byte8NonZeroLSB (8'hA5); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:166:5: Unsupported: case matches (for tagged union) - 166 | case (wt) matches +%Error-UNSUPPORTED: t/t_tagged_case.v:172:5: Unsupported: case matches (for tagged union) + 172 | case (wt) matches | ^~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:167:7: Unsupported: tagged pattern - 167 | tagged Byte8NonZeroLSB .b : result = b; +%Error-UNSUPPORTED: t/t_tagged_case.v:173:7: Unsupported: tagged pattern + 173 | tagged Byte8NonZeroLSB .b : result = b; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:167:30: Unsupported: pattern variable - 167 | tagged Byte8NonZeroLSB .b : result = b; +%Error-UNSUPPORTED: t/t_tagged_case.v:173:30: Unsupported: pattern variable + 173 | tagged Byte8NonZeroLSB .b : result = b; | ^ -%Error-UNSUPPORTED: t/t_tagged_case.v:173:10: Unsupported: tagged union - 173 | wt = tagged Word32LittleEndian (32'hDEADBEEF); +%Error-UNSUPPORTED: t/t_tagged_case.v:179:10: Unsupported: tagged union + 179 | wt = tagged Word32LittleEndian (32'hDEADBEEF); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:175:5: Unsupported: case matches (for tagged union) - 175 | case (wt) matches +%Error-UNSUPPORTED: t/t_tagged_case.v:181:5: Unsupported: case matches (for tagged union) + 181 | case (wt) matches | ^~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:176:7: Unsupported: tagged pattern - 176 | tagged Word32LittleEndian .w : result = w; +%Error-UNSUPPORTED: t/t_tagged_case.v:182:7: Unsupported: tagged pattern + 182 | tagged Word32LittleEndian .w : result = w; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:176:33: Unsupported: pattern variable - 176 | tagged Word32LittleEndian .w : result = w; +%Error-UNSUPPORTED: t/t_tagged_case.v:182:33: Unsupported: pattern variable + 182 | tagged Word32LittleEndian .w : result = w; | ^ -%Error-UNSUPPORTED: t/t_tagged_case.v:182:10: Unsupported: tagged union - 182 | at = tagged Arr '{10, 20, 30, 40}; +%Error-UNSUPPORTED: t/t_tagged_case.v:188:10: Unsupported: tagged union + 188 | at = tagged Arr '{10, 20, 30, 40}; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:184:5: Unsupported: case matches (for tagged union) - 184 | case (at) matches +%Error-UNSUPPORTED: t/t_tagged_case.v:190:5: Unsupported: case matches (for tagged union) + 190 | case (at) matches | ^~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:185:7: Unsupported: tagged union - 185 | tagged Invalid : result = -1; +%Error-UNSUPPORTED: t/t_tagged_case.v:191:7: Unsupported: tagged union + 191 | tagged Invalid : result = -1; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:186:7: Unsupported: tagged pattern - 186 | tagged Scalar .s : result = s; +%Error-UNSUPPORTED: t/t_tagged_case.v:192:7: Unsupported: tagged pattern + 192 | tagged Scalar .s : result = s; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:186:21: Unsupported: pattern variable - 186 | tagged Scalar .s : result = s; +%Error-UNSUPPORTED: t/t_tagged_case.v:192:21: Unsupported: pattern variable + 192 | tagged Scalar .s : result = s; | ^ -%Error-UNSUPPORTED: t/t_tagged_case.v:187:7: Unsupported: tagged pattern - 187 | tagged Arr .a : result = a[0] + a[1] + a[2] + a[3]; +%Error-UNSUPPORTED: t/t_tagged_case.v:193:7: Unsupported: tagged pattern + 193 | tagged Arr .a : result = a[0] + a[1] + a[2] + a[3]; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:187:18: Unsupported: pattern variable - 187 | tagged Arr .a : result = a[0] + a[1] + a[2] + a[3]; +%Error-UNSUPPORTED: t/t_tagged_case.v:193:18: Unsupported: pattern variable + 193 | tagged Arr .a : result = a[0] + a[1] + a[2] + a[3]; | ^ -%Error-UNSUPPORTED: t/t_tagged_case.v:192:13: Unsupported: tagged union - 192 | instr = tagged Jmp (tagged JmpC '{2'd1, 10'd256}); +%Error-UNSUPPORTED: t/t_tagged_case.v:198:13: Unsupported: tagged union + 198 | instr = tagged Jmp (tagged JmpC '{2'd1, 10'd256}); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:192:25: Unsupported: tagged union - 192 | instr = tagged Jmp (tagged JmpC '{2'd1, 10'd256}); +%Error-UNSUPPORTED: t/t_tagged_case.v:198:25: Unsupported: tagged union + 198 | instr = tagged Jmp (tagged JmpC '{2'd1, 10'd256}); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:194:5: Unsupported: case matches (for tagged union) - 194 | case (instr) matches +%Error-UNSUPPORTED: t/t_tagged_case.v:200:5: Unsupported: case matches (for tagged union) + 200 | case (instr) matches | ^~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:195:7: Unsupported: tagged pattern - 195 | tagged Add .* : result = -1; +%Error-UNSUPPORTED: t/t_tagged_case.v:201:7: Unsupported: tagged pattern + 201 | tagged Add .* : result = -1; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_case.v:195:18: Unsupported: pattern wildcard - 195 | tagged Add .* : result = -1; +%Error-UNSUPPORTED: t/t_tagged_case.v:201:18: Unsupported: pattern wildcard + 201 | tagged Add .* : result = -1; | ^~ -%Error-UNSUPPORTED: t/t_tagged_case.v:196:7: Unsupported: tagged union - 196 | tagged Jmp (tagged JmpU .a) : result = a; +%Error-UNSUPPORTED: t/t_tagged_case.v:202:7: Unsupported: tagged union + 202 | tagged Jmp (tagged JmpU .a) : result = a; | ^~~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_tagged_case.v b/test_regress/t/t_tagged_case.v index a2ebf02fc..ebf466c59 100644 --- a/test_regress/t/t_tagged_case.v +++ b/test_regress/t/t_tagged_case.v @@ -63,7 +63,9 @@ module t; // Tagged union with chandle member typedef union tagged { void Invalid; +`ifndef QUESTA chandle Handle; +`endif } ChandleType; // Tagged union with class reference member @@ -148,7 +150,9 @@ module t; tagged Wide60 .w : wide60_result = w; default : wide60_result = 0; endcase +`ifndef QUESTA `checkh(wide60_result, 60'hFEDCBA987654321); +`endif // Test 4: Wide type case matching - 90-bit wt = tagged Wide90 (90'hDE_ADBEEFCA_FEBABE12_3456); @@ -158,7 +162,9 @@ module t; tagged Wide90 .w : wide90_result = w; default : wide90_result = 0; endcase +`ifndef QUESTA `checkh(wide90_result, 90'hDE_ADBEEFCA_FEBABE12_3456); +`endif // Test 5: Non-zero LSB case match wt = tagged Byte8NonZeroLSB (8'hA5); @@ -203,7 +209,9 @@ module t; result = 0; case (cht) matches tagged Invalid : result = 1; +`ifndef QUESTA tagged Handle .* : result = 2; // Wildcard - can't bind chandle +`endif endcase `checkh(result, 1); @@ -213,9 +221,9 @@ module t; result = 0; case (clt) matches tagged Invalid : result = -1; - tagged Obj .o : result = o.value; + tagged Obj : result = 2; endcase - `checkh(result, 42); + `checkh(result, 2); // Test 11: Real member case matching rt = tagged Invalid; diff --git a/test_regress/t/t_tagged_if.out b/test_regress/t/t_tagged_if.out index 31b7cc0bb..db7e619f6 100644 --- a/test_regress/t/t_tagged_if.out +++ b/test_regress/t/t_tagged_if.out @@ -1,14 +1,14 @@ -%Error-UNSUPPORTED: t/t_tagged_if.v:218:37: Unsupported: &&& expression - 218 | if (instr matches tagged Jmp .j &&& +%Error-UNSUPPORTED: t/t_tagged_if.v:226:37: Unsupported: &&& expression + 226 | if (instr matches tagged Jmp .j &&& | ^~~ ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest -%Error-UNSUPPORTED: t/t_tagged_if.v:228:35: Unsupported: &&& expression - 228 | if (v matches tagged Valid .n &&& (n > 50)) +%Error-UNSUPPORTED: t/t_tagged_if.v:236:35: Unsupported: &&& expression + 236 | if (v matches tagged Valid .n &&& (n > 50)) | ^~~ -%Error-UNSUPPORTED: t/t_tagged_if.v:237:35: Unsupported: &&& expression - 237 | if (v matches tagged Valid .n &&& (n > 50)) +%Error-UNSUPPORTED: t/t_tagged_if.v:245:35: Unsupported: &&& expression + 245 | if (v matches tagged Valid .n &&& (n > 50)) | ^~~ -%Error-UNSUPPORTED: t/t_tagged_if.v:266:37: Unsupported: &&& expression - 266 | if (instr matches tagged Jmp .j &&& +%Error-UNSUPPORTED: t/t_tagged_if.v:274:37: Unsupported: &&& expression + 274 | if (instr matches tagged Jmp .j &&& | ^~~ %Error: Exiting due to diff --git a/test_regress/t/t_tagged_if.v b/test_regress/t/t_tagged_if.v index 46be66135..269219f9d 100644 --- a/test_regress/t/t_tagged_if.v +++ b/test_regress/t/t_tagged_if.v @@ -61,10 +61,12 @@ module t; } Instr; // Tagged union with chandle member +`ifndef QUESTA typedef union tagged { void Invalid; chandle Handle; } ChandleType; +`endif // Tagged union with class reference member typedef union tagged { @@ -108,7 +110,9 @@ module t; WideType wt; ArrayType at; Instr instr; +`ifndef QUESTA ChandleType cht; +`endif ClassType clt; TestClass obj; RealType rt; @@ -156,7 +160,9 @@ module t; wide60_result = w; else wide60_result = 0; +`ifndef QUESTA `checkh(wide60_result, 60'hFEDCBA987654321); +`endif // Test 5: Wide type if matching - 90-bit wt = tagged Wide90 (90'hDE_ADBEEFCA_FEBABE12_3456); @@ -165,7 +171,9 @@ module t; wide90_result = w; else wide90_result = 0; +`ifndef QUESTA `checkh(wide90_result, 90'hDE_ADBEEFCA_FEBABE12_3456); +`endif // Test 6: Non-zero LSB if match wt = tagged Byte8NonZeroLSB (8'hA5); @@ -291,6 +299,7 @@ module t; result = 2; `checkh(result, 1); +`ifndef QUESTA // Test 19: Chandle member if matching cht = tagged Invalid; result = 0; @@ -307,6 +316,7 @@ module t; else result = 2; `checkh(result, 1); +`endif // Test 20: Class reference member if matching obj = new(42); @@ -320,8 +330,8 @@ module t; clt = tagged Obj (obj); result = 0; - if (clt matches tagged Obj .o) - result = o.value; + if (clt matches tagged Obj) + result = 42; else result = -1; `checkh(result, 42); diff --git a/test_regress/t/t_tagged_union.out b/test_regress/t/t_tagged_union.out index ab08889dc..d31a3fdfa 100644 --- a/test_regress/t/t_tagged_union.out +++ b/test_regress/t/t_tagged_union.out @@ -8,145 +8,145 @@ %Error-UNSUPPORTED: t/t_tagged_union.v:57:5: Unsupported: void (for tagged unions) 57 | void Invalid; | ^~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:79:5: Unsupported: void (for tagged unions) - 79 | void Invalid; +%Error-UNSUPPORTED: t/t_tagged_union.v:80:5: Unsupported: void (for tagged unions) + 80 | void Invalid; | ^~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:85:5: Unsupported: void (for tagged unions) - 85 | void Invalid; +%Error-UNSUPPORTED: t/t_tagged_union.v:87:5: Unsupported: void (for tagged unions) + 87 | void Invalid; | ^~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:94:5: Unsupported: void (for tagged unions) - 94 | void Invalid; +%Error-UNSUPPORTED: t/t_tagged_union.v:96:5: Unsupported: void (for tagged unions) + 96 | void Invalid; | ^~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:101:5: Unsupported: void (for tagged unions) - 101 | void Invalid; +%Error-UNSUPPORTED: t/t_tagged_union.v:103:5: Unsupported: void (for tagged unions) + 103 | void Invalid; | ^~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:107:5: Unsupported: void (for tagged unions) - 107 | void Invalid; +%Error-UNSUPPORTED: t/t_tagged_union.v:109:5: Unsupported: void (for tagged unions) + 109 | void Invalid; | ^~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:116:5: Unsupported: void (for tagged unions) - 116 | void Invalid; +%Error-UNSUPPORTED: t/t_tagged_union.v:118:5: Unsupported: void (for tagged unions) + 118 | void Invalid; | ^~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:137:11: Unsupported: tagged union - 137 | vi1 = tagged Invalid; - | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:138:11: Unsupported: tagged union - 138 | vi2 = tagged Invalid; - | ^~~~~~ %Error-UNSUPPORTED: t/t_tagged_union.v:141:11: Unsupported: tagged union - 141 | vi1 = tagged Valid (42); + 141 | vi1 = tagged Invalid; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:144:11: Unsupported: tagged union - 144 | vi2 = tagged Valid (23 + 34); +%Error-UNSUPPORTED: t/t_tagged_union.v:142:11: Unsupported: tagged union + 142 | vi2 = tagged Invalid; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:148:10: Unsupported: tagged union - 148 | mt = tagged Invalid; +%Error-UNSUPPORTED: t/t_tagged_union.v:145:11: Unsupported: tagged union + 145 | vi1 = tagged Valid (42); + | ^~~~~~ +%Error-UNSUPPORTED: t/t_tagged_union.v:148:11: Unsupported: tagged union + 148 | vi2 = tagged Valid (23 + 34); + | ^~~~~~ +%Error-UNSUPPORTED: t/t_tagged_union.v:152:10: Unsupported: tagged union + 152 | mt = tagged Invalid; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:150:10: Unsupported: tagged union - 150 | mt = tagged IntVal (32'h12345678); +%Error-UNSUPPORTED: t/t_tagged_union.v:154:10: Unsupported: tagged union + 154 | mt = tagged IntVal (32'h12345678); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:153:10: Unsupported: tagged union - 153 | mt = tagged ShortVal (16'hABCD); +%Error-UNSUPPORTED: t/t_tagged_union.v:157:10: Unsupported: tagged union + 157 | mt = tagged ShortVal (16'hABCD); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:156:10: Unsupported: tagged union - 156 | mt = tagged ByteVal (8'h5A); - | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:159:10: Unsupported: tagged union - 159 | mt = tagged BitVal (1'b1); +%Error-UNSUPPORTED: t/t_tagged_union.v:160:10: Unsupported: tagged union + 160 | mt = tagged ByteVal (8'h5A); | ^~~~~~ %Error-UNSUPPORTED: t/t_tagged_union.v:163:10: Unsupported: tagged union - 163 | mt = tagged Byte8NonZeroLSB (8'hA5); + 163 | mt = tagged BitVal (1'b1); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:166:10: Unsupported: tagged union - 166 | mt = tagged Word16NonZeroLSB (16'h1234); +%Error-UNSUPPORTED: t/t_tagged_union.v:167:10: Unsupported: tagged union + 167 | mt = tagged Byte8NonZeroLSB (8'hA5); | ^~~~~~ %Error-UNSUPPORTED: t/t_tagged_union.v:170:10: Unsupported: tagged union - 170 | mt = tagged Word32LittleEndian (32'hDEADBEEF); + 170 | mt = tagged Word16NonZeroLSB (16'h1234); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:173:10: Unsupported: tagged union - 173 | mt = tagged Word16LittleEndian (16'hCAFE); +%Error-UNSUPPORTED: t/t_tagged_union.v:174:10: Unsupported: tagged union + 174 | mt = tagged Word32LittleEndian (32'hDEADBEEF); | ^~~~~~ %Error-UNSUPPORTED: t/t_tagged_union.v:177:10: Unsupported: tagged union - 177 | mt = tagged Wide60 (60'hFEDCBA987654321); + 177 | mt = tagged Word16LittleEndian (16'hCAFE); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:180:10: Unsupported: tagged union - 180 | mt = tagged Wide60NonZeroLSB (60'h123456789ABCDEF); +%Error-UNSUPPORTED: t/t_tagged_union.v:181:10: Unsupported: tagged union + 181 | mt = tagged Wide60 (60'hFEDCBA987654321); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:183:10: Unsupported: tagged union - 183 | mt = tagged Wide60LittleEndian (60'hABCDEF012345678); +%Error-UNSUPPORTED: t/t_tagged_union.v:184:10: Unsupported: tagged union + 184 | mt = tagged Wide60NonZeroLSB (60'h123456789ABCDEF); | ^~~~~~ %Error-UNSUPPORTED: t/t_tagged_union.v:187:10: Unsupported: tagged union - 187 | mt = tagged Wide90 (90'hFF_FFFFFFFF_FFFFFFFF_FFFF); + 187 | mt = tagged Wide60LittleEndian (60'hABCDEF012345678); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:190:10: Unsupported: tagged union - 190 | mt = tagged Wide90NonZeroLSB (90'hDE_ADBEEFCA_FEBABE12_3456); +%Error-UNSUPPORTED: t/t_tagged_union.v:191:10: Unsupported: tagged union + 191 | mt = tagged Wide90 (90'hFF_FFFFFFFF_FFFFFFFF_FFFF); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:193:10: Unsupported: tagged union - 193 | mt = tagged Wide90LittleEndian (90'h11_11111122_22222233_3333); +%Error-UNSUPPORTED: t/t_tagged_union.v:194:10: Unsupported: tagged union + 194 | mt = tagged Wide90NonZeroLSB (90'hDE_ADBEEFCA_FEBABE12_3456); | ^~~~~~ %Error-UNSUPPORTED: t/t_tagged_union.v:197:10: Unsupported: tagged union - 197 | at = tagged Invalid; + 197 | mt = tagged Wide90LittleEndian (90'h11_11111122_22222233_3333); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:199:10: Unsupported: tagged union - 199 | at = tagged Scalar (999); +%Error-UNSUPPORTED: t/t_tagged_union.v:201:10: Unsupported: tagged union + 201 | at = tagged Invalid; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:202:10: Unsupported: tagged union - 202 | at = tagged UnpackedArr '{100, 200, 300, 400}; +%Error-UNSUPPORTED: t/t_tagged_union.v:203:10: Unsupported: tagged union + 203 | at = tagged Scalar (999); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:208:10: Unsupported: tagged union - 208 | at = tagged UnpackedArr2D '{'{32'hA, 32'hB, 32'hC}, '{32'hD, 32'hE, 32'hF}}; +%Error-UNSUPPORTED: t/t_tagged_union.v:206:10: Unsupported: tagged union + 206 | at = tagged UnpackedArr '{100, 200, 300, 400}; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:217:13: Unsupported: tagged union - 217 | instr = tagged Add '{5'd1, 5'd2, 5'd3}; +%Error-UNSUPPORTED: t/t_tagged_union.v:212:10: Unsupported: tagged union + 212 | at = tagged UnpackedArr2D '{'{32'hA, 32'hB, 32'hC}, '{32'hD, 32'hE, 32'hF}}; + | ^~~~~~ +%Error-UNSUPPORTED: t/t_tagged_union.v:221:13: Unsupported: tagged union + 221 | instr = tagged Add '{5'd1, 5'd2, 5'd3}; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:223:13: Unsupported: tagged union - 223 | instr = tagged Add '{reg2:5'd10, regd:5'd20, reg1:5'd5}; +%Error-UNSUPPORTED: t/t_tagged_union.v:227:13: Unsupported: tagged union + 227 | instr = tagged Add '{reg2:5'd10, regd:5'd20, reg1:5'd5}; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:229:13: Unsupported: tagged union - 229 | instr = tagged Jmp (tagged JmpU 10'd512); - | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:229:25: Unsupported: tagged union - 229 | instr = tagged Jmp (tagged JmpU 10'd512); - | ^~~~~~ %Error-UNSUPPORTED: t/t_tagged_union.v:233:13: Unsupported: tagged union - 233 | instr = tagged Jmp (tagged JmpC '{2'd1, 10'd256}); + 233 | instr = tagged Jmp (tagged JmpU 10'd512); | ^~~~~~ %Error-UNSUPPORTED: t/t_tagged_union.v:233:25: Unsupported: tagged union - 233 | instr = tagged Jmp (tagged JmpC '{2'd1, 10'd256}); + 233 | instr = tagged Jmp (tagged JmpU 10'd512); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:238:13: Unsupported: tagged union - 238 | instr = tagged Jmp (tagged JmpC '{cc:2'd3, addr:10'd100}); +%Error-UNSUPPORTED: t/t_tagged_union.v:237:13: Unsupported: tagged union + 237 | instr = tagged Jmp (tagged JmpC '{2'd1, 10'd256}); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:238:25: Unsupported: tagged union - 238 | instr = tagged Jmp (tagged JmpC '{cc:2'd3, addr:10'd100}); +%Error-UNSUPPORTED: t/t_tagged_union.v:237:25: Unsupported: tagged union + 237 | instr = tagged Jmp (tagged JmpC '{2'd1, 10'd256}); + | ^~~~~~ +%Error-UNSUPPORTED: t/t_tagged_union.v:242:13: Unsupported: tagged union + 242 | instr = tagged Jmp (tagged JmpC '{cc:2'd3, addr:10'd100}); + | ^~~~~~ +%Error-UNSUPPORTED: t/t_tagged_union.v:242:25: Unsupported: tagged union + 242 | instr = tagged Jmp (tagged JmpC '{cc:2'd3, addr:10'd100}); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:243:11: Unsupported: tagged union - 243 | cht = tagged Invalid; - | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:244:11: Unsupported: tagged union - 244 | cht = tagged Handle (null); - | ^~~~~~ %Error-UNSUPPORTED: t/t_tagged_union.v:248:11: Unsupported: tagged union - 248 | clt = tagged Invalid; + 248 | cht = tagged Invalid; | ^~~~~~ %Error-UNSUPPORTED: t/t_tagged_union.v:249:11: Unsupported: tagged union - 249 | clt = tagged Obj (obj); + 249 | cht = tagged Handle (null); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:253:10: Unsupported: tagged union - 253 | rt = tagged Invalid; +%Error-UNSUPPORTED: t/t_tagged_union.v:254:11: Unsupported: tagged union + 254 | clt = tagged Invalid; + | ^~~~~~ +%Error-UNSUPPORTED: t/t_tagged_union.v:255:11: Unsupported: tagged union + 255 | clt = tagged Obj (obj); + | ^~~~~~ +%Error-UNSUPPORTED: t/t_tagged_union.v:259:10: Unsupported: tagged union + 259 | rt = tagged Invalid; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:254:10: Unsupported: tagged union - 254 | rt = tagged RealVal (3.14159); +%Error-UNSUPPORTED: t/t_tagged_union.v:260:10: Unsupported: tagged union + 260 | rt = tagged RealVal (3.14159); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:258:10: Unsupported: tagged union - 258 | rt = tagged ShortRealVal (2.5); +%Error-UNSUPPORTED: t/t_tagged_union.v:264:10: Unsupported: tagged union + 264 | rt = tagged ShortRealVal (2.5); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:262:10: Unsupported: tagged union - 262 | st = tagged Invalid; +%Error-UNSUPPORTED: t/t_tagged_union.v:268:10: Unsupported: tagged union + 268 | st = tagged Invalid; | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:263:10: Unsupported: tagged union - 263 | st = tagged StrVal ("hello"); +%Error-UNSUPPORTED: t/t_tagged_union.v:269:10: Unsupported: tagged union + 269 | st = tagged StrVal ("hello"); | ^~~~~~ -%Error-UNSUPPORTED: t/t_tagged_union.v:267:10: Unsupported: tagged union - 267 | et = tagged Invalid; +%Error-UNSUPPORTED: t/t_tagged_union.v:273:10: Unsupported: tagged union + 273 | et = tagged Invalid; | ^~~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_tagged_union.v b/test_regress/t/t_tagged_union.v index 59642f503..4ce7fe866 100644 --- a/test_regress/t/t_tagged_union.v +++ b/test_regress/t/t_tagged_union.v @@ -75,10 +75,12 @@ module t; } Instr; // Tagged union with chandle member +`ifndef QUESTA typedef union tagged { void Invalid; chandle Handle; } ChandleType; +`endif // Tagged union with class reference member typedef union tagged { @@ -122,7 +124,9 @@ module t; MultiType mt; ArrayType at; Instr instr; +`ifndef QUESTA ChandleType cht; +`endif ClassType clt; TestClass obj; RealType rt; @@ -239,9 +243,11 @@ module t; `checkh(instr.Jmp.JmpC.cc, 2'd3); `checkh(instr.Jmp.JmpC.addr, 10'd100); +`ifndef QUESTA // Test 13: Chandle member cht = tagged Invalid; cht = tagged Handle (null); +`endif // Test 14: Class reference member obj = new(42); diff --git a/test_regress/t/t_vpi_force.v b/test_regress/t/t_vpi_force.v index ae4913926..fcfa1b5fb 100644 --- a/test_regress/t/t_vpi_force.v +++ b/test_regress/t/t_vpi_force.v @@ -175,8 +175,7 @@ typedef enum byte { // - Continuous assignments do not work // - vpi_handle_by_multi_index is not implemented // - vpi_handle_by_name and vpi_handle_by_index fail with negative indices - // Hence, these signals are excluded from testing with Icarus. Recommend - // Xcelium for cross-checking results. + // Hence, these signals are excluded from testing with Icarus. `ifndef IVERILOG // Force the entire packed array (no partial forcing possible, because // partial indexing only works for bits, not dimension slices) @@ -2422,10 +2421,8 @@ $dumpfile(`STRINGIFY(`TEST_DUMPFILE)); svReleaseValues(); #8 svCheckValuesReleased(); - // Icarus does not support forcing single bits through VPI -`ifndef IVERILOG - // Xcelium supports forcing single bits through VPI, but crashes on some signals -`ifndef XRUN +`ifndef IVERILOG // Does not support forcing single bits through VPI +`ifndef XRUN // Supports forcing single bits through VPI, but crashes on some signals // Force single bit through VPI, release through VPI if (`verbose) $display("*** Forcing single bit through VPI, releasing through VPI ***"); From f82f59a0246f7e62f2f3a237446fdf10788cd09f Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 3 Jul 2026 13:01:05 -0400 Subject: [PATCH 29/29] Commentary: Changes update --- Changes | 8 ++++++++ docs/spelling.txt | 3 +++ .../t/{t_clang_overload.py => t_class_cpp_overload.py} | 0 .../t/{t_clang_overload.v => t_class_cpp_overload.v} | 0 test_regress/t/t_unique0_case.v | 3 +-- 5 files changed, 12 insertions(+), 2 deletions(-) rename test_regress/t/{t_clang_overload.py => t_class_cpp_overload.py} (100%) rename test_regress/t/{t_clang_overload.v => t_class_cpp_overload.v} (100%) diff --git a/Changes b/Changes index 3e4174b62..9ae1a40ee 100644 --- a/Changes +++ b/Changes @@ -15,6 +15,14 @@ Verilator 5.051 devel **Other:** +* Add comments as a branch description in coverage .info files (#7843). [Eryk Szpotanski] +* Optimize random initialization. [Geza Lore, Testorrent USA, Inc.] +* Fix DFG misoptimizing bound checks (#7755). [Jakub Michalski] +* Fix unique0 case side effects (#7787). [Pawel Klopotek] +* Fix cleaning purity cache after assertions. [Geza Lore, Testorrent USA, Inc.] +* Fix clang++ ambiguous overload of '==' operator (#7863). [Pawel Kojma, Antmicro Ltd.] +* Fix heap-use-after-free in `VlRNG::VlRNG()` (#7865). [Dragon-Git] + Verilator 5.050 2026-07-01 ========================== diff --git a/docs/spelling.txt b/docs/spelling.txt index a9d91f52b..f99491317 100644 --- a/docs/spelling.txt +++ b/docs/spelling.txt @@ -477,6 +477,7 @@ Syms Synopsys SystemC SystemVerilog +Szpotanski Takatsukasa Tambe Tarik @@ -537,6 +538,7 @@ Verilog Vighnesh Viktor Vilp +VlRNG VlWide Vlip Vm @@ -947,6 +949,7 @@ misconnected misconversion misdetecting misoptimized +misoptimizing missized mk mno diff --git a/test_regress/t/t_clang_overload.py b/test_regress/t/t_class_cpp_overload.py similarity index 100% rename from test_regress/t/t_clang_overload.py rename to test_regress/t/t_class_cpp_overload.py diff --git a/test_regress/t/t_clang_overload.v b/test_regress/t/t_class_cpp_overload.v similarity index 100% rename from test_regress/t/t_clang_overload.v rename to test_regress/t/t_class_cpp_overload.v diff --git a/test_regress/t/t_unique0_case.v b/test_regress/t/t_unique0_case.v index 54cedb901..ed3f92535 100644 --- a/test_regress/t/t_unique0_case.v +++ b/test_regress/t/t_unique0_case.v @@ -7,7 +7,6 @@ // verilog_format: off `define stop $stop `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); -`define checkp(gotv,expv_s) do begin string gotv_s; gotv_s = $sformatf("%p", gotv); if ((gotv_s) != (expv_s)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv_s), (expv_s)); `stop; end end while(0); // verilog_format: on module t; @@ -18,7 +17,7 @@ module t; y = 0; x = 0; z = 0; - unique0 case(increment_x()) + unique0 case (increment_x()) 1: begin y = 1; end