mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
+2
-58
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user