Fix $finish inside fork blocks (#6555)
Signed-off-by: Bartłomiej Chmiel <bchmiel@antmicro.com>
This commit is contained in:
parent
61c64e4a3b
commit
9bd30baba4
|
|
@ -619,6 +619,20 @@ public:
|
|||
int instrCount() const override { return 0; } // Rarely executes
|
||||
bool sameNode(const AstNode* samep) const override { return fileline() == samep->fileline(); }
|
||||
};
|
||||
class AstFinishFork final : public AstNodeStmt {
|
||||
// $finish in fork
|
||||
public:
|
||||
explicit AstFinishFork(FileLine* fl)
|
||||
: ASTGEN_SUPER_FinishFork(fl) {}
|
||||
ASTGEN_MEMBERS_AstFinishFork;
|
||||
bool isGateOptimizable() const override { return false; }
|
||||
bool isPredictOptimizable() const override { return false; }
|
||||
bool isPure() override { return false; } // SPECIAL: $display has 'visual' ordering
|
||||
bool isOutputter() override { return true; } // SPECIAL: $display makes output
|
||||
bool isUnlikely() const override { return true; }
|
||||
int instrCount() const override { return 0; } // Rarely executes
|
||||
bool sameNode(const AstNode* samep) const override { return fileline() == samep->fileline(); }
|
||||
};
|
||||
class AstFireEvent final : public AstNodeStmt {
|
||||
// '-> _' and '->> _' event trigger statements
|
||||
// @astgen op1 := operandp : AstNodeExpr
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ class CfgBuilder final : public VNVisitorConst {
|
|||
void visit(AstComment*) override {} // ignore entirely
|
||||
void visit(AstDisplay* nodep) override { simpleStatement(nodep); }
|
||||
void visit(AstFinish* nodep) override { simpleStatement(nodep); }
|
||||
void visit(AstFinishFork* nodep) override { simpleStatement(nodep); }
|
||||
void visit(AstStmtExpr* nodep) override { simpleStatement(nodep); }
|
||||
void visit(AstStop* nodep) override { simpleStatement(nodep); }
|
||||
|
||||
|
|
|
|||
|
|
@ -165,6 +165,7 @@ class CfgLiveVariables final : VNVisitorConst {
|
|||
void visit(AstAssignW* nodep) override { single(nodep); }
|
||||
void visit(AstDisplay* nodep) override { single(nodep); }
|
||||
void visit(AstFinish* nodep) override { single(nodep); }
|
||||
void visit(AstFinishFork* nodep) override { single(nodep); }
|
||||
void visit(AstStmtExpr* nodep) override { single(nodep); }
|
||||
void visit(AstStop* nodep) override { single(nodep); }
|
||||
|
||||
|
|
|
|||
|
|
@ -1253,6 +1253,18 @@ public:
|
|||
puts(cvtToStr(nodep->fileline()->lineno()));
|
||||
puts(", \"\");\n");
|
||||
}
|
||||
void visit(AstFinishFork* nodep) override {
|
||||
putns(nodep, "VL_FINISH_MT(");
|
||||
putsQuoted(protect(nodep->fileline()->filename()));
|
||||
puts(", ");
|
||||
puts(cvtToStr(nodep->fileline()->lineno()));
|
||||
puts(", \"\");\n");
|
||||
if (m_cfuncp->isCoroutine()) {
|
||||
putns(nodep, "co_return;\n");
|
||||
} else {
|
||||
putns(nodep, "return;\n");
|
||||
}
|
||||
}
|
||||
void visit(AstPrintTimeScale* nodep) override {
|
||||
putns(nodep, "VL_PRINTTIMESCALE(");
|
||||
putsQuoted(protect(nodep->prettyName()));
|
||||
|
|
|
|||
|
|
@ -556,6 +556,7 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst {
|
|||
puts(";\n");
|
||||
}
|
||||
void visit(AstFinish* nodep) override { putfs(nodep, "$finish;\n"); }
|
||||
void visit(AstFinishFork* nodep) override { putfs(nodep, "$finish;\n"); }
|
||||
void visit(AstStmtExpr* nodep) override {
|
||||
iterateConst(nodep->exprp());
|
||||
puts(";\n");
|
||||
|
|
|
|||
|
|
@ -441,7 +441,10 @@ class LinkJumpVisitor final : public VNVisitor {
|
|||
void visit(AstFinish* nodep) override {
|
||||
if (nodep->user1SetOnce()) return; // Process once
|
||||
iterateChildren(nodep);
|
||||
if (m_loopp) {
|
||||
if (m_inFork) {
|
||||
nodep->replaceWith(new AstFinishFork{nodep->fileline()});
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
} else 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});
|
||||
|
|
|
|||
|
|
@ -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=["--timing"])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -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 Antmicro.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t;
|
||||
initial begin
|
||||
forever begin
|
||||
fork
|
||||
begin
|
||||
assert ($c(1)) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
wait ($c(1));
|
||||
end
|
||||
join_any
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
Loading…
Reference in New Issue