Support ## delay on implication RHS in SVA properties (#7284)

This commit is contained in:
Yilou Wang
2026-03-20 09:53:49 -04:00
committed by GitHub
parent 998ec5b1d7
commit 25c3bc814e
5 changed files with 134 additions and 25 deletions
+41 -1
View File
@@ -609,7 +609,37 @@ private:
FileLine* const flp = nodep->fileline();
AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack();
AstNodeExpr* lhsp = nodep->lhsp()->unlinkFrBack();
if (nodep->isOverlapped()) {
if (AstPExpr* const pexprp = VN_CAST(rhsp, PExpr)) {
// Implication with sequence expression on RHS (IEEE 1800-2023 16.11, 16.12.7).
// The PExpr was already lowered from the property expression by V3AssertProp.
// Wrap the PExpr body with the antecedent check so the sequence only
// starts when the antecedent holds.
AstNodeExpr* condp;
if (nodep->isOverlapped()) {
// Overlapped implication (|->): check antecedent on same cycle.
// disable iff is applied at the assertion level, not at the
// antecedent gate, matching the existing non-PExpr overlapped path.
condp = new AstSampled{flp, lhsp};
condp->dtypeFrom(lhsp);
} else {
// Non-overlapped implication (|=>): check antecedent from previous cycle
if (m_disablep) {
lhsp
= new AstAnd{flp, new AstNot{flp, m_disablep->cloneTreePure(false)}, lhsp};
}
AstPast* const pastp = new AstPast{flp, lhsp};
pastp->dtypeFrom(lhsp);
pastp->sentreep(newSenTree(nodep));
condp = pastp;
}
// Wrap existing PExpr body: if (antecedent) { <original body> } else { /* vacuous pass
// */ }
AstBegin* const bodyp = pexprp->bodyp();
AstNode* const origStmtsp = bodyp->stmtsp()->unlinkFrBackWithNext();
AstIf* const guardp = new AstIf{flp, condp, origStmtsp};
bodyp->addStmtsp(guardp);
nodep->replaceWith(pexprp);
} else if (nodep->isOverlapped()) {
nodep->replaceWith(new AstLogOr{flp, new AstLogNot{flp, lhsp}, rhsp});
} else {
if (m_disablep) {
@@ -667,6 +697,16 @@ private:
iterate(nodep);
return;
}
// Sequence expression as antecedent of implication is not yet supported
if (AstImplication* const implp = VN_CAST(nodep->backp(), Implication)) {
if (implp->lhsp() == nodep) {
implp->v3warn(E_UNSUPPORTED,
"Unsupported: Implication with sequence expression as antecedent");
nodep->replaceWith(new AstConst{nodep->fileline(), AstConst::BitFalse{}});
VL_DO_DANGLING(pushDeletep(nodep), nodep);
return;
}
}
VL_RESTORER(m_inPExpr);
VL_RESTORER(m_disableSeqIfp);
m_inPExpr = true;