diff --git a/src/V3LinkJump.cpp b/src/V3LinkJump.cpp index bce12782b..1ac3cd51f 100644 --- a/src/V3LinkJump.cpp +++ b/src/V3LinkJump.cpp @@ -45,7 +45,8 @@ VL_DEFINE_DEBUG_FUNCTIONS; class LinkJumpVisitor final : public VNVisitor { // NODE STATE - // AstNode::user1() -> AstJumpBlock*, for body of this loop + // AstBegin/etc::user1() -> AstJumpBlock*, for body of this loop + // AstFinish::user1() -> bool, processed // AstNode::user2() -> AstJumpBlock*, for this block // AstNodeBlock::user3() -> bool, true if contains a fork const VNUser1InUse m_user1InUse; @@ -437,6 +438,15 @@ class LinkJumpVisitor final : public VNVisitor { nodep->unlinkFrBack(); VL_DO_DANGLING(pushDeletep(nodep), nodep); } + void visit(AstFinish* nodep) override { + if (nodep->user1SetOnce()) return; // Process once + iterateChildren(nodep); + if (m_loopp) { + // Jump to the end of the loop (post-finish) + AstJumpBlock* const blockp = getJumpBlock(m_loopp, false); + nodep->addNextHere(new AstJumpGo{nodep->fileline(), blockp}); + } + } void visit(AstVarRef* nodep) override { if (m_loopInc && nodep->varp()) nodep->varp()->usedLoopIdx(true); } diff --git a/test_regress/t/t_while_finish.py b/test_regress/t/t_while_finish.py new file mode 100755 index 000000000..bd059b0f2 --- /dev/null +++ b/test_regress/t/t_while_finish.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 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=['--binary']) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_while_finish.v b/test_regress/t/t_while_finish.v new file mode 100644 index 000000000..82692197d --- /dev/null +++ b/test_regress/t/t_while_finish.v @@ -0,0 +1,21 @@ +// 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; + + int loops; + + initial begin + #1; + // verilator lint_off INFINITELOOP + while (1'b1) begin + $write("*-* All Finished *-*\n"); + $finish; // Infinite loop, but for this finish + if (++loops > 100) $stop; + end + end + +endmodule