Revert NFA assertion outcomes (#7946 revert) (#8258)

This commit is contained in:
Wilson Snyder
2026-09-01 11:15:05 -04:00
parent 667f64813f
commit f694e9e1e8
56 changed files with 1224 additions and 3780 deletions
+2 -58
View File
@@ -149,24 +149,6 @@ void V3AssertCommon::collectDefaultDisable(AstNetlist* nodep) {
{ DefaultDisablePropagateVisitor{nodep}; }
}
AstNode* V3AssertCommon::repeatLoop(FileLine* flp, AstVar* counterp, AstNodeExpr* countp,
AstNode* actionp) {
AstAssign* const initp
= new AstAssign{flp, new AstVarRef{flp, counterp, VAccess::WRITE}, countp};
AstLoop* const loopp = new AstLoop{flp};
loopp->addStmtsp(
new AstLoopTest{flp, loopp,
new AstGt{flp, new AstVarRef{flp, counterp, VAccess::READ},
new AstConst{flp, AstConst::WidthedValue{}, 32, 0}}});
loopp->addStmtsp(actionp);
AstSub* const decrementp = new AstSub{flp, new AstVarRef{flp, counterp, VAccess::READ},
new AstConst{flp, AstConst::WidthedValue{}, 32, 1}};
decrementp->dtypeFrom(counterp);
loopp->addStmtsp(new AstAssign{flp, new AstVarRef{flp, counterp, VAccess::WRITE}, decrementp});
AstNode::addNext<AstNode, AstNode>(initp, loopp);
return initp;
}
void V3AssertCommon::lowerSequenceEvents(AstNetlist* nodep) {
{ SeqEventLowerVisitor{nodep}; }
V3Global::dumpCheckGlobalTree("assertseqevent", 0, dumpTreeEitherLevel() >= 3);
@@ -342,8 +324,6 @@ class AssertVisitor final : public VNVisitor {
VDouble0 m_statLiftedCaseExprs; // Count of purified case expressions
AstNodeFTask* m_ftaskp = nullptr; // Current function/task
V3UniqueNames m_caseTempNames{"__VCase"};
V3UniqueNames m_actionCountNames{"__VassertActionCount"}; // Action repeat count temps
bool m_inReactiveAssertionAction = false; // Action will execute after NBA
// Maps from (expression, senTree) to the AstAlways that computes its delayed values.
std::unordered_map<VNRef<AstNodeExpr>, std::unordered_map<VNRef<AstSenTree>, AstAlways*>>
m_modExpr2Sen2DelayedAlwaysp;
@@ -449,16 +429,6 @@ class AssertVisitor final : public VNVisitor {
AstSampled* newSampledExpr(AstNodeExpr* nodep) {
return new AstSampled{nodep->fileline(), nodep, nodep->dtypep(), true};
}
AstNode* repeatAction(FileLine* flp, AstNodeExpr* countp, AstNode* actionp) {
AstNodeDType* const u32p = m_modp->findBasicDType(VBasicDTypeKwd::UINT32);
AstVar* const counterp
= new AstVar{flp, VVarType::BLOCKTEMP, m_actionCountNames.get(""), u32p};
counterp->lifetime(VLifetime::AUTOMATIC_EXPLICIT);
AstBegin* const beginp = new AstBegin{flp, "", counterp, true};
beginp->addStmtsp(V3AssertCommon::repeatLoop(flp, counterp, countp, actionp));
return beginp;
}
AstVarRef* newMonitorNumVarRefp(const AstNode* nodep, VAccess access) {
if (!m_monitorNumVarp) {
m_monitorNumVarp = new AstVar{nodep->fileline(), VVarType::MODULETEMP, "__VmonitorNum",
@@ -662,31 +632,12 @@ class AssertVisitor final : public VNVisitor {
return varpr;
}
AstNode* wrapAssertionInSensitivity(AstNodeCoverOrAssert* nodep, AstSenTree* sentreep,
AstNode* bodysp) {
if (!sentreep) return bodysp;
FileLine* const flp = nodep->fileline();
if (nodep->nfaLowered()) {
// Impure: a $finish in an earlier same-slot region must be seen live
AstNodeExpr* const notFinishp
= new AstLogNot{flp, new AstCExpr{flp,
"(vlSymsp->_vm_contextp__->finishPending()"
" || vlSymsp->_vm_contextp__->gotFinish())",
1}};
bodysp = new AstIf{flp, notFinishp, bodysp};
return new AstAlwaysReactive{flp, sentreep, bodysp};
}
return new AstAlways{flp, VAlwaysKwd::ALWAYS, sentreep, bodysp};
}
void visitAssertionIterate(AstNodeCoverOrAssert* nodep, AstNode* failsp) {
if (m_beginp && nodep->name() == "") nodep->name(m_beginp->name());
{ AssertDeFutureVisitor{nodep->propp(), m_modp, m_modPastNum++}; }
iterateAndNextNull(nodep->sentreep());
VL_RESTORER(m_inReactiveAssertionAction);
m_inReactiveAssertionAction = nodep->nfaLowered();
if (AstAssert* const assertp = VN_CAST(nodep, Assert)) {
iterateAndNextNull(assertp->failsp());
} else if (AstAssertIntrinsic* const assertp = VN_CAST(nodep, AssertIntrinsic)) {
@@ -740,8 +691,6 @@ class AssertVisitor final : public VNVisitor {
// V3Coverage assigned us a bucket to increment.
AstCoverInc* const covincp = VN_AS(coverp->coverincsp(), CoverInc);
UASSERT_OBJ(covincp, coverp, "Missing AstCoverInc under assertion");
AstNodeExpr* const multiplicityp = covincp->multiplicityp();
if (multiplicityp) multiplicityp->unlinkFrBack();
covincp->unlinkFrBackWithNext(); // next() might have AstAssign for trace
if (message != "") covincp->declp()->comment(message);
if (passsp) {
@@ -752,7 +701,6 @@ class AssertVisitor final : public VNVisitor {
} else {
passsp = covincp;
}
if (multiplicityp) passsp = repeatAction(nodep->fileline(), multiplicityp, passsp);
}
} else if (VN_IS(nodep, Assert) || VN_IS(nodep, AssertIntrinsic)) {
if (nodep->immediate()) {
@@ -822,7 +770,7 @@ class AssertVisitor final : public VNVisitor {
if (disablep) bodysp = new AstIf{flp, new AstLogNot{flp, disablep}, bodysp};
// Add assertOn check last, for better combining
if (!seqEvent) bodysp = newIfAssertOn(bodysp, nodep->directive(), nodep->userType());
bodysp = wrapAssertionInSensitivity(nodep, sentreep, bodysp);
if (sentreep) bodysp = new AstAlways{flp, VAlwaysKwd::ALWAYS, sentreep, bodysp};
if (passsp && !passsp->backp()) VL_DO_DANGLING(pushDeletep(passsp), passsp);
if (failsp && !failsp->backp()) VL_DO_DANGLING(pushDeletep(failsp), failsp);
@@ -1151,11 +1099,7 @@ class AssertVisitor final : public VNVisitor {
condp->dtypeFrom(onTickp);
inp = condp;
} else {
// Post-NBA readers use the pipeline's next stage after this tick's shift.
const bool procedureRunsPostNba = VN_IS(m_procedurep, AlwaysObserved);
const uint32_t pipelineTicks
= ticks + (procedureRunsPostNba || m_inReactiveAssertionAction ? 1 : 0);
inp = getPastValue(exprp, initp, senTreep, pipelineTicks);
inp = getPastValue(exprp, initp, senTreep, ticks);
}
nodep->replaceWith(inp);
VL_DO_DANGLING(pushDeletep(nodep), nodep);