diff --git a/src/V3Sched.cpp b/src/V3Sched.cpp index d7abb1eec..476d9bfa5 100644 --- a/src/V3Sched.cpp +++ b/src/V3Sched.cpp @@ -746,7 +746,9 @@ const TriggerKit createTriggers(AstNetlist* netlistp, AstCFunc* const initFuncp, ss << "@("; V3EmitV::verilogForTree(senItemp, ss); ss << ")"; - addDebug(triggerNumber, VString::quoteBackslash(ss.str())); + std::string desc = VString::quoteBackslash(ss.str()); + desc = VString::replaceSubstr(desc, "\n", "\\n"); + addDebug(triggerNumber, desc); // ++triggerNumber; diff --git a/src/V3Task.cpp b/src/V3Task.cpp index 10f277e3f..a3d815973 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -1458,8 +1458,9 @@ class TaskVisitor final : public VNVisitor { UASSERT_OBJ(!m_insStmtp, nodep, "Didn't finish out last statement"); } void visit(AstNodeFTaskRef* nodep) override { - if (m_inSensesp) { - nodep->v3warn(E_UNSUPPORTED, "Unsupported: function calls in sensitivity lists"); + if (m_inSensesp && !nodep->isPure()) { + nodep->v3warn(E_UNSUPPORTED, + "Unsupported: Impure function calls in sensitivity lists"); nodep->taskp(nullptr); // So V3Broken doesn't complain return; } diff --git a/test_regress/t/t_event_control_expr.v b/test_regress/t/t_event_control_expr.v index d544b419a..de3562a6a 100644 --- a/test_regress/t/t_event_control_expr.v +++ b/test_regress/t/t_event_control_expr.v @@ -50,10 +50,8 @@ endmodule `EXPR_TEST(queue, 0, (input int q[$]), q[0]) `EXPR_TEST(queue_mul, 0, (input int q[$], int i), q[0]*i) -`ifdef UNSUP function int id(int x); return x; endfunction `EXPR_TEST(func, 0, (input int cyc), id(cyc)) -`endif //======================================================================== // Class tests (special case as V3Width doesn't always properly handle @@ -78,27 +76,25 @@ endmodule `CLASS_TEST(class, obj.k) -`ifdef UNSUP `CLASS_TEST(method, obj.get_k()) `endif -`endif //======================================================================== // $c test has to be written out explicitly as the STRINGIFY macro can't handle it // module t_cstmt; logic last = 0; - always @($c("vlSelf->clk")) begin - if ($time > 0 && logic'($c("vlSelf->clk")) == last) $stop; - last <= logic'($c("vlSelf->clk")); + always @($c("vlSymsp->TOP.clk")) begin + if ($time > 0 && logic'($c("vlSymsp->TOP.clk")) == last) $stop; + last <= logic'($c("vlSymsp->TOP.clk")); end - always @(posedge $c("vlSelf->clk")) begin - `WRITE_VERBOSE(("[%0t] cstmt [posedge] $c(\"vlSelf->clk\")=%0b, last=%b\n", $time, $c("vlSelf->clk"), last)); - if ($time > 0 && (~logic'($c("vlSelf->clk")) || last)) $stop; + always @(posedge $c("vlSymsp->TOP.clk")) begin + `WRITE_VERBOSE(("[%0t] cstmt [posedge] $c(\"vlSymsp->TOP.clk\")=%0b, last=%b\n", $time, $c("vlSymsp->TOP.clk"), last)); + if ($time > 0 && (~logic'($c("vlSymsp->TOP.clk")) || last)) $stop; end - always @(negedge $c("vlSelf->clk")) begin - `WRITE_VERBOSE(("[%0t] cstmt [negedge] $c(\"vlSelf->clk\")=%0b, last=%b\n", $time, $c("vlSelf->clk"), last)); - if ($time > 0 && (logic'($c("vlSelf->clk")) || !last)) $stop; + always @(negedge $c("vlSymsp->TOP.clk")) begin + `WRITE_VERBOSE(("[%0t] cstmt [negedge] $c(\"vlSymsp->TOP.clk\")=%0b, last=%b\n", $time, $c("vlSymsp->TOP.clk"), last)); + if ($time > 0 && (logic'($c("vlSymsp->TOP.clk")) || !last)) $stop; end endmodule @@ -129,17 +125,13 @@ module t(/*AUTOARG*/ t_queue u_queue(.*); t_queue_mul u_queue_mul(.*); -`ifdef UNSUP t_func u_func(.*); -`endif int k; assign k = i + j; `ifndef NO_CLASS t_class u_class(.*); -`ifdef UNSUP t_method u_method(.*); -`endif `endif t_cstmt u_cstmt(); diff --git a/test_regress/t/t_event_control_expr_noinl.py b/test_regress/t/t_event_control_expr_noinl.py new file mode 100755 index 000000000..c96b715f6 --- /dev/null +++ b/test_regress/t/t_event_control_expr_noinl.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator') +test.top_filename = 't_event_control_expr.v' + +test.compile( + # do not test classes for multithreaded, as V3InstrCount doesn't handle MemberSel + verilator_flags2=(['-fno-inline'] + ['-DNO_CLASS'] if test.vltmt else [])) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_event_control_expr_unsup.out b/test_regress/t/t_event_control_expr_unsup.out index 8b6cc69ae..310e7c6ec 100644 --- a/test_regress/t/t_event_control_expr_unsup.out +++ b/test_regress/t/t_event_control_expr_unsup.out @@ -1,9 +1,5 @@ -%Error-UNSUPPORTED: t/t_event_control_expr.v:55:13: Unsupported: function calls in sensitivity lists - 55 | always @(id(cyc)) begin - | ^~ +%Error-UNSUPPORTED: t/t_event_control_expr_unsup.v:15:21: Unsupported: Impure function calls in sensitivity lists + 15 | always @(posedge foo()); + | ^~~ ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest -%Error-UNSUPPORTED: t/t_event_control_expr.v:82:17: Unsupported: function calls in sensitivity lists - : ... note: In instance 't.u_method' - 82 | always @(obj.get_k()) begin - | ^~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_event_control_expr_unsup.py b/test_regress/t/t_event_control_expr_unsup.py index dbee9633e..685bf2355 100755 --- a/test_regress/t/t_event_control_expr_unsup.py +++ b/test_regress/t/t_event_control_expr_unsup.py @@ -10,8 +10,7 @@ import vltest_bootstrap test.scenarios('vlt') # no vltmt, as AstMemberSel is unhandled in V3InstrCount -test.top_filename = "t_event_control_expr.v" -test.lint(verilator_flags2=['-DUNSUP'], fails=True, expect_filename=test.golden_filename) +test.lint(fails=True, expect_filename=test.golden_filename) test.passes() diff --git a/test_regress/t/t_event_control_expr_unsup.v b/test_regress/t/t_event_control_expr_unsup.v new file mode 100644 index 000000000..4cbfe594c --- /dev/null +++ b/test_regress/t/t_event_control_expr_unsup.v @@ -0,0 +1,17 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +module t; + int x; + + function bit foo; + x += 1; + return bit'(x % 2); + endfunction + + always @(posedge foo()); + +endmodule