diff --git a/src/V3Fork.cpp b/src/V3Fork.cpp index 7b8d065d9..117d56dd5 100644 --- a/src/V3Fork.cpp +++ b/src/V3Fork.cpp @@ -582,6 +582,39 @@ class ForkVisitor final : public VNVisitor { // We did wrap the body return true; } + static bool isForkJoinNoneSentinelDelay(const AstNode* const nodep) { + const AstDelay* const delayp = VN_CAST(nodep, Delay); + if (!delayp) return false; + const AstConst* const constp = VN_CAST(delayp->lhsp(), Const); + return constp && (constp->toUQuad() == std::numeric_limits::max()); + } + static bool isDisableQueuePushSelfStmt(const AstNode* const nodep) { + // Detect LinkJump-generated registration: + // __VprocessQueue_*.push_back(std::process::self()) + const AstStmtExpr* const stmtExprp = VN_CAST(nodep, StmtExpr); + if (!stmtExprp) return false; + const AstCMethodHard* const methodp = VN_CAST(stmtExprp->exprp(), CMethodHard); + if (!methodp || methodp->name() != "push_back") return false; + const AstVarRef* const queueRefp = VN_CAST(methodp->fromp(), VarRef); + return queueRefp && queueRefp->name().rfind("__VprocessQueue_", 0) == 0; + } + static void moveForkSentinelAfterDisableQueuePushes(AstBegin* const beginp) { + AstNode* const firstStmtp = beginp->stmtsp(); + if (!isForkJoinNoneSentinelDelay(firstStmtp)) return; + + AstNode* insertBeforep = firstStmtp->nextp(); + while (insertBeforep && isDisableQueuePushSelfStmt(insertBeforep)) { + insertBeforep = insertBeforep->nextp(); + } + if (insertBeforep == firstStmtp->nextp()) return; + + AstNode* const delayp = firstStmtp->unlinkFrBackWithNext(); + if (insertBeforep) { + insertBeforep->addHereThisAsNext(delayp); + } else { + beginp->addStmtsp(delayp); + } + } // VISITORS void visit(AstNodeModule* nodep) override { @@ -619,6 +652,7 @@ class ForkVisitor final : public VNVisitor { new AstConst{fl, AstConst::Unsized64{}, std::numeric_limits::max()}, false}; itemp->stmtsp()->addHereThisAsNext(delayp); + moveForkSentinelAfterDisableQueuePushes(itemp); } } diff --git a/test_regress/t/t_disable.py b/test_regress/t/t_disable.py index 67b896515..276645160 100755 --- a/test_regress/t/t_disable.py +++ b/test_regress/t/t_disable.py @@ -9,8 +9,10 @@ import vltest_bootstrap -test.scenarios('linter') +test.scenarios('simulator') -test.lint() +test.compile(timing_loop=True, verilator_flags2=["--timing"]) + +test.execute() test.passes()