diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index 6502a8838..5d2ac8b3c 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -46,6 +46,7 @@ protected: public: ASTGEN_MEMBERS_AstNodeBlock; + bool maybePointedTo() const override VL_MT_SAFE { return true; } void dump(std::ostream& str) const override; void dumpJson(std::ostream& str) const override; string name() const override VL_MT_STABLE { return m_name; } // * = Block name @@ -3096,14 +3097,18 @@ public: bool isCycleDelay() const { return m_isCycle; } }; class AstDisable final : public AstNodeStmt { - string m_name; // Name of block + // @astgen op1 := targetRefp : Optional[AstNodeExpr] // Reference to link in V3LinkDot + // @astgen ptr := m_targetp : Optional[AstNode] // Task or block after V3LinkDot public: - AstDisable(FileLine* fl, const string& name) - : ASTGEN_SUPER_Disable(fl) - , m_name{name} {} + AstDisable(FileLine* fl, AstNodeExpr* targetRefp) + : ASTGEN_SUPER_Disable(fl) { + this->targetRefp(targetRefp); + } ASTGEN_MEMBERS_AstDisable; - string name() const override VL_MT_STABLE { return m_name; } // * = Block name - void name(const string& flag) override { m_name = flag; } + const char* broken() const override; + void dump(std::ostream& str) const override; + void targetp(AstNode* nodep) { m_targetp = nodep; } + AstNode* targetp() const { return m_targetp; } bool isBrancher() const override { return true; // SPECIAL: We don't process code after breaks } diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 5c073487b..acdbd9256 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -3177,6 +3177,20 @@ void AstDelay::dumpJson(std::ostream& str) const { dumpJsonBoolFunc(str, isCycleDelay); dumpJsonGen(str); } + +const char* AstDisable::broken() const { + BROKEN_RTN((m_targetp && targetRefp()) || ((!m_targetp && !targetRefp()))); + return nullptr; +} +void AstDisable::dump(std::ostream& str) const { + this->AstNodeStmt::dump(str); + str << " -> "; + if (targetp()) { + targetp()->dump(str); + } else { + str << "UNLINKED"; + } +} const char* AstAnd::widthMismatch() const VL_MT_STABLE { BROKEN_RTN(lhsp()->widthMin() != rhsp()->widthMin()); BROKEN_RTN(lhsp()->widthMin() != widthMin()); diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 313307919..85da123c9 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -2365,6 +2365,7 @@ class LinkDotResolveVisitor final : public VNVisitor { bool m_unresolvedClass; // Unresolved class reference, needs help from V3Param bool m_genBlk; // Contains gen block reference AstNode* m_unlinkedScopep; // Unresolved scope, needs corresponding VarXRef + AstDisable* m_disablep; // Disable statement under which the reference is bool m_dotErr; // Error found in dotted resolution, ignore upwards string m_dotText; // String of dotted names found in below parseref DotStates() { init(nullptr); } @@ -2380,6 +2381,7 @@ class LinkDotResolveVisitor final : public VNVisitor { m_unresolvedClass = false; m_genBlk = false; m_unlinkedScopep = nullptr; + m_disablep = nullptr; } string ascii() const { static const char* const names[] @@ -3084,7 +3086,11 @@ class LinkDotResolveVisitor final : public VNVisitor { bool allowVar = false; bool allowFTask = false; bool staticAccess = false; - if (m_ds.m_dotPos == DP_PACKAGE) { + if (m_ds.m_disablep) { + allowScope = true; + allowFTask = true; + expectWhat = "block/task"; + } else if (m_ds.m_dotPos == DP_PACKAGE) { // {package-or-class}::{a} AstNodeModule* classOrPackagep = nullptr; expectWhat = "scope/variable/func"; @@ -3185,7 +3191,7 @@ class LinkDotResolveVisitor final : public VNVisitor { } } if (!foundp) { - } else if (VN_IS(foundp->nodep(), Cell) || VN_IS(foundp->nodep(), Begin) + } else if (VN_IS(foundp->nodep(), Cell) || VN_IS(foundp->nodep(), NodeBlock) || VN_IS(foundp->nodep(), Netlist) // for $root || VN_IS(foundp->nodep(), Module)) { // if top if (allowScope) { @@ -3193,8 +3199,20 @@ class LinkDotResolveVisitor final : public VNVisitor { m_ds.m_dotText = VString::dot(m_ds.m_dotText, ".", nodep->name()); m_ds.m_dotSymp = foundp; m_ds.m_dotPos = DP_SCOPE; + if (m_ds.m_disablep && VN_IS(foundp->nodep(), NodeBlock)) { + // Possibly it is not the final link. If we are under dot and not in its + // last component, `targetp()` field will be overwritten by next components + m_ds.m_disablep->targetp(foundp->nodep()); + } if (const AstBegin* const beginp = VN_CAST(foundp->nodep(), Begin)) { - if (beginp->generate()) m_ds.m_genBlk = true; + if (beginp->generate()) { + m_ds.m_genBlk = true; + if (m_ds.m_disablep) { + m_ds.m_disablep->v3warn( + E_UNSUPPORTED, + "Unsupported: Generate block referenced by disable"); + } + } } // Upper AstDot visitor will handle it from here } else if (VN_IS(foundp->nodep(), Cell) && allowVar) { @@ -3438,7 +3456,8 @@ class LinkDotResolveVisitor final : public VNVisitor { m_ds.m_dotPos = DP_MEMBER; } else { // Cells/interfaces can't be implicit - const bool checkImplicit = (!m_ds.m_dotp && m_ds.m_dotText == "" && !foundp); + const bool checkImplicit + = (!m_ds.m_dotp && m_ds.m_dotText == "" && !m_ds.m_disablep && !foundp); const bool err = !(checkImplicit && m_statep->implicitOk(m_modp, nodep->name())); if (err) { @@ -3845,7 +3864,8 @@ class LinkDotResolveVisitor final : public VNVisitor { // HERE function() . method_called_on_function_return_value() m_ds.m_dotPos = DP_MEMBER; m_ds.m_dotText = ""; - } else { + } else if (!m_ds.m_disablep) { + // visit(AstDisable*) setup the dot handling checkNoDot(nodep); } if (nodep->classOrPackagep() && nodep->taskp()) { @@ -4510,6 +4530,30 @@ class LinkDotResolveVisitor final : public VNVisitor { } VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); } + void visit(AstDisable* nodep) override { + LINKDOT_VISIT_START(); + checkNoDot(nodep); + VL_RESTORER(m_ds); + m_ds.init(m_curSymp); + m_ds.m_dotPos = DP_FIRST; + m_ds.m_disablep = nodep; + iterateChildren(nodep); + if (nodep->targetRefp()) { + if (AstTaskRef* const taskRefp = VN_CAST(nodep->targetRefp(), TaskRef)) { + nodep->targetp(taskRefp->taskp()); + } else if (!VN_IS(nodep->targetRefp(), ParseRef)) { + // If it is a ParseRef, either it couldn't be linked or it is linked to a block + nodep->v3warn(E_UNSUPPORTED, "Node of type " + << nodep->targetRefp()->prettyTypeName() + << " referenced by disable"); + pushDeletep(nodep->unlinkFrBack()); + } + if (nodep->targetp()) { + // If the target is already linked, there is no need to store reference as child + VL_DO_DANGLING(nodep->targetRefp()->unlinkFrBack()->deleteTree(), nodep); + } + } + } void visit(AstPackageImport* nodep) override { // No longer needed LINKDOT_VISIT_START(); diff --git a/src/V3LinkJump.cpp b/src/V3LinkJump.cpp index a97d11f58..3cfb7afab 100644 --- a/src/V3LinkJump.cpp +++ b/src/V3LinkJump.cpp @@ -337,33 +337,41 @@ class LinkJumpVisitor final : public VNVisitor { } void visit(AstDisable* nodep) override { UINFO(8, " DISABLE " << nodep); - iterateChildren(nodep); - AstNodeBlock* blockp = nullptr; - for (AstNodeBlock* const stackp : vlstd::reverse_view(m_blockStack)) { - UINFO(9, " UNDERBLK " << stackp); - if (stackp->name() == nodep->name()) { - blockp = stackp; - break; + AstNode* const targetp = nodep->targetp(); + UASSERT_OBJ(targetp, nodep, "Unlinked disable statement"); + if (VN_IS(targetp, Task)) { + nodep->v3warn(E_UNSUPPORTED, "Unsupported: disabling task by name"); + } else if (VN_IS(targetp, Fork)) { + nodep->v3warn(E_UNSUPPORTED, "Unsupported: disabling fork by name"); + } else if (AstBegin* const beginp = VN_CAST(targetp, Begin)) { + const std::string targetName = beginp->name(); + bool aboveBlock = false; + for (AstNodeBlock* const stackp : vlstd::reverse_view(m_blockStack)) { + UINFO(9, " UNDERBLK " << stackp); + if (stackp->name() == targetName) { + aboveBlock = true; + break; + } } - } - // if (debug() >= 9) { UINFO(0, "\n"); blockp->dumpTree("- labeli: "); } - if (!blockp) { - nodep->v3warn(E_UNSUPPORTED, - "disable isn't underneath a begin with name: " << nodep->prettyNameQ()); - } else if (AstBegin* const beginp = VN_CAST(blockp, Begin)) { - if (beginp->user3()) { - nodep->v3warn(E_UNSUPPORTED, "Unsupported: disabling block that contains a fork"); + if (aboveBlock) { + if (beginp->user3()) { + nodep->v3warn(E_UNSUPPORTED, + "Unsupported: disabling block that contains a fork"); + } else { + // Jump to the end of the named block + AstJumpLabel* const labelp = findAddLabel(beginp, false); + nodep->addNextHere(new AstJumpGo{nodep->fileline(), labelp}); + } } else { - // Jump to the end of the named block - AstJumpLabel* const labelp = findAddLabel(beginp, false); - nodep->addNextHere(new AstJumpGo{nodep->fileline(), labelp}); + nodep->v3warn(E_UNSUPPORTED, "disable isn't underneath a begin with name: '" + << targetName << "'"); } } else { - nodep->v3warn(E_UNSUPPORTED, "Unsupported: disabling fork by name"); + nodep->v3fatalSrc("Disable linked with node of unhandled type " + << targetp->prettyTypeName()); } nodep->unlinkFrBack(); VL_DO_DANGLING(pushDeletep(nodep), nodep); - // if (debug() >= 9) { UINFO(0, "\n"); beginp->dumpTree("- labelo: "); } } void visit(AstVarRef* nodep) override { if (m_loopInc && nodep->varp()) nodep->varp()->usedLoopIdx(true); diff --git a/src/verilog.y b/src/verilog.y index dfdcf3e80..f82f79ed3 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -3753,10 +3753,8 @@ statement_item: // IEEE: statement_item // // // IEEE: disable_statement | yDISABLE yFORK ';' { $$ = new AstDisableFork{$1}; } - | yDISABLE idAny/*UNSUP: hierarchical_identifier-task_or_block*/ ';' - { $$ = new AstDisable{$1, *$2}; } - | yDISABLE idAny '.' idDottedSel ';' - { $$ = nullptr; BBUNSUP($4, "Unsupported: disable with '.'"); } + | yDISABLE idDottedSel ';' + { $$ = new AstDisable{$1, $2}; } // // IEEE: event_trigger | yP_MINUSGT expr ';' { $$ = new AstFireEvent{$1, $2, false}; } diff --git a/test_regress/t/t_disable_bad.out b/test_regress/t/t_disable_bad.out new file mode 100644 index 000000000..35f743a9b --- /dev/null +++ b/test_regress/t/t_disable_bad.out @@ -0,0 +1,8 @@ +%Error: t/t_disable_bad.v:9:15: Can't find definition of block/task: 'abcd' + 9 | disable abcd; + | ^~~~ + ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. +%Error: Internal Error: t/t_disable_bad.v:9:7: ../V3LinkJump.cpp:#: Unlinked disable statement + 9 | disable abcd; + | ^~~~~~~ + ... This fatal error may be caused by the earlier error(s); resolve those first. diff --git a/test_regress/t/t_disable_bad.py b/test_regress/t/t_disable_bad.py new file mode 100755 index 000000000..31228c9a7 --- /dev/null +++ b/test_regress/t/t_disable_bad.py @@ -0,0 +1,16 @@ +#!/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('linter') + +test.lint(fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_disable_bad.v b/test_regress/t/t_disable_bad.v new file mode 100644 index 000000000..b056b1b7f --- /dev/null +++ b/test_regress/t/t_disable_bad.v @@ -0,0 +1,11 @@ +// 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; + initial begin + disable abcd; + end +endmodule: t diff --git a/test_regress/t/t_disable_empty.out b/test_regress/t/t_disable_empty.out new file mode 100644 index 000000000..48d8fd58b --- /dev/null +++ b/test_regress/t/t_disable_empty.out @@ -0,0 +1,5 @@ +%Error-UNSUPPORTED: t/t_disable_empty.v:12:7: disable isn't underneath a begin with name: 'block' + 12 | disable block; + | ^~~~~~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error: Exiting due to diff --git a/test_regress/t/t_disable_empty.py b/test_regress/t/t_disable_empty.py new file mode 100755 index 000000000..44c75cc0f --- /dev/null +++ b/test_regress/t/t_disable_empty.py @@ -0,0 +1,16 @@ +#!/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.lint(verilator_flags2=['--timing'], fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_disable_empty.v b/test_regress/t/t_disable_empty.v new file mode 100644 index 000000000..aac889913 --- /dev/null +++ b/test_regress/t/t_disable_empty.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 Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t(/*AUTOARG*/); + + initial begin + if (0) begin : block + end + disable block; + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_disable_func_bad.out b/test_regress/t/t_disable_func_bad.out new file mode 100644 index 000000000..0b3a8de88 --- /dev/null +++ b/test_regress/t/t_disable_func_bad.out @@ -0,0 +1,5 @@ +%Error-UNSUPPORTED: t/t_disable_func_bad.v:19:13: Node of type FUNCREF 'increment_x' referenced by disable + 19 | #1 disable increment_x; + | ^~~~~~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error: Exiting due to diff --git a/test_regress/t/t_disable_func_bad.py b/test_regress/t/t_disable_func_bad.py new file mode 100755 index 000000000..cf9cba66e --- /dev/null +++ b/test_regress/t/t_disable_func_bad.py @@ -0,0 +1,18 @@ +#!/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('linter') + +test.lint(verilator_flags2=['--lint-only --timing'], + fails=True, + expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_disable_func_bad.v b/test_regress/t/t_disable_func_bad.v new file mode 100644 index 000000000..587987cd0 --- /dev/null +++ b/test_regress/t/t_disable_func_bad.v @@ -0,0 +1,23 @@ +// 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 + +int x = 0; + +function int increment_x; + x++; + return x; +endfunction + +module t(/*AUTOARG*/); + + initial begin + fork + increment_x(); + #1 disable increment_x; + join + end + +endmodule diff --git a/test_regress/t/t_disable_genfor2.py b/test_regress/t/t_disable_genfor2.py new file mode 100755 index 000000000..a4e75e7ad --- /dev/null +++ b/test_regress/t/t_disable_genfor2.py @@ -0,0 +1,18 @@ +#!/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.compile(verilator_flags2=["--exe --main --timing"]) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_disable_genfor2.v b/test_regress/t/t_disable_genfor2.v new file mode 100644 index 000000000..eb9382f99 --- /dev/null +++ b/test_regress/t/t_disable_genfor2.v @@ -0,0 +1,24 @@ +// 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 ( /*AUTOARG*/); + for (genvar j = 0; j < 3; j++) begin : genblk + initial begin : init + int i; + begin : named + for (i = 0; i < 10; ++i) begin : loop + if (i == 5) disable named; + end + end + if (i != 5) $stop; + end + end + initial begin + #1; + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_disable_genfor_unsup.out b/test_regress/t/t_disable_genfor_unsup.out new file mode 100644 index 000000000..a1e2054c9 --- /dev/null +++ b/test_regress/t/t_disable_genfor_unsup.out @@ -0,0 +1,8 @@ +%Error-UNSUPPORTED: t/t_disable_genfor_unsup.v:13:23: Unsupported: Generate block referenced by disable + 13 | if (i == 5) disable t.genblk[0].init.named; + | ^~~~~~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error-UNSUPPORTED: t/t_disable_genfor_unsup.v:13:23: Node of type CELLREF referenced by disable + 13 | if (i == 5) disable t.genblk[0].init.named; + | ^~~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_disable_genfor_unsup.py b/test_regress/t/t_disable_genfor_unsup.py new file mode 100755 index 000000000..44c75cc0f --- /dev/null +++ b/test_regress/t/t_disable_genfor_unsup.py @@ -0,0 +1,16 @@ +#!/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.lint(verilator_flags2=['--timing'], fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_disable_genfor_unsup.v b/test_regress/t/t_disable_genfor_unsup.v new file mode 100644 index 000000000..0f8e05c16 --- /dev/null +++ b/test_regress/t/t_disable_genfor_unsup.v @@ -0,0 +1,25 @@ +// 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 ( /*AUTOARG*/); + for (genvar j = 0; j < 3; j++) begin : genblk + initial begin : init + int i; + begin : named + for (i = 0; i < 10; ++i) begin : loop + if (i == 5) disable t.genblk[0].init.named; + end + end + if (j == 0 && i != 5) $stop; + if (j != 0 && i != 10) $stop; + end + end + initial begin + #1; + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_disable_task_unsup.out b/test_regress/t/t_disable_task_unsup.out new file mode 100644 index 000000000..e5628d22a --- /dev/null +++ b/test_regress/t/t_disable_task_unsup.out @@ -0,0 +1,5 @@ +%Error-UNSUPPORTED: t/t_disable_task_unsup.v:20:13: Unsupported: disabling task by name + 20 | #1 disable increment_x; + | ^~~~~~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error: Exiting due to diff --git a/test_regress/t/t_disable_task_unsup.py b/test_regress/t/t_disable_task_unsup.py new file mode 100755 index 000000000..44c75cc0f --- /dev/null +++ b/test_regress/t/t_disable_task_unsup.py @@ -0,0 +1,16 @@ +#!/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.lint(verilator_flags2=['--timing'], fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_disable_task_unsup.v b/test_regress/t/t_disable_task_unsup.v new file mode 100644 index 000000000..0ab943842 --- /dev/null +++ b/test_regress/t/t_disable_task_unsup.v @@ -0,0 +1,27 @@ +// 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 + +int x = 0; + +task increment_x; + x++; + #2; + x++; +endtask + +module t(/*AUTOARG*/); + + initial begin + fork + increment_x(); + #1 disable increment_x; + join + if (x != 1) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_dump.v b/test_regress/t/t_dump.v index 4f706d700..dca21e9d8 100644 --- a/test_regress/t/t_dump.v +++ b/test_regress/t/t_dump.v @@ -88,5 +88,8 @@ module Test(/*AUTOARG*/ assert(0); $asserton; $assertcontrol(3, 8); + begin : blk + disable blk; + end end endmodule diff --git a/test_regress/t/t_dump_json.out b/test_regress/t/t_dump_json.out index fa903003a..36d58e850 100644 --- a/test_regress/t/t_dump_json.out +++ b/test_regress/t/t_dump_json.out @@ -510,22 +510,29 @@ ], "assertTypesp": [ {"type":"CONST","name":"?32?sh8","addr":"(GI)","loc":"e,90:25,90:26","dtypep":"(JF)"} - ],"directiveTypesp": []} + ],"directiveTypesp": []}, + {"type":"BEGIN","name":"blk","addr":"(HI)","loc":"e,91:15,91:18","generate":false,"genfor":false,"implied":false,"needProcess":false,"unnamed":false,"genforp": [], + "stmtsp": [ + {"type":"DISABLE","name":"","addr":"(II)","loc":"e,92:10,92:17", + "targetRefp": [ + {"type":"PARSEREF","name":"blk","addr":"(JI)","loc":"e,92:18,92:21","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + ]} + ]} ]} ]} ]} ]} ],"filesp": [], "miscsp": [ - {"type":"TYPETABLE","name":"","addr":"(C)","loc":"a,0:0,0:0","constraintRefp":"UNLINKED","emptyQueuep":"UNLINKED","queueIndexp":"UNLINKED","streamp":"UNLINKED","voidp":"(HI)", + {"type":"TYPETABLE","name":"","addr":"(C)","loc":"a,0:0,0:0","constraintRefp":"UNLINKED","emptyQueuep":"UNLINKED","queueIndexp":"UNLINKED","streamp":"UNLINKED","voidp":"(KI)", "typesp": [ - {"type":"BASICDTYPE","name":"integer","addr":"(II)","loc":"d,34:27,34:28","dtypep":"(II)","keyword":"integer","range":"31:0","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"integer","addr":"(LI)","loc":"d,34:27,34:28","dtypep":"(LI)","keyword":"integer","range":"31:0","generic":true,"rangep": []}, {"type":"BASICDTYPE","name":"logic","addr":"(L)","loc":"d,36:32,36:33","dtypep":"(L)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, {"type":"BASICDTYPE","name":"logic","addr":"(UE)","loc":"d,53:22,53:24","dtypep":"(UE)","keyword":"logic","generic":true,"rangep": []}, - {"type":"VOIDDTYPE","name":"","addr":"(HI)","loc":"d,54:21,54:30","dtypep":"(HI)","generic":false}, + {"type":"VOIDDTYPE","name":"","addr":"(KI)","loc":"d,54:21,54:30","dtypep":"(KI)","generic":false}, {"type":"BASICDTYPE","name":"logic","addr":"(QD)","loc":"d,128:22,128:23","dtypep":"(QD)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(JI)","loc":"d,130:22,130:23","dtypep":"(JI)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(KI)","loc":"d,165:17,165:56","dtypep":"(KI)","keyword":"logic","range":"295:0","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(MI)","loc":"d,130:22,130:23","dtypep":"(MI)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(NI)","loc":"d,165:17,165:56","dtypep":"(NI)","keyword":"logic","range":"295:0","generic":true,"rangep": []}, {"type":"BASICDTYPE","name":"string","addr":"(BG)","loc":"d,165:10,165:16","dtypep":"(BG)","keyword":"string","generic":true,"rangep": []}, {"type":"BASICDTYPE","name":"logic","addr":"(Q)","loc":"e,14:9,14:11","dtypep":"(Q)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, {"type":"BASICDTYPE","name":"logic","addr":"(BB)","loc":"e,18:10,18:12","dtypep":"(BB)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, @@ -540,9 +547,9 @@ ]}, {"type":"CONSTPOOL","name":"","addr":"(D)","loc":"a,0:0,0:0", "modulep": [ - {"type":"MODULE","name":"@CONST-POOL@","addr":"(LI)","loc":"a,0:0,0:0","isChecker":false,"isProgram":false,"origName":"@CONST-POOL@","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"NONE","inlinesp": [], + {"type":"MODULE","name":"@CONST-POOL@","addr":"(OI)","loc":"a,0:0,0:0","isChecker":false,"isProgram":false,"origName":"@CONST-POOL@","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"NONE","inlinesp": [], "stmtsp": [ - {"type":"SCOPE","name":"@CONST-POOL@","addr":"(MI)","loc":"a,0:0,0:0","aboveScopep":"UNLINKED","aboveCellp":"UNLINKED","modp":"(LI)","varsp": [],"blocksp": [],"inlinesp": []} + {"type":"SCOPE","name":"@CONST-POOL@","addr":"(PI)","loc":"a,0:0,0:0","aboveScopep":"UNLINKED","aboveCellp":"UNLINKED","modp":"(OI)","varsp": [],"blocksp": [],"inlinesp": []} ]} ]} ]} diff --git a/test_regress/t/t_for_disable_dot.out b/test_regress/t/t_for_disable_dot.out deleted file mode 100644 index fe6edd7f7..000000000 --- a/test_regress/t/t_for_disable_dot.out +++ /dev/null @@ -1,5 +0,0 @@ -%Error-UNSUPPORTED: t/t_for_disable_dot.v:14:35: Unsupported: disable with '.' - 14 | if (i == 5) disable t.named; - | ^~~~~ - ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest -%Error: Exiting due to diff --git a/test_regress/t/t_for_disable_dot.py b/test_regress/t/t_for_disable_dot.py index 30c3d4f77..d4f986441 100755 --- a/test_regress/t/t_for_disable_dot.py +++ b/test_regress/t/t_for_disable_dot.py @@ -9,8 +9,10 @@ import vltest_bootstrap -test.scenarios('linter') +test.scenarios('simulator') -test.lint(fails=test.vlt_all, expect_filename=test.golden_filename) +test.compile() + +test.execute() test.passes()