Support simple cycle delay sequence expressions inside assertion properties (#6508)

Signed-off-by: Bartłomiej Chmiel <bchmiel@antmicro.com>
Co-authored-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
Bartłomiej Chmiel 2025-10-10 16:16:15 +02:00 committed by GitHub
parent 2ac7cf51a9
commit 31e73f1645
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
29 changed files with 1488 additions and 390 deletions

View File

@ -142,6 +142,7 @@ class AssertVisitor final : public VNVisitor {
VDouble0 m_statAsFull; // Statistic tracking VDouble0 m_statAsFull; // Statistic tracking
VDouble0 m_statPastVars; // Statistic tracking VDouble0 m_statPastVars; // Statistic tracking
bool m_inSampled = false; // True inside a sampled expression bool m_inSampled = false; // True inside a sampled expression
bool m_inRestrict = false; // True inside restrict assertion
// METHODS // METHODS
static AstNodeExpr* assertOnCond(FileLine* fl, VAssertType type, static AstNodeExpr* assertOnCond(FileLine* fl, VAssertType type,
@ -274,6 +275,38 @@ class AssertVisitor final : public VNVisitor {
return newp; return newp;
} }
static AstIf* assertCond(AstNodeCoverOrAssert* nodep, AstNodeExpr* propp, AstNode* passsp,
AstNode* failsp) {
AstIf* const ifp = new AstIf{nodep->fileline(), propp, passsp, failsp};
// It's more LIKELY that we'll take the nullptr if clause
// than the sim-killing else clause:
ifp->branchPred(VBranchPred::BP_LIKELY);
ifp->isBoundsCheck(true); // To avoid LATCH warning
return ifp;
}
static AstNode* assertBody(AstNodeCoverOrAssert* nodep, AstNodeExpr* propp, AstNode* passsp,
AstNode* failsp) {
if (AstPExpr* const pExpr = VN_CAST(propp, PExpr)) {
AstNodeExpr* const condp = pExpr->condp();
UASSERT_OBJ(condp, pExpr, "Should have condition");
AstIf* const ifp = assertCond(nodep, condp->unlinkFrBack(), passsp, failsp);
AstNode* const precondps = pExpr->precondp();
UASSERT_OBJ(precondps, pExpr, "Should have precondition");
precondps->unlinkFrBackWithNext()->addNext(ifp);
AstNodeStmt* const assertOnp
= newIfAssertOn(precondps, nodep->directive(), nodep->type());
AstFork* const forkp = new AstFork{precondps->fileline(), "", assertOnp};
forkp->joinType(VJoinType::JOIN_NONE);
return forkp;
}
AstIf* const ifp = assertCond(nodep, propp, passsp, failsp);
return newIfAssertOn(ifp, nodep->directive(), nodep->type());
}
AstNodeStmt* newFireAssertUnchecked(const AstNodeStmt* nodep, const string& message, AstNodeStmt* newFireAssertUnchecked(const AstNodeStmt* nodep, const string& message,
AstNodeExpr* exprsp = nullptr) { AstNodeExpr* exprsp = nullptr) {
// Like newFireAssert() but omits the asserts-on check // Like newFireAssert() but omits the asserts-on check
@ -321,9 +354,7 @@ class AssertVisitor final : public VNVisitor {
} }
} }
// //
AstNode* bodysp = nullptr;
bool selfDestruct = false; bool selfDestruct = false;
AstIf* ifp = nullptr;
if (const AstCover* const snodep = VN_CAST(nodep, Cover)) { if (const AstCover* const snodep = VN_CAST(nodep, Cover)) {
++m_statCover; ++m_statCover;
if (!v3Global.opt.coverageUser()) { if (!v3Global.opt.coverageUser()) {
@ -334,14 +365,12 @@ class AssertVisitor final : public VNVisitor {
UASSERT_OBJ(covincp, snodep, "Missing AstCoverInc under assertion"); UASSERT_OBJ(covincp, snodep, "Missing AstCoverInc under assertion");
covincp->unlinkFrBackWithNext(); // next() might have AstAssign for trace covincp->unlinkFrBackWithNext(); // next() might have AstAssign for trace
if (message != "") covincp->declp()->comment(message); if (message != "") covincp->declp()->comment(message);
bodysp = covincp; if (passsp) {
passsp = AstNode::addNext<AstNode, AstNode>(covincp, passsp);
} else {
passsp = covincp;
}
} }
if (bodysp && passsp) bodysp = bodysp->addNext(passsp);
if (bodysp) bodysp = newIfAssertOn(bodysp, nodep->directive(), nodep->type());
ifp = new AstIf{nodep->fileline(), propp, bodysp};
ifp->isBoundsCheck(true); // To avoid LATCH warning
bodysp = ifp;
} else if (VN_IS(nodep, Assert) || VN_IS(nodep, AssertIntrinsic)) { } else if (VN_IS(nodep, Assert) || VN_IS(nodep, AssertIntrinsic)) {
if (nodep->immediate()) { if (nodep->immediate()) {
++m_statAsImm; ++m_statAsImm;
@ -349,33 +378,26 @@ class AssertVisitor final : public VNVisitor {
++m_statAsNotImm; ++m_statAsNotImm;
} }
if (!passsp && !failsp) failsp = newFireAssertUnchecked(nodep, "'assert' failed."); if (!passsp && !failsp) failsp = newFireAssertUnchecked(nodep, "'assert' failed.");
ifp = new AstIf{nodep->fileline(), propp, passsp, failsp};
ifp->isBoundsCheck(true); // To avoid LATCH warning
// It's more LIKELY that we'll take the nullptr if clause
// than the sim-killing else clause:
ifp->branchPred(VBranchPred::BP_LIKELY);
bodysp = newIfAssertOn(ifp, nodep->directive(), nodep->type());
} else { } else {
nodep->v3fatalSrc("Unknown node type"); nodep->v3fatalSrc("Unknown node type");
} }
AstNode* bodysp = assertBody(nodep, propp, passsp, failsp);
if (sentreep) {
bodysp = new AstAlways{nodep->fileline(), VAlwaysKwd::ALWAYS, sentreep, bodysp};
}
if (passsp && !passsp->backp()) VL_DO_DANGLING(pushDeletep(passsp), passsp); if (passsp && !passsp->backp()) VL_DO_DANGLING(pushDeletep(passsp), passsp);
if (failsp && !failsp->backp()) VL_DO_DANGLING(pushDeletep(failsp), failsp); if (failsp && !failsp->backp()) VL_DO_DANGLING(pushDeletep(failsp), failsp);
AstNode* newp;
if (sentreep) {
newp = new AstAlways{nodep->fileline(), VAlwaysKwd::ALWAYS, sentreep, bodysp};
} else {
newp = bodysp;
}
// Install it // Install it
if (selfDestruct) { if (selfDestruct) {
// Delete it after making the tree. This way we can tell the user // Delete it after making the tree. This way we can tell the user
// if it wasn't constructed nicely or has other errors without needing --coverage. // if it wasn't constructed nicely or has other errors without needing --coverage.
VL_DO_DANGLING(newp->deleteTree(), newp); VL_DO_DANGLING(bodysp->deleteTree(), bodysp);
nodep->unlinkFrBack(); nodep->unlinkFrBack();
} else { } else {
nodep->replaceWith(newp); nodep->replaceWith(bodysp);
} }
// Bye // Bye
VL_DO_DANGLING(pushDeletep(nodep), nodep); VL_DO_DANGLING(pushDeletep(nodep), nodep);
@ -579,6 +601,7 @@ class AssertVisitor final : public VNVisitor {
AstVar* const outvarp = new AstVar{ AstVar* const outvarp = new AstVar{
nodep->fileline(), VVarType::MODULETEMP, nodep->fileline(), VVarType::MODULETEMP,
"_Vpast_" + cvtToStr(m_modPastNum++) + "_" + cvtToStr(i), inp->dtypep()}; "_Vpast_" + cvtToStr(m_modPastNum++) + "_" + cvtToStr(i), inp->dtypep()};
outvarp->lifetime(VLifetime::AUTOMATIC_EXPLICIT);
++m_statPastVars; ++m_statPastVars;
m_modp->addStmtsp(outvarp); m_modp->addStmtsp(outvarp);
AstNode* const assp = new AstAssignDly{ AstNode* const assp = new AstAssignDly{
@ -605,7 +628,7 @@ class AssertVisitor final : public VNVisitor {
} }
void visit(AstVarRef* nodep) override { void visit(AstVarRef* nodep) override {
iterateChildren(nodep); iterateChildren(nodep);
if (m_inSampled) { if (m_inSampled && !VString::startsWith(nodep->name(), "__VpropPrecond")) {
if (!nodep->access().isReadOnly()) { if (!nodep->access().isReadOnly()) {
nodep->v3warn(E_UNSUPPORTED, nodep->v3warn(E_UNSUPPORTED,
"Unsupported: Write to variable in sampled expression"); "Unsupported: Write to variable in sampled expression");
@ -625,6 +648,19 @@ class AssertVisitor final : public VNVisitor {
m_inSampled = false; m_inSampled = false;
iterateChildren(nodep); iterateChildren(nodep);
} }
void visit(AstPExpr* nodep) override {
{
VL_RESTORER(m_inSampled);
m_inSampled = false;
iterateAndNextNull(nodep->precondp());
}
iterate(nodep->condp());
if (!m_inRestrict) {
VL_DO_DANGLING(pushDeletep(nodep), nodep);
} else {
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
}
}
//========== Statements //========== Statements
void visit(AstDisplay* nodep) override { void visit(AstDisplay* nodep) override {
@ -790,6 +826,8 @@ class AssertVisitor final : public VNVisitor {
visitAssertionIterate(nodep, nullptr); visitAssertionIterate(nodep, nullptr);
} }
void visit(AstRestrict* nodep) override { void visit(AstRestrict* nodep) override {
VL_RESTORER(m_inRestrict);
m_inRestrict = true;
iterateChildren(nodep); iterateChildren(nodep);
// IEEE says simulator ignores these // IEEE says simulator ignores these
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);

View File

@ -56,10 +56,15 @@ private:
AstNodeExpr* m_disablep = nullptr; // Last disable AstNodeExpr* m_disablep = nullptr; // Last disable
// Other: // Other:
V3UniqueNames m_cycleDlyNames{"__VcycleDly"}; // Cycle delay counter name generator V3UniqueNames m_cycleDlyNames{"__VcycleDly"}; // Cycle delay counter name generator
V3UniqueNames m_propPrecondNames{"__VpropPrecond"}; // Cycle delay temporaries name generator
bool m_inAssign = false; // True if in an AssignNode bool m_inAssign = false; // True if in an AssignNode
bool m_inAssignDlyLhs = false; // True if in AssignDly's LHS bool m_inAssignDlyLhs = false; // True if in AssignDly's LHS
bool m_inSynchDrive = false; // True if in synchronous drive bool m_inSynchDrive = false; // True if in synchronous drive
std::vector<AstVarXRef*> m_xrefsp; // list of xrefs that need name fixup std::vector<AstVarXRef*> m_xrefsp; // list of xrefs that need name fixup
AstNodeExpr* m_hasUnsupp = nullptr; // True if assert has unsupported construct inside
AstPExpr* m_pExpr = nullptr; // Current AstPExpr
bool m_hasSExpr = false; // True if assert has AstSExpr inside
bool m_inSExpr = false; // True if in AstSExpr
// METHODS // METHODS
@ -335,16 +340,21 @@ private:
VL_DO_DANGLING(valuep->deleteTree(), valuep); VL_DO_DANGLING(valuep->deleteTree(), valuep);
return; return;
} }
AstSenItem* sensesp = nullptr;
if (!m_defaultClockingp) { if (!m_defaultClockingp) {
if (!m_pExpr && !m_inSExpr) {
nodep->v3error("Usage of cycle delays requires default clocking" nodep->v3error("Usage of cycle delays requires default clocking"
" (IEEE 1800-2023 14.11)"); " (IEEE 1800-2023 14.11)");
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
VL_DO_DANGLING(valuep->deleteTree(), valuep); VL_DO_DANGLING(valuep->deleteTree(), valuep);
return; return;
} }
sensesp = m_senip;
} else {
sensesp = m_defaultClockingp->sensesp();
}
AstEventControl* const controlp = new AstEventControl{ AstEventControl* const controlp = new AstEventControl{
nodep->fileline(), nodep->fileline(), new AstSenTree{flp, sensesp->cloneTree(false)}, nullptr};
new AstSenTree{flp, m_defaultClockingp->sensesp()->cloneTree(false)}, nullptr};
const std::string delayName = m_cycleDlyNames.get(nodep); const std::string delayName = m_cycleDlyNames.get(nodep);
AstVar* const cntVarp = new AstVar{flp, VVarType::BLOCKTEMP, delayName + "__counter", AstVar* const cntVarp = new AstVar{flp, VVarType::BLOCKTEMP, delayName + "__counter",
nodep->findBasicDType(VBasicDTypeKwd::UINT32)}; nodep->findBasicDType(VBasicDTypeKwd::UINT32)};
@ -408,6 +418,33 @@ private:
} }
} }
nodep->user1(true); nodep->user1(true);
} else if (m_inSExpr && !nodep->user1()) {
AstVar* const preVarp
= new AstVar{nodep->varp()->fileline(), VVarType::BLOCKTEMP,
m_propPrecondNames.get(nodep->varp()) + "__" + nodep->varp()->name(),
nodep->varp()->dtypep()};
preVarp->lifetime(VLifetime::STATIC_EXPLICIT);
m_modp->addStmtsp(preVarp);
AstVarRef* const origp
= new AstVarRef{nodep->fileline(), nodep->varp(), VAccess::READ};
origp->user1(true);
AstVarRef* const precondp
= new AstVarRef{preVarp->fileline(), preVarp, VAccess::WRITE};
precondp->user1(true);
// Pack assignments in sampled as in concurrent assertions they are needed.
// Then, in assert's propp, sample only non-precondition variables.
AstSampled* const sampledp = new AstSampled{origp->fileline(), origp};
sampledp->dtypeFrom(origp);
UASSERT(m_pExpr, "Should be under assertion");
AstAssign* const assignp = new AstAssign{m_pExpr->fileline(), precondp, sampledp};
m_pExpr->addPrecondp(assignp);
AstVarRef* const precondReadp
= new AstVarRef{preVarp->fileline(), preVarp, VAccess::READ};
precondReadp->user1(true);
nodep->replaceWith(precondReadp);
VL_DO_DANGLING(pushDeletep(nodep), nodep);
} }
} }
void visit(AstMemberSel* nodep) override { void visit(AstMemberSel* nodep) override {
@ -461,10 +498,33 @@ private:
void visit(AstNodeCoverOrAssert* nodep) override { void visit(AstNodeCoverOrAssert* nodep) override {
if (nodep->sentreep()) return; // Already processed if (nodep->sentreep()) return; // Already processed
VL_RESTORER(m_hasSExpr);
VL_RESTORER(m_hasUnsupp);
clearAssertInfo(); clearAssertInfo();
m_pExpr = new AstPExpr{nodep->propp()->fileline()};
m_pExpr->dtypeFrom(nodep->propp());
// Find Clocking's buried under nodep->exprsp // Find Clocking's buried under nodep->exprsp
iterateChildren(nodep); iterateChildren(nodep);
if (!nodep->immediate()) nodep->sentreep(newSenTree(nodep)); if (!nodep->immediate()) nodep->sentreep(newSenTree(nodep));
if (m_hasSExpr && m_hasUnsupp) {
if (VN_IS(m_hasUnsupp, Implication)) {
m_hasUnsupp->v3warn(E_UNSUPPORTED,
"Unsupported: Implication with sequence expression");
} else {
m_hasUnsupp->v3warn(E_UNSUPPORTED,
"Unsupported: Disable iff with sequence expression");
}
if (m_pExpr) VL_DO_DANGLING(pushDeletep(m_pExpr), m_pExpr);
} else if (m_pExpr && m_pExpr->precondp()) {
m_pExpr->condp(VN_AS(nodep->propp()->unlinkFrBackWithNext(), NodeExpr));
nodep->propp(m_pExpr);
iterateAndNextNull(m_pExpr->precondp());
} else if (m_pExpr) {
VL_DO_DANGLING(pushDeletep(m_pExpr), m_pExpr);
}
clearAssertInfo(); clearAssertInfo();
} }
void visit(AstFalling* nodep) override { void visit(AstFalling* nodep) override {
@ -488,12 +548,12 @@ private:
if (exprp->width() > 1) exprp = new AstSel{fl, exprp, 0, 1}; if (exprp->width() > 1) exprp = new AstSel{fl, exprp, 0, 1};
AstSenTree* sentreep = nodep->sentreep(); AstSenTree* sentreep = nodep->sentreep();
if (sentreep) sentreep->unlinkFrBack(); if (sentreep) sentreep->unlinkFrBack();
AstNodeExpr* const pastp = new AstPast{fl, exprp}; AstPast* const pastp = new AstPast{fl, exprp};
pastp->dtypeFrom(exprp); pastp->dtypeFrom(exprp);
pastp->sentreep(newSenTree(nodep, sentreep));
exprp = new AstAnd{fl, pastp, new AstNot{fl, exprp->cloneTreePure(false)}}; exprp = new AstAnd{fl, pastp, new AstNot{fl, exprp->cloneTreePure(false)}};
exprp->dtypeSetBit(); exprp->dtypeSetBit();
nodep->replaceWith(exprp); nodep->replaceWith(exprp);
nodep->sentreep(newSenTree(nodep, sentreep));
VL_DO_DANGLING(pushDeletep(nodep), nodep); VL_DO_DANGLING(pushDeletep(nodep), nodep);
} }
void visit(AstFuture* nodep) override { void visit(AstFuture* nodep) override {
@ -503,6 +563,10 @@ private:
if (sentreep) VL_DO_DANGLING(pushDeletep(sentreep->unlinkFrBack()), sentreep); if (sentreep) VL_DO_DANGLING(pushDeletep(sentreep->unlinkFrBack()), sentreep);
nodep->sentreep(newSenTree(nodep)); nodep->sentreep(newSenTree(nodep));
} }
void visit(AstLogNot* nodep) override {
if (m_inSExpr) nodep->v3error("Syntax error: unexpected 'not' in sequence expression");
iterateChildren(nodep);
}
void visit(AstPast* nodep) override { void visit(AstPast* nodep) override {
if (nodep->sentreep()) return; // Already processed if (nodep->sentreep()) return; // Already processed
iterateChildren(nodep); iterateChildren(nodep);
@ -529,12 +593,12 @@ private:
if (exprp->width() > 1) exprp = new AstSel{fl, exprp, 0, 1}; if (exprp->width() > 1) exprp = new AstSel{fl, exprp, 0, 1};
AstSenTree* sentreep = nodep->sentreep(); AstSenTree* sentreep = nodep->sentreep();
if (sentreep) sentreep->unlinkFrBack(); if (sentreep) sentreep->unlinkFrBack();
AstNodeExpr* const pastp = new AstPast{fl, exprp}; AstPast* const pastp = new AstPast{fl, exprp};
pastp->dtypeFrom(exprp); pastp->dtypeFrom(exprp);
pastp->sentreep(newSenTree(nodep, sentreep));
exprp = new AstAnd{fl, new AstNot{fl, pastp}, exprp->cloneTreePure(false)}; exprp = new AstAnd{fl, new AstNot{fl, pastp}, exprp->cloneTreePure(false)};
exprp->dtypeSetBit(); exprp->dtypeSetBit();
nodep->replaceWith(exprp); nodep->replaceWith(exprp);
nodep->sentreep(newSenTree(nodep, sentreep));
VL_DO_DANGLING(pushDeletep(nodep), nodep); VL_DO_DANGLING(pushDeletep(nodep), nodep);
} }
void visit(AstStable* nodep) override { void visit(AstStable* nodep) override {
@ -544,12 +608,12 @@ private:
AstNodeExpr* exprp = nodep->exprp()->unlinkFrBack(); AstNodeExpr* exprp = nodep->exprp()->unlinkFrBack();
AstSenTree* sentreep = nodep->sentreep(); AstSenTree* sentreep = nodep->sentreep();
if (sentreep) sentreep->unlinkFrBack(); if (sentreep) sentreep->unlinkFrBack();
AstNodeExpr* const pastp = new AstPast{fl, exprp}; AstPast* const pastp = new AstPast{fl, exprp};
pastp->dtypeFrom(exprp); pastp->dtypeFrom(exprp);
pastp->sentreep(newSenTree(nodep, sentreep));
exprp = new AstEq{fl, pastp, exprp->cloneTreePure(false)}; exprp = new AstEq{fl, pastp, exprp->cloneTreePure(false)};
exprp->dtypeSetBit(); exprp->dtypeSetBit();
nodep->replaceWith(exprp); nodep->replaceWith(exprp);
nodep->sentreep(newSenTree(nodep, sentreep));
VL_DO_DANGLING(pushDeletep(nodep), nodep); VL_DO_DANGLING(pushDeletep(nodep), nodep);
} }
void visit(AstSteady* nodep) override { void visit(AstSteady* nodep) override {
@ -568,21 +632,27 @@ private:
void visit(AstImplication* nodep) override { void visit(AstImplication* nodep) override {
if (nodep->sentreep()) return; // Already processed if (nodep->sentreep()) return; // Already processed
m_hasUnsupp = nodep;
FileLine* const fl = nodep->fileline(); iterateChildren(nodep);
FileLine* const flp = nodep->fileline();
AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack(); AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack();
AstNodeExpr* lhsp = nodep->lhsp()->unlinkFrBack(); AstNodeExpr* lhsp = nodep->lhsp()->unlinkFrBack();
if (nodep->isOverlapped()) {
nodep->replaceWith(new AstLogOr{flp, new AstLogNot{flp, lhsp}, rhsp});
} else {
if (m_disablep) { if (m_disablep) {
lhsp = new AstAnd{fl, new AstNot{fl, m_disablep->cloneTreePure(false)}, lhsp}; lhsp = new AstAnd{flp, new AstNot{flp, m_disablep->cloneTreePure(false)}, lhsp};
} }
AstNodeExpr* const pastp = new AstPast{fl, lhsp}; AstPast* const pastp = new AstPast{flp, lhsp};
pastp->dtypeFrom(lhsp); pastp->dtypeFrom(lhsp);
AstNodeExpr* const exprp = new AstOr{fl, new AstNot{fl, pastp}, rhsp}; pastp->sentreep(newSenTree(nodep));
AstNodeExpr* const exprp = new AstOr{flp, new AstNot{flp, pastp}, rhsp};
exprp->dtypeSetBit(); exprp->dtypeSetBit();
nodep->replaceWith(exprp); nodep->replaceWith(exprp);
nodep->sentreep(newSenTree(nodep)); }
VL_DO_DANGLING(pushDeletep(nodep), nodep); VL_DO_DANGLING(pushDeletep(nodep), nodep);
} }
@ -614,6 +684,7 @@ private:
} }
if (AstNodeExpr* const disablep = nodep->disablep()) { if (AstNodeExpr* const disablep = nodep->disablep()) {
m_disablep = disablep; m_disablep = disablep;
m_hasUnsupp = disablep;
if (VN_IS(nodep->backp(), Cover)) { if (VN_IS(nodep->backp(), Cover)) {
blockp = new AstAnd{disablep->fileline(), blockp = new AstAnd{disablep->fileline(),
new AstNot{disablep->fileline(), disablep->unlinkFrBack()}, new AstNot{disablep->fileline(), disablep->unlinkFrBack()},
@ -627,6 +698,18 @@ private:
nodep->replaceWith(blockp); nodep->replaceWith(blockp);
VL_DO_DANGLING(pushDeletep(nodep), nodep); VL_DO_DANGLING(pushDeletep(nodep), nodep);
} }
void visit(AstSExpr* nodep) override {
VL_RESTORER(m_inSExpr);
m_inSExpr = true;
m_hasSExpr = true;
UASSERT_OBJ(m_pExpr, nodep, "Should be under assertion");
m_pExpr->addPrecondp(nodep->delayp()->unlinkFrBack());
iterateChildren(nodep);
nodep->replaceWith(nodep->exprp()->unlinkFrBack());
VL_DO_DANGLING(pushDeletep(nodep), nodep);
}
void visit(AstNodeModule* nodep) override { void visit(AstNodeModule* nodep) override {
VL_RESTORER(m_defaultClockingp); VL_RESTORER(m_defaultClockingp);
VL_RESTORER(m_defaultDisablep); VL_RESTORER(m_defaultDisablep);

View File

@ -1523,14 +1523,19 @@ public:
}; };
class AstImplication final : public AstNodeExpr { class AstImplication final : public AstNodeExpr {
// Verilog Implication Operator // Verilog Implication Operator
// Nonoverlapping "|=>" // Nonoverlapped "|=>"
// Overlapping "|->" (doesn't currently use this - might make new Ast type) // Overlapped "|->"
// @astgen op1 := lhsp : AstNodeExpr // @astgen op1 := lhsp : AstNodeExpr
// @astgen op2 := rhsp : AstNodeExpr // @astgen op2 := rhsp : AstNodeExpr
// @astgen op3 := sentreep : Optional[AstSenTree] // @astgen op3 := sentreep : Optional[AstSenTree]
private:
const bool m_isOverlapped; // True if overlapped
public: public:
AstImplication(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp) AstImplication(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp, bool isOverlapped)
: ASTGEN_SUPER_Implication(fl) { : ASTGEN_SUPER_Implication(fl)
, m_isOverlapped{isOverlapped} {
this->lhsp(lhsp); this->lhsp(lhsp);
this->rhsp(rhsp); this->rhsp(rhsp);
} }
@ -1541,6 +1546,7 @@ public:
bool cleanOut() const override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { V3ERROR_NA_RETURN(""); }
int instrCount() const override { return widthInstrs(); } int instrCount() const override { return widthInstrs(); }
bool sameNode(const AstNode* /*samep*/) const override { return true; } bool sameNode(const AstNode* /*samep*/) const override { return true; }
bool isOverlapped() const { return m_isOverlapped; }
}; };
class AstInitArray final : public AstNodeExpr { class AstInitArray final : public AstNodeExpr {
// This is also used as an array value in V3Simulate/const prop. // This is also used as an array value in V3Simulate/const prop.
@ -1706,6 +1712,19 @@ public:
bool sameNode(const AstNode* /*samep*/) const override { return true; } bool sameNode(const AstNode* /*samep*/) const override { return true; }
int instrCount() const override { return widthInstrs(); } int instrCount() const override { return widthInstrs(); }
}; };
class AstPExpr final : public AstNodeExpr {
// Property expression
// @astgen op1 := precondp : List[AstNode]
// @astgen op2 := condp : Optional[AstNodeExpr]
public:
explicit AstPExpr(FileLine* fl)
: ASTGEN_SUPER_PExpr(fl) {}
ASTGEN_MEMBERS_AstPExpr;
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); }
bool cleanOut() const override { V3ERROR_NA_RETURN(""); }
int instrCount() const override { return widthInstrs(); }
};
class AstParseHolder final : public AstNodeExpr { class AstParseHolder final : public AstNodeExpr {
// A reference to something soon to replace, used in a select at parse time // A reference to something soon to replace, used in a select at parse time
// that needs conversion to pull the upper lvalue later // that needs conversion to pull the upper lvalue later
@ -1915,6 +1934,22 @@ public:
int instrCount() const override { return widthInstrs(); } int instrCount() const override { return widthInstrs(); }
bool sameNode(const AstNode* /*samep*/) const override { return true; } bool sameNode(const AstNode* /*samep*/) const override { return true; }
}; };
class AstSExpr final : public AstNodeExpr {
// Sequence expression
// @astgen op1 := delayp : AstDelay
// @astgen op2 := exprp : AstNodeExpr
public:
explicit AstSExpr(FileLine* fl, AstDelay* delayp, AstNodeExpr* exprp)
: ASTGEN_SUPER_SExpr(fl) {
this->delayp(delayp);
this->exprp(exprp);
}
ASTGEN_MEMBERS_AstSExpr;
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); }
bool cleanOut() const override { V3ERROR_NA_RETURN(""); }
int instrCount() const override { return widthInstrs(); }
};
class AstSFormatF final : public AstNodeExpr { class AstSFormatF final : public AstNodeExpr {
// Convert format to string, generally under an AstDisplay or AstSFormat // Convert format to string, generally under an AstDisplay or AstSFormat
// Also used as "real" function for /*verilator sformat*/ functions // Also used as "real" function for /*verilator sformat*/ functions

View File

@ -1204,6 +1204,9 @@ public:
: ASTGEN_SUPER_Assert(fl, propp, passsp, type, directive, name) { : ASTGEN_SUPER_Assert(fl, propp, passsp, type, directive, name) {
addFailsp(failsp); addFailsp(failsp);
} }
string verilogKwd() const override {
return directive() == VAssertDirectiveType::ASSERT ? "assert" : "assume";
}
}; };
class AstAssertIntrinsic final : public AstNodeCoverOrAssert { class AstAssertIntrinsic final : public AstNodeCoverOrAssert {
// A $cast or other compiler inserted assert, that must run even without --assert option // A $cast or other compiler inserted assert, that must run even without --assert option
@ -1217,6 +1220,7 @@ public:
VAssertDirectiveType::INTRINSIC, name) { VAssertDirectiveType::INTRINSIC, name) {
addFailsp(failsp); addFailsp(failsp);
} }
string verilogKwd() const override { return "assert"; }
}; };
class AstCover final : public AstNodeCoverOrAssert { class AstCover final : public AstNodeCoverOrAssert {
// @astgen op3 := coverincsp: List[AstNode] // Coverage node // @astgen op3 := coverincsp: List[AstNode] // Coverage node
@ -1225,6 +1229,7 @@ public:
AstCover(FileLine* fl, AstNode* propp, AstNode* stmtsp, VAssertType type, AstCover(FileLine* fl, AstNode* propp, AstNode* stmtsp, VAssertType type,
const string& name = "") const string& name = "")
: ASTGEN_SUPER_Cover(fl, propp, stmtsp, type, VAssertDirectiveType::COVER, name) {} : ASTGEN_SUPER_Cover(fl, propp, stmtsp, type, VAssertDirectiveType::COVER, name) {}
string verilogKwd() const override { return "cover"; }
}; };
class AstRestrict final : public AstNodeCoverOrAssert { class AstRestrict final : public AstNodeCoverOrAssert {
public: public:
@ -1233,6 +1238,7 @@ public:
// Intrinsic asserts are always ignored thus 'type' field is set to INTERNAL. // Intrinsic asserts are always ignored thus 'type' field is set to INTERNAL.
: ASTGEN_SUPER_Restrict(fl, propp, nullptr, VAssertType::INTERNAL, : ASTGEN_SUPER_Restrict(fl, propp, nullptr, VAssertType::INTERNAL,
VAssertDirectiveType::RESTRICT) {} VAssertDirectiveType::RESTRICT) {}
string verilogKwd() const override { return "restrict"; }
}; };
// === AstNodeForeach === // === AstNodeForeach ===

View File

@ -37,7 +37,9 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst {
AstSenTree* m_sentreep = nullptr; // Domain for printing one a ALWAYS under a ACTIVE AstSenTree* m_sentreep = nullptr; // Domain for printing one a ALWAYS under a ACTIVE
bool m_suppressSemi = false; // Non-statement, don't print ; bool m_suppressSemi = false; // Non-statement, don't print ;
bool m_suppressVarSemi = false; // Suppress emitting semicolon for AstVars bool m_suppressVarSemi = false; // Suppress emitting semicolon for AstVars
bool m_suppressSampled = false; // Suppress emitting sampled in assertion properties
bool m_arrayPost = false; // Print array information that goes after identifier (vs after) bool m_arrayPost = false; // Print array information that goes after identifier (vs after)
bool m_prefixed = true; // Whether constants need to be prefixed
std::deque<AstNodeArrayDType*> m_packedps; // Packed arrays to print with BasicDType std::deque<AstNodeArrayDType*> m_packedps; // Packed arrays to print with BasicDType
std::unordered_map<AstJumpBlock*, size_t> m_labelNumbers; // Label numbers for JumpBlocks std::unordered_map<AstJumpBlock*, size_t> m_labelNumbers; // Label numbers for JumpBlocks
@ -79,14 +81,13 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst {
} }
void visit(AstPort* nodep) override {} void visit(AstPort* nodep) override {}
void visit(AstNodeFTask* nodep) override { void visit(AstNodeFTask* nodep) override {
const bool func = nodep->isFunction() || nodep->name() == "new"; putfs(nodep, nodep->verilogKwd());
putfs(nodep, func ? "function" : "task");
puts(" "); puts(" ");
puts(nodep->prettyName()); puts(nodep->prettyName());
puts(";\n"); puts(";\n");
// Only putfs the first time for each visitor; later for same node is putqs // Only putfs the first time for each visitor; later for same node is putqs
iterateAndNextConstNull(nodep->stmtsp()); iterateAndNextConstNull(nodep->stmtsp());
putfs(nodep, func ? "endfunction\n" : "endtask\n"); putqs(nodep, "end" + nodep->verilogKwd() + "\n");
} }
void visit(AstGenBlock* nodep) override { void visit(AstGenBlock* nodep) override {
@ -466,10 +467,12 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst {
puts(")"); puts(")");
} }
void visit(AstSampled* nodep) override { void visit(AstSampled* nodep) override {
if (!m_suppressSampled) {
putfs(nodep, "$sampled("); putfs(nodep, "$sampled(");
iterateAndNextConstNull(nodep->exprp()); iterateAndNextConstNull(nodep->exprp());
puts(")"); puts(")");
} }
}
void visit(AstRising* nodep) override { void visit(AstRising* nodep) override {
putfs(nodep, "$rising("); putfs(nodep, "$rising(");
iterateAndNextConstNull(nodep->exprp()); iterateAndNextConstNull(nodep->exprp());
@ -757,6 +760,47 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst {
puts(nodep->prettyName()); puts(nodep->prettyName());
puts(";\n"); puts(";\n");
} }
void visit(AstNodeCoverOrAssert* nodep) override {
if (AstPExpr* const pexprp = VN_CAST(nodep->propp(), PExpr)) {
iterateAndNextConstNull(pexprp);
}
putfs(nodep, nodep->verilogKwd() + " ");
if (nodep->type() == VAssertType::OBSERVED_DEFERRED_IMMEDIATE) {
puts("#0 ");
} else if (nodep->type() == VAssertType::FINAL_DEFERRED_IMMEDIATE) {
puts("final ");
} else if (nodep->type() == VAssertType::CONCURRENT) {
puts("property ");
}
iterateConstNull(nodep->sentreep());
puts("(");
if (const AstPExpr* const pexprp = VN_CAST(nodep->propp(), PExpr)) {
iterateAndNextConstNull(pexprp->condp());
} else {
if (AstSampled* const sampledp = VN_CAST(nodep->propp(), Sampled)) {
iterateAndNextConstNull(sampledp->exprp());
} else {
iterateAndNextConstNull(nodep->propp());
}
}
if (!VN_IS(nodep, Restrict)) {
puts(") begin\n");
iterateAndNextConstNull(nodep->passsp());
puts("end\n");
} else {
puts(");\n");
}
if (const AstAssert* const assertp = VN_CAST(nodep, Assert)) {
puts("else begin\n");
iterateAndNextConstNull(assertp->failsp());
puts("end\n");
} else if (const AstAssertIntrinsic* const assertp = VN_CAST(nodep, AssertIntrinsic)) {
puts("else begin\n");
iterateAndNextConstNull(assertp->failsp());
puts("end\n");
}
}
void visit(AstAssocArrayDType* nodep) override { void visit(AstAssocArrayDType* nodep) override {
if (!m_arrayPost) { if (!m_arrayPost) {
iterateConst(nodep->subDTypep()); iterateConst(nodep->subDTypep());
@ -934,10 +978,12 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst {
} else { } else {
putfs(nodep, nodep->prettyName()); putfs(nodep, nodep->prettyName());
} }
if (!VN_IS(nodep->taskp(), Property)) {
puts("("); puts("(");
iterateAndNextConstNull(nodep->pinsp()); iterateAndNextConstNull(nodep->pinsp());
puts(")"); puts(")");
} }
}
void visit(AstCCall* nodep) override { void visit(AstCCall* nodep) override {
puts(nodep->funcp()->name()); puts(nodep->funcp()->name());
puts("("); puts("(");
@ -949,6 +995,36 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst {
puts(nodep->verilogKwd()); puts(nodep->verilogKwd());
puts(";\n"); puts(";\n");
} }
void visit(AstPropSpec* nodep) override {
if (!VN_IS(nodep->propp(), FuncRef)) {
// Same dumping as in AstSenTree
putfs(nodep, "@(");
for (AstNode* expp = nodep->sensesp(); expp; expp = expp->nextp()) {
iterateConst(expp);
if (expp->nextp()) putqs(expp->nextp(), " or ");
}
puts(")");
}
if (nodep->disablep()) {
puts(" disable iff ");
iterateConst(nodep->disablep());
}
puts(" ");
iterateConstNull(nodep->propp());
puts("\n");
}
void visit(AstPExpr* nodep) override {
iterateAndNextConstNull(nodep->precondp()); // condp emitted by AstNodeCoverOrAssert
}
void visit(AstSExpr* nodep) override {
{
VL_RESTORER(m_suppressSemi);
m_suppressSemi = true;
iterateConstNull(nodep->delayp());
}
iterateConstNull(nodep->exprp());
}
// Terminals // Terminals
void visit(AstVarRef* nodep) override { void visit(AstVarRef* nodep) override {
@ -977,7 +1053,7 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst {
puts(nodep->prettyName()); puts(nodep->prettyName());
} }
} }
void visit(AstConst* nodep) override { putfs(nodep, nodep->num().ascii(true, true)); } void visit(AstConst* nodep) override { putfs(nodep, nodep->num().ascii(m_prefixed, true)); }
// Just iterate // Just iterate
void visit(AstTopScope* nodep) override { iterateChildrenConst(nodep); } void visit(AstTopScope* nodep) override { iterateChildrenConst(nodep); }
@ -1003,9 +1079,19 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst {
} }
void visit(AstDelay* nodep) override { void visit(AstDelay* nodep) override {
puts(""); // this is for proper alignment puts(""); // this is for proper alignment
if (nodep->isCycleDelay()) {
puts("##");
} else {
puts("#"); puts("#");
}
VL_RESTORER(m_prefixed);
m_prefixed = false;
iterateConst(nodep->lhsp()); iterateConst(nodep->lhsp());
if (!m_suppressSemi) {
puts(";\n"); puts(";\n");
} else {
puts(" ");
}
iterateAndNextConstNull(nodep->stmtsp()); iterateAndNextConstNull(nodep->stmtsp());
} }
void visit(AstCAwait* nodep) override { void visit(AstCAwait* nodep) override {

View File

@ -1551,6 +1551,13 @@ class WidthVisitor final : public VNVisitor {
if (nodep->seedp()) iterateCheckSigned32(nodep, "seed", nodep->seedp(), BOTH); if (nodep->seedp()) iterateCheckSigned32(nodep, "seed", nodep->seedp(), BOTH);
} }
} }
void visit(AstSExpr* nodep) override {
if (m_vup->prelim()) {
iterateCheckBool(nodep, "exprp", nodep->exprp(), BOTH);
iterate(nodep->delayp());
nodep->dtypeSetBit();
}
}
void visit(AstURandomRange* nodep) override { void visit(AstURandomRange* nodep) override {
if (m_vup->prelim()) { if (m_vup->prelim()) {
nodep->dtypeSetUInt32(); // Says the spec nodep->dtypeSetUInt32(); // Says the spec

View File

@ -6519,8 +6519,8 @@ pexpr<nodeExprp>: // IEEE: property_expr (The name pexpr is important as regex
// //
// // IEEE: "sequence_expr yP_ORMINUSGT pexpr" // // IEEE: "sequence_expr yP_ORMINUSGT pexpr"
// // Instead we use pexpr to prevent conflicts // // Instead we use pexpr to prevent conflicts
| ~o~pexpr yP_ORMINUSGT pexpr { $$ = new AstLogOr{$2, new AstLogNot{$2, $1}, $3}; } | ~o~pexpr yP_ORMINUSGT pexpr { $$ = new AstImplication{$2, $1, $3, true}; }
| ~o~pexpr yP_OREQGT pexpr { $$ = new AstImplication{$2, $1, $3}; } | ~o~pexpr yP_OREQGT pexpr { $$ = new AstImplication{$2, $1, $3, false}; }
// //
// // IEEE-2009: property_statement // // IEEE-2009: property_statement
// // IEEE-2012: yIF and yCASE // // IEEE-2012: yIF and yCASE
@ -6596,7 +6596,7 @@ sexpr<nodeExprp>: // ==IEEE: sequence_expr (The name sexpr is important as reg
// // IEEE: "sequence_expr cycle_delay_range sequence_expr { cycle_delay_range sequence_expr }" // // IEEE: "sequence_expr cycle_delay_range sequence_expr { cycle_delay_range sequence_expr }"
// // Both rules basically mean we can repeat sequences, so make it simpler: // // Both rules basically mean we can repeat sequences, so make it simpler:
cycle_delay_range ~p~sexpr %prec yP_POUNDPOUND cycle_delay_range ~p~sexpr %prec yP_POUNDPOUND
{ $$ = $2; BBUNSUP($2->fileline(), "Unsupported: ## (in sequence expression)"); DEL($1); } { $$ = new AstSExpr{$<fl>1, $1, $2}; }
| ~p~sexpr cycle_delay_range sexpr %prec prPOUNDPOUND_MULTI | ~p~sexpr cycle_delay_range sexpr %prec prPOUNDPOUND_MULTI
{ $$ = $1; BBUNSUP($2->fileline(), "Unsupported: ## (in sequence expression)"); DEL($2, $3); } { $$ = $1; BBUNSUP($2->fileline(), "Unsupported: ## (in sequence expression)"); DEL($2, $3); }
// //
@ -6648,16 +6648,15 @@ sexpr<nodeExprp>: // ==IEEE: sequence_expr (The name sexpr is important as reg
| BISONPRE_COPY_ONCE(expr,{s/~l~/s/g; s/~p~/s/g; s/~noPar__IGNORE~'.'/yP_PAR__IGNORE /g; }) // {copied} | BISONPRE_COPY_ONCE(expr,{s/~l~/s/g; s/~p~/s/g; s/~noPar__IGNORE~'.'/yP_PAR__IGNORE /g; }) // {copied}
; ;
cycle_delay_range<nodep>: // IEEE: ==cycle_delay_range cycle_delay_range<delayp>: // IEEE: ==cycle_delay_range
// // These three terms in 1800-2005 ONLY // // These three terms in 1800-2005 ONLY
yP_POUNDPOUND intnumAsConst yP_POUNDPOUND intnumAsConst
{ $$ = $2; { $$ = new AstDelay{$1, $2, true}; }
BBUNSUP($<fl>1, "Unsupported: ## () cycle delay range expression"); }
| yP_POUNDPOUND idAny | yP_POUNDPOUND idAny
{ $$ = new AstConst{$1, AstConst::BitFalse{}}; { $$ = new AstDelay{$1, new AstConst{$1, AstConst::BitFalse{}}, true};
BBUNSUP($<fl>1, "Unsupported: ## id cycle delay range expression"); } BBUNSUP($<fl>1, "Unsupported: ## id cycle delay range expression"); }
| yP_POUNDPOUND '(' constExpr ')' | yP_POUNDPOUND '(' constExpr ')'
{ $$ = $3; { $$ = new AstDelay{$1, new AstConst{$1, AstConst::BitFalse{}}, true};
BBUNSUP($<fl>1, "Unsupported: ## () cycle delay range expression"); } BBUNSUP($<fl>1, "Unsupported: ## () cycle delay range expression"); }
// // In 1800-2009 ONLY: // // In 1800-2009 ONLY:
// // IEEE: yP_POUNDPOUND constant_primary // // IEEE: yP_POUNDPOUND constant_primary
@ -6665,13 +6664,14 @@ cycle_delay_range<nodep>: // IEEE: ==cycle_delay_range
// // as ()'s mismatch between primary and the following statement // // as ()'s mismatch between primary and the following statement
// // the sv-ac committee has been asked to clarify (Mantis 1901) // // the sv-ac committee has been asked to clarify (Mantis 1901)
| yP_POUNDPOUND anyrange | yP_POUNDPOUND anyrange
{ $$ = new AstConst{$1, AstConst::BitFalse{}}; { $$ = new AstDelay{$1, new AstConst{$1, AstConst::BitFalse{}}, true};
BBUNSUP($<fl>1, "Unsupported: ## range cycle delay range expression"); DEL($2); } DEL($2);
BBUNSUP($<fl>1, "Unsupported: ## range cycle delay range expression"); }
| yP_POUNDPOUND yP_BRASTAR ']' | yP_POUNDPOUND yP_BRASTAR ']'
{ $$ = new AstConst{$1, AstConst::BitFalse{}}; { $$ = new AstDelay{$1, new AstConst{$1, AstConst::BitFalse{}}, true};
BBUNSUP($<fl>1, "Unsupported: ## [*] cycle delay range expression"); } BBUNSUP($<fl>1, "Unsupported: ## [*] cycle delay range expression"); }
| yP_POUNDPOUND yP_BRAPLUSKET | yP_POUNDPOUND yP_BRAPLUSKET
{ $$ = new AstConst{$1, AstConst::BitFalse{}}; { $$ = new AstDelay{$1, new AstConst{$1, AstConst::BitFalse{}}, true};
BBUNSUP($<fl>1, "Unsupported: ## [+] cycle delay range expression"); } BBUNSUP($<fl>1, "Unsupported: ## [+] cycle delay range expression"); }
; ;

View File

@ -74,7 +74,7 @@ module Vt_debug_emitv_t;
if (the_ifaces[2].ifsig) begin if (the_ifaces[2].ifsig) begin
$write(""); $write("");
end end
#64'h1; #1;
$write("After #1 delay"); $write("After #1 delay");
end end
end end
@ -359,6 +359,311 @@ module Vt_debug_emitv_t;
release sum; release sum;
end end
end end
property p;
@(posedge clk) ##1 sum[0]
endproperty
property p1;
@( clk) sum[0]
endproperty
property p2;
@(posedge clk) disable iff (cyc == 'sh1) ##1 sum[0]
endproperty
assert property (@( clk) (! ##1 in)
) begin
end
else begin
end
initial begin
begin
begin : assert_simple_immediate_else
assert ('sh0) begin
end
else begin
$display("fail");
end
end
begin : assert_simple_immediate_stmt
assert ('sh0) begin
$display("pass");
end
else begin
end
end
begin : assert_simple_immediate_stmt_else
assert ('sh0) begin
$display("pass");
end
else begin
$display("fail");
end
end
begin : assume_simple_immediate
assume ('sh0) begin
end
else begin
end
end
begin : assume_simple_immediate_else
assume ('sh0) begin
end
else begin
$display("fail");
end
end
begin : assume_simple_immediate_stmt
assume ('sh0) begin
$display("pass");
end
else begin
end
end
begin : assume_simple_immediate_stmt_else
assume ('sh0) begin
$display("pass");
end
else begin
$display("fail");
end
end
end
end
always begin
begin : assert_observed_deferred_immediate
assert #0 ('sh0) begin
end
else begin
end
end
end
always begin
begin : assert_observed_deferred_immediate_else
assert #0 ('sh0) begin
end
else begin
$display("fail");
end
end
end
always begin
begin : assert_observed_deferred_immediate_stmt
assert #0 ('sh0) begin
$display("pass");
end
else begin
end
end
end
always begin
begin : assert_observed_deferred_immediate_stmt_else
assert #0 ('sh0) begin
$display("pass");
end
else begin
$display("fail");
end
end
end
always begin
begin : assume_observed_deferred_immediate
assume #0 ('sh0) begin
end
else begin
end
end
end
always begin
begin : assume_observed_deferred_immediate_else
assume #0 ('sh0) begin
end
else begin
$display("fail");
end
end
end
always begin
begin : assume_observed_deferred_immediate_stmt
assume #0 ('sh0) begin
$display("pass");
end
else begin
end
end
end
always begin
begin : assume_observed_deferred_immediate_stmt_else
assume #0 ('sh0) begin
$display("pass");
end
else begin
$display("fail");
end
end
end
always begin
begin : assert_final_deferred_immediate
assert final ('sh0) begin
end
else begin
end
end
end
always begin
begin : assert_final_deferred_immediate_else
assert final ('sh0) begin
end
else begin
$display("fail");
end
end
end
always begin
begin : assert_final_deferred_immediate_stmt
assert final ('sh0) begin
$display("pass");
end
else begin
end
end
end
always begin
begin : assert_final_deferred_immediate_stmt_else
assert final ('sh0) begin
$display("pass");
end
else begin
$display("fail");
end
end
end
always begin
begin : assume_final_deferred_immediate
assume final ('sh0) begin
end
else begin
end
end
end
always begin
begin : assume_final_deferred_immediate_else
assume final ('sh0) begin
end
else begin
$display("fail");
end
end
end
always begin
begin : assume_final_deferred_immediate_stmt
assume final ('sh0) begin
$display("pass");
end
else begin
end
end
end
always begin
begin : assume_final_deferred_immediate_stmt_else
assume final ('sh0) begin
$display("pass");
end
else begin
$display("fail");
end
end
end
property prop;
@(posedge clk) 'sh0
endproperty
begin : assert_concurrent
assert property ( prop
) begin
end
else begin
end
end
begin : assert_concurrent_else
assert property ( prop
) begin
end
else begin
$display("fail");
end
end
begin : assert_concurrent_stmt
assert property ( prop
) begin
$display("pass");
end
else begin
end
end
begin : assert_concurrent_stmt_else
assert property ( prop
) begin
$display("pass");
end
else begin
$display("fail");
end
end
begin : assume_concurrent
assume property ( prop
) begin
end
else begin
end
end
begin : assume_concurrent_else
assume property ( prop
) begin
end
else begin
$display("fail");
end
end
begin : assume_concurrent_stmt
assume property ( prop
) begin
$display("pass");
end
else begin
end
end
begin : assume_concurrent_stmt_else
assume property ( prop
) begin
$display("pass");
end
else begin
$display("fail");
end
end
begin : cover_concurrent
cover property ( prop
) begin
end
end
begin : cover_concurrent_stmt
cover property ( prop
) begin
$display("pass");
end
end
int signed a;
int signed ao;
initial begin
begin : assert_intrinsic
assert ((| $_EXPRSTMT(
ao = (a);
, );
)) begin
end
else begin
end
end
end
restrict (@(posedge clk) ##1 a[0]
);
endmodule endmodule
package Vt_debug_emitv___024unit; package Vt_debug_emitv___024unit;
class Vt_debug_emitv_Cls; class Vt_debug_emitv_Cls;

View File

@ -269,6 +269,77 @@ module t (/*AUTOARG*/
repeat (2) if (sum != 10) $stop; repeat (2) if (sum != 10) $stop;
release sum; release sum;
end end
property p;
@(posedge clk) ##1 sum[0]
endproperty
property p1;
@(clk) sum[0]
endproperty
property p2;
@(posedge clk) disable iff (cyc == 1) ##1 sum[0]
endproperty
assert property (@(clk) not ##1 in);
initial begin
assert_simple_immediate_else: assert(0) else $display("fail");
assert_simple_immediate_stmt: assert(0) $display("pass");
assert_simple_immediate_stmt_else: assert(0) $display("pass"); else $display("fail");
assume_simple_immediate: assume(0);
assume_simple_immediate_else: assume(0) else $display("fail");
assume_simple_immediate_stmt: assume(0) $display("pass");
assume_simple_immediate_stmt_else: assume(0) $display("pass"); else $display("fail");
end
assert_observed_deferred_immediate: assert #0 (0);
assert_observed_deferred_immediate_else: assert #0 (0) else $display("fail");
assert_observed_deferred_immediate_stmt: assert #0 (0) $display("pass");
assert_observed_deferred_immediate_stmt_else: assert #0 (0) $display("pass"); else $display("fail");
assume_observed_deferred_immediate: assume #0 (0);
assume_observed_deferred_immediate_else: assume #0 (0) else $display("fail");
assume_observed_deferred_immediate_stmt: assume #0 (0) $display("pass");
assume_observed_deferred_immediate_stmt_else: assume #0 (0) $display("pass"); else $display("fail");
assert_final_deferred_immediate: assert final (0);
assert_final_deferred_immediate_else: assert final (0) else $display("fail");
assert_final_deferred_immediate_stmt: assert final (0) $display("pass");
assert_final_deferred_immediate_stmt_else: assert final (0) $display("pass"); else $display("fail");
assume_final_deferred_immediate: assume final (0);
assume_final_deferred_immediate_else: assume final (0) else $display("fail");
assume_final_deferred_immediate_stmt: assume final (0) $display("pass");
assume_final_deferred_immediate_stmt_else: assume final (0) $display("pass"); else $display("fail");
property prop();
@(posedge clk) 0
endproperty
assert_concurrent: assert property (prop);
assert_concurrent_else: assert property(prop) else $display("fail");
assert_concurrent_stmt: assert property(prop) $display("pass");
assert_concurrent_stmt_else: assert property(prop) $display("pass"); else $display("fail");
assume_concurrent: assume property(prop);
assume_concurrent_else: assume property(prop) else $display("fail");
assume_concurrent_stmt: assume property(prop) $display("pass");
assume_concurrent_stmt_else: assume property(prop) $display("pass"); else $display("fail");
cover_concurrent: cover property(prop);
cover_concurrent_stmt: cover property(prop) $display("pass");
int a;
int ao;
// verilator lint_off CASTCONST
initial begin : assert_intrinsic
$cast(ao, a);
end
restrict property (@(posedge clk) ##1 a[0]);
endmodule endmodule
module sub(input logic clk); module sub(input logic clk);

View File

@ -44,6 +44,7 @@ EXEMPT_FILES_LIST = """
test_regress/t/t_fuzz_eof_bad.v test_regress/t/t_fuzz_eof_bad.v
test_regress/t/t_incr_void.v test_regress/t/t_incr_void.v
test_regress/t/t_property_unsup.v test_regress/t/t_property_unsup.v
test_regress/t/t_sequence_first_match_unsup.v
test_regress/t/tsub/t_flag_f_tsub.v test_regress/t/tsub/t_flag_f_tsub.v
test_regress/t/tsub/t_flag_f_tsub_inc.v test_regress/t/tsub/t_flag_f_tsub_inc.v
test_regress/t/uvm/dpi test_regress/t/uvm/dpi

View File

@ -1,28 +1,19 @@
%Error-UNSUPPORTED: t/t_expect.v:19:32: Unsupported: ## () cycle delay range expression %Error-UNSUPPORTED: t/t_expect.v:19:32: Unsupported: ## (in sequence expression)
19 | expect (@(posedge clk) a ##1 b) a = 110; 19 | expect (@(posedge clk) a ##1 b) a = 110;
| ^~ | ^~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error-UNSUPPORTED: t/t_expect.v:19:34: Unsupported: ## (in sequence expression)
19 | expect (@(posedge clk) a ##1 b) a = 110;
| ^
%Error-UNSUPPORTED: t/t_expect.v:19:7: Unsupported: expect %Error-UNSUPPORTED: t/t_expect.v:19:7: Unsupported: expect
19 | expect (@(posedge clk) a ##1 b) a = 110; 19 | expect (@(posedge clk) a ##1 b) a = 110;
| ^~~~~~ | ^~~~~~
%Error-UNSUPPORTED: t/t_expect.v:21:32: Unsupported: ## () cycle delay range expression %Error-UNSUPPORTED: t/t_expect.v:21:32: Unsupported: ## (in sequence expression)
21 | expect (@(posedge clk) a ##1 b) else a = 299; 21 | expect (@(posedge clk) a ##1 b) else a = 299;
| ^~ | ^~
%Error-UNSUPPORTED: t/t_expect.v:21:34: Unsupported: ## (in sequence expression)
21 | expect (@(posedge clk) a ##1 b) else a = 299;
| ^
%Error-UNSUPPORTED: t/t_expect.v:21:7: Unsupported: expect %Error-UNSUPPORTED: t/t_expect.v:21:7: Unsupported: expect
21 | expect (@(posedge clk) a ##1 b) else a = 299; 21 | expect (@(posedge clk) a ##1 b) else a = 299;
| ^~~~~~ | ^~~~~~
%Error-UNSUPPORTED: t/t_expect.v:23:32: Unsupported: ## () cycle delay range expression %Error-UNSUPPORTED: t/t_expect.v:23:32: Unsupported: ## (in sequence expression)
23 | expect (@(posedge clk) a ##1 b) a = 300; else a = 399; 23 | expect (@(posedge clk) a ##1 b) a = 300; else a = 399;
| ^~ | ^~
%Error-UNSUPPORTED: t/t_expect.v:23:34: Unsupported: ## (in sequence expression)
23 | expect (@(posedge clk) a ##1 b) a = 300; else a = 399;
| ^
%Error-UNSUPPORTED: t/t_expect.v:23:7: Unsupported: expect %Error-UNSUPPORTED: t/t_expect.v:23:7: Unsupported: expect
23 | expect (@(posedge clk) a ##1 b) a = 300; else a = 399; 23 | expect (@(posedge clk) a ##1 b) a = 300; else a = 399;
| ^~~~~~ | ^~~~~~

View File

@ -0,0 +1,140 @@
[4] single delay with const stmt, fileline:115
[5] concurrent assert else, fileline:167
[6] single delay with const stmt, fileline:115
[7] concurrent assert stmt, fileline:166
[8] single delay with const stmt, fileline:115
[9] concurrent assert else, fileline:167
[11] concurrent assert else, fileline:167
[12] single delay with var stmt, fileline:118
[13] concurrent assert else, fileline:167
[14] single delay with var else, fileline:119
[15] concurrent assert stmt, fileline:166
[16] single delay with var stmt, fileline:118
[17] concurrent assert else, fileline:167
[18] single delay with var else, fileline:119
[19] concurrent assert else, fileline:167
[20] single delay with var stmt, fileline:118
[21] concurrent assert else, fileline:167
[23] concurrent assert stmt, fileline:166
[25] concurrent assert else, fileline:167
[26] single multi-cycle delay with var else, fileline:123
[27] concurrent assert else, fileline:167
[28] single multi-cycle delay with var stmt, fileline:122
[29] concurrent assert else, fileline:167
[30] single multi-cycle delay with var else, fileline:123
[31] concurrent assert stmt, fileline:166
[33] concurrent assert else, fileline:167
[34] single delay with var brackets 1 else, fileline:127
[35] concurrent assert else, fileline:167
[36] single delay with var brackets 1 stmt, fileline:126
[37] concurrent assert else, fileline:167
[38] single delay with var brackets 1 else, fileline:127
[39] concurrent assert stmt, fileline:166
[40] single delay with var brackets 1 stmt, fileline:126
[41] concurrent assert else, fileline:167
[43] concurrent assert else, fileline:167
[44] single delay with var brackets 2 stmt, fileline:130
[45] concurrent assert else, fileline:167
[46] single delay with var brackets 2 else, fileline:131
[47] concurrent assert stmt, fileline:166
[48] single delay with var brackets 2 stmt, fileline:130
[49] concurrent assert else, fileline:167
[50] single delay with var brackets 2 else, fileline:131
[51] concurrent assert else, fileline:167
[53] concurrent assert else, fileline:167
[54] single delay with negated var else, fileline:135
[55] concurrent assert stmt, fileline:166
[56] single delay with negated var stmt, fileline:134
[57] concurrent assert else, fileline:167
[58] single delay with negated var else, fileline:135
[59] concurrent assert else, fileline:167
[60] single delay with negated var else, fileline:135
[61] concurrent assert else, fileline:167
[63] concurrent assert stmt, fileline:166
[64] single delay with negated var else, fileline:139
[65] concurrent assert else, fileline:167
[66] single delay with negated var stmt, fileline:138
[67] concurrent assert else, fileline:167
[68] single delay with negated var else, fileline:139
[69] concurrent assert else, fileline:167
[70] single delay with negated var stmt, fileline:138
[71] concurrent assert stmt, fileline:166
[73] concurrent assert else, fileline:167
[74] single delay with negated var brackets stmt, fileline:142
[75] concurrent assert else, fileline:167
[76] single delay with negated var brackets else, fileline:144
[77] concurrent assert else, fileline:167
[78] single delay with negated var brackets stmt, fileline:142
[79] concurrent assert stmt, fileline:166
[80] single delay with negated var brackets else, fileline:144
[81] concurrent assert else, fileline:167
[83] concurrent assert else, fileline:167
[84] single delay with negated var brackets else, fileline:148
[85] concurrent assert else, fileline:167
[87] concurrent assert stmt, fileline:166
[88] single delay with negated var brackets else, fileline:148
[89] concurrent assert else, fileline:167
[91] concurrent assert else, fileline:167
[93] concurrent assert else, fileline:167
[94] single delay with nested not else, fileline:152
[95] concurrent assert stmt, fileline:166
[96] single delay with nested not stmt, fileline:151
[97] concurrent assert else, fileline:167
[98] single delay with nested not else, fileline:152
[99] concurrent assert else, fileline:167
[100] single delay with nested not stmt, fileline:151
[101] concurrent assert else, fileline:167
[103] concurrent assert stmt, fileline:166
[105] concurrent assert else, fileline:167
[107] concurrent assert else, fileline:167
[109] concurrent assert else, fileline:167
[111] concurrent assert stmt, fileline:166
[113] concurrent assert else, fileline:167
[114] property, fileline:162
[115] concurrent assert else, fileline:167
[116] property, fileline:163
[117] concurrent assert else, fileline:167
[118] property, fileline:162
[119] concurrent assert stmt, fileline:166
[120] property, fileline:163
[121] concurrent assert else, fileline:167
[123] concurrent assert else, fileline:167
[125] concurrent assert else, fileline:167
[127] concurrent assert stmt, fileline:166
[129] concurrent assert else, fileline:167
[131] concurrent assert else, fileline:167
[133] concurrent assert else, fileline:167
[135] concurrent assert stmt, fileline:166
[137] concurrent assert else, fileline:167
[139] concurrent assert else, fileline:167
[141] concurrent assert else, fileline:167
[143] concurrent assert stmt, fileline:166
[145] concurrent assert else, fileline:167
[147] concurrent assert else, fileline:167
[149] concurrent assert else, fileline:167
[151] concurrent assert stmt, fileline:166
[153] concurrent assert else, fileline:167
[155] concurrent assert else, fileline:167
[157] concurrent assert else, fileline:167
[159] concurrent assert stmt, fileline:166
[161] concurrent assert else, fileline:167
[163] concurrent assert else, fileline:167
[165] concurrent assert else, fileline:167
[167] concurrent assert stmt, fileline:166
[169] concurrent assert else, fileline:167
[171] concurrent assert else, fileline:167
[173] concurrent assert else, fileline:167
[175] concurrent assert stmt, fileline:166
[177] concurrent assert else, fileline:167
[179] concurrent assert else, fileline:167
[181] concurrent assert else, fileline:167
[183] concurrent assert stmt, fileline:166
[185] concurrent assert else, fileline:167
[187] concurrent assert else, fileline:167
[189] concurrent assert else, fileline:167
[191] concurrent assert stmt, fileline:166
[193] concurrent assert else, fileline:167
[195] concurrent assert else, fileline:167
[197] concurrent assert else, fileline:167
[199] concurrent assert stmt, fileline:166
*-* All Finished *-*

View File

@ -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(timing_loop=True, verilator_flags2=['--assert', '--timing'])
test.execute(expect_filename=test.golden_filename)
test.passes()

View File

@ -0,0 +1,168 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
module t ( /*AUTOARG*/
// Inputs
clk
);
input clk;
bit [3:0] val = 0;
event e1;
event e2;
event e3;
event e4;
event e5;
event e6;
event e7;
event e8;
event e9;
event e10;
event e11;
event e12;
integer cyc = 1;
always @(negedge clk) begin
val <= 4'(cyc % 4);
if (cyc >= 0 && cyc <= 4) begin
->e1;
`ifdef TEST_VERBOSE
$display("[%0t] triggered e1", $time);
`endif
end
if (cyc >= 5 && cyc <= 10) begin
->e2;
`ifdef TEST_VERBOSE
$display("[%0t] triggered e2", $time);
`endif
end
if (cyc >= 11 && cyc <= 15) begin
->e3;
`ifdef TEST_VERBOSE
$display("[%0t] triggered e3", $time);
`endif
end
if (cyc >= 16 && cyc <= 20) begin
->e4;
`ifdef TEST_VERBOSE
$display("[%0t] triggered e4", $time);
`endif
end
if (cyc >= 21 && cyc <= 25) begin
->e5;
`ifdef TEST_VERBOSE
$display("[%0t] triggered e5", $time);
`endif
end
if (cyc >= 26 && cyc <= 30) begin
->e6;
`ifdef TEST_VERBOSE
$display("[%0t] triggered e6", $time);
`endif
end
if (cyc >= 31 && cyc <= 35) begin
->e7;
`ifdef TEST_VERBOSE
$display("[%0t] triggered e7", $time);
`endif
end
if (cyc >= 36 && cyc <= 40) begin
->e8;
`ifdef TEST_VERBOSE
$display("[%0t] triggered e8", $time);
`endif
end
if (cyc >= 41 && cyc <= 45) begin
->e9;
`ifdef TEST_VERBOSE
$display("[%0t] triggered e9", $time);
`endif
end
if (cyc >= 46 && cyc <= 50) begin
->e10;
`ifdef TEST_VERBOSE
$display("[%0t] triggered e10", $time);
`endif
end
if (cyc >= 51 && cyc <= 55) begin
->e11;
`ifdef TEST_VERBOSE
$display("[%0t] triggered e11", $time);
`endif
end
if (cyc >= 56 && cyc <= 60) begin
->e12;
`ifdef TEST_VERBOSE
$display("[%0t] triggered e12", $time);
`endif
end
`ifdef TEST_VERBOSE
$display("cyc=%0d val=%0d", cyc, val);
`endif
cyc <= cyc + 1;
if (cyc == 100) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
assert property (@(e1) ##1 1)
$display("[%0t] single delay with const stmt, fileline:%0d", $time, `__LINE__);
assert property (@(e2) ##1 val[0])
$display("[%0t] single delay with var stmt, fileline:%0d", $time, `__LINE__);
else $display("[%0t] single delay with var else, fileline:%0d", $time, `__LINE__);
assert property (@(e3) ##2 val[0])
$display("[%0t] single multi-cycle delay with var stmt, fileline:%0d", $time, `__LINE__);
else $display("[%0t] single multi-cycle delay with var else, fileline:%0d", $time, `__LINE__);
assert property (@(e4) ##1 (val[0]))
$display("[%0t] single delay with var brackets 1 stmt, fileline:%0d", $time, `__LINE__);
else $display("[%0t] single delay with var brackets 1 else, fileline:%0d", $time, `__LINE__);
assert property (@(e5) (##1 (val[0])))
$display("[%0t] single delay with var brackets 2 stmt, fileline:%0d", $time, `__LINE__);
else $display("[%0t] single delay with var brackets 2 else, fileline:%0d", $time, `__LINE__);
assert property (@(e6) (##1 val[0] && val[1]))
$display("[%0t] single delay with negated var stmt, fileline:%0d", $time, `__LINE__);
else $display("[%0t] single delay with negated var else, fileline:%0d", $time, `__LINE__);
assert property (@(e7) not ##1 val[0])
$display("[%0t] single delay with negated var stmt, fileline:%0d", $time, `__LINE__);
else $display("[%0t] single delay with negated var else, fileline:%0d", $time, `__LINE__);
assume property (@(e8) not (##1 val[0]))
$display("[%0t] single delay with negated var brackets stmt, fileline:%0d", $time, `__LINE__);
else
$display("[%0t] single delay with negated var brackets else, fileline:%0d", $time, `__LINE__);
assume property (@(e9) not (##1 val[0]))
else
$display("[%0t] single delay with negated var brackets else, fileline:%0d", $time, `__LINE__);
assert property (@(e10) not (not ##1 val[0]))
$display("[%0t] single delay with nested not stmt, fileline:%0d", $time, `__LINE__);
else $display("[%0t] single delay with nested not else, fileline:%0d", $time, `__LINE__);
restrict property (@(e11) ##1 val[0]);
restrict property (@(e11) not ##1 val[0]);
property prop;
@(e12) not ##1 val[0]
endproperty
assert property (prop) $display("[%0t] property, fileline:%0d", $time, `__LINE__);
else $display("[%0t] property, fileline:%0d", $time, `__LINE__);
assert property (@(posedge clk) not (not ##2 val[0] && val[1]))
$display("[%0t] concurrent assert stmt, fileline:%0d", $time, `__LINE__);
else $display("[%0t] concurrent assert else, fileline:%0d", $time, `__LINE__);
endmodule

View File

@ -0,0 +1,6 @@
%Error: t/t_property_sexpr_bad.v:20:39: Syntax error: unexpected 'not' in sequence expression
: ... note: In instance 't'
20 | assert property (@(posedge clk) ##1 not val) $display("[%0t] single delay with negated var stmt, fileline:%d", $time, 20);
| ^~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: Exiting due to

View File

@ -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('vlt')
test.lint(fails=True,
verilator_flags2=['--assert', '--timing'],
expect_filename=test.golden_filename)
test.passes()

View File

@ -0,0 +1,21 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
module t ( /*AUTOARG*/
// Inputs
clk
);
input clk;
bit val;
always @(negedge clk) begin
$write("*-* All Finished *-*\n");
$finish;
end
assert property (@(posedge clk) ##1 not val) $display("[%0t] single delay with negated var stmt, fileline:%d", $time, `__LINE__);
endmodule

View File

@ -0,0 +1,31 @@
[4] cover property, fileline:45
[7] concurrent cover, fileline:51
[8] cover property, fileline:45
[12] not cover property, fileline:48
[15] concurrent cover, fileline:51
[18] not cover property, fileline:48
[20] not cover property, fileline:48
[23] concurrent cover, fileline:51
[31] concurrent cover, fileline:51
[39] concurrent cover, fileline:51
[47] concurrent cover, fileline:51
[55] concurrent cover, fileline:51
[63] concurrent cover, fileline:51
[71] concurrent cover, fileline:51
[79] concurrent cover, fileline:51
[87] concurrent cover, fileline:51
[95] concurrent cover, fileline:51
[103] concurrent cover, fileline:51
[111] concurrent cover, fileline:51
[119] concurrent cover, fileline:51
[127] concurrent cover, fileline:51
[135] concurrent cover, fileline:51
[143] concurrent cover, fileline:51
[151] concurrent cover, fileline:51
[159] concurrent cover, fileline:51
[167] concurrent cover, fileline:51
[175] concurrent cover, fileline:51
[183] concurrent cover, fileline:51
[191] concurrent cover, fileline:51
[199] concurrent cover, fileline:51
*-* All Finished *-*

View File

@ -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(timing_loop=True, verilator_flags2=['--assert', '--timing', '--coverage-user'])
test.execute(expect_filename=test.golden_filename)
test.passes()

View File

@ -0,0 +1,52 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
module t ( /*AUTOARG*/
// Inputs
clk
);
input clk;
bit [3:0] val = 0;
event e1;
event e2;
integer cyc = 1;
always @(negedge clk) begin
val <= 4'(cyc % 4);
if (cyc >= 0 && cyc <= 4) begin
->e1;
`ifdef TEST_VERBOSE
$display("[%0t] triggered e1", $time);
`endif
end
if (cyc >= 5 && cyc <= 10) begin
->e2;
`ifdef TEST_VERBOSE
$display("[%0t] triggered e2", $time);
`endif
end
`ifdef TEST_VERBOSE
$display("cyc=%0d val=%0d", cyc, val);
`endif
cyc <= cyc + 1;
if (cyc == 100) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
cover property (@(e1) ##1 val[0])
$display("[%0t] cover property, fileline:%0d", $time, `__LINE__);
cover property (@(e2) not ##1 val[1])
$display("[%0t] not cover property, fileline:%0d", $time, `__LINE__);
cover property (@(posedge clk) ##3 val[0] && val[1])
$display("[%0t] concurrent cover, fileline:%0d", $time, `__LINE__);
endmodule

View File

@ -0,0 +1,35 @@
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:29:39: Unsupported: ## (in sequence expression)
29 | assert property (@(posedge clk) val ##1 val) $display("[%0t] var with single delay stmt, fileline:%d", $time, 29);
| ^~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:30:43: Unsupported: ## (in sequence expression)
30 | assert property (@(posedge clk) ##1 val ##2 val) $display("[%0t] sequence stmt, fileline:%d", $time, 30);
| ^~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:71:14: Unsupported sequence match items
71 | ($rose(a), l_b = b) |-> ##[3:10] q[l_b];
| ^
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:71:29: Unsupported: ## range cycle delay range expression
71 | ($rose(a), l_b = b) |-> ##[3:10] q[l_b];
| ^~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:70:13: Unsupported: property variable declaration
70 | integer l_b;
| ^~~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:88:16: Unsupported sequence match items
88 | (count == 0, l_t = $realtime) ##1 (count == 7)[->1] |-> $realtime - l_t < 50.5;
| ^
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:88:51: Unsupported: [-> boolean abbrev expression
88 | (count == 0, l_t = $realtime) ##1 (count == 7)[->1] |-> $realtime - l_t < 50.5;
| ^~~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:88:54: Unsupported: boolean abbrev (in sequence expression)
88 | (count == 0, l_t = $realtime) ##1 (count == 7)[->1] |-> $realtime - l_t < 50.5;
| ^
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:88:35: Unsupported: ## (in sequence expression)
88 | (count == 0, l_t = $realtime) ##1 (count == 7)[->1] |-> $realtime - l_t < 50.5;
| ^~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:86:14: Unsupported: property variable declaration
86 | realtime l_t;
| ^~~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:92:31: Unsupported: ## (in sequence expression)
92 | assert property (@clk not a ##1 b);
| ^~
%Error: Exiting due to

View File

@ -0,0 +1,20 @@
#!/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('vlt')
test.top_filename = "t/t_property_sexpr_unsup.v"
test.lint(expect_filename=test.golden_filename,
verilator_flags2=['-DPARSING_TIME', '--assert', '--timing', '--error-limit 1000'],
fails=True)
test.passes()

View File

@ -1,122 +1,35 @@
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:46:35: Unsupported: ## () cycle delay range expression %Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:32:41: Unsupported: Implication with sequence expression
46 | assert property (@(posedge clk) ##2 val) 32 | assert property (@(posedge clk) ##1 1 |-> 1) $display("[%0t] single delay with const implication stmt, fileline:%d", $time, 32);
| ^~ | ^~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:46:39: Unsupported: ## (in sequence expression) %Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:34:41: Unsupported: Implication with sequence expression
46 | assert property (@(posedge clk) ##2 val) 34 | assert property (@(posedge clk) ##1 1 |-> not (val)) $display("[%0t] single delay implication with negated var stmt, fileline:%d", $time, 34);
| ^~~ | ^~~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:49:35: Unsupported: ## () cycle delay range expression %Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:36:37: Unsupported: Implication with sequence expression
49 | assert property (@(posedge clk) ##1 1 |=> 0) 36 | assert property (@(posedge clk) 1 |-> ##1 val) $display("[%0t] single delay implication with negated var stmt, fileline:%d", $time, 36);
| ^~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:49:39: Unsupported: ## (in sequence expression)
49 | assert property (@(posedge clk) ##1 1 |=> 0)
| ^
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:52:35: Unsupported: ## () cycle delay range expression
52 | assert property (@(posedge clk) ##1 1 |=> not (val))
| ^~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:52:39: Unsupported: ## (in sequence expression)
52 | assert property (@(posedge clk) ##1 1 |=> not (val))
| ^
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:55:35: Unsupported: ## () cycle delay range expression
55 | assert property (@(posedge clk) ##1 val)
| ^~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:55:39: Unsupported: ## (in sequence expression)
55 | assert property (@(posedge clk) ##1 val)
| ^~~ | ^~~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:58:35: Unsupported: ## () cycle delay range expression %Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:38:45: Unsupported: Implication with sequence expression
58 | assert property (@(posedge clk) ##1 (val)) 38 | assert property (@(posedge clk) (##1 val) |-> (not val)) $display("[%0t] single delay with negated implication stmt, fileline:%d", $time, 38);
| ^~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:58:40: Unsupported: ## (in sequence expression)
58 | assert property (@(posedge clk) ##1 (val))
| ^~~ | ^~~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:61:36: Unsupported: ## () cycle delay range expression %Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:40:45: Unsupported: Implication with sequence expression
61 | assert property (@(posedge clk) (##1 (val))) 40 | assert property (@(posedge clk) ##1 (val) |-> not (val)) $display("[%0t] single delay with negated implication brackets stmt, fileline:%d", $time, 40);
| ^~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:61:41: Unsupported: ## (in sequence expression)
61 | assert property (@(posedge clk) (##1 (val)))
| ^~~ | ^~~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:64:36: Unsupported: ## () cycle delay range expression %Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:44:41: Unsupported: Implication with sequence expression
64 | assert property (@(posedge clk) (##1 (val))) 44 | assert property (@(posedge clk) ##1 1 |-> 0) $display("[%0t] disable iff with cond implication stmt, fileline:%d", $time, 44);
| ^~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:64:41: Unsupported: ## (in sequence expression)
64 | assert property (@(posedge clk) (##1 (val)))
| ^~~ | ^~~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:67:40: Unsupported: ## () cycle delay range expression %Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:46:45: Unsupported: Implication with sequence expression
67 | assert property (@(posedge clk) not (##1 val)) 46 | assert property (@(posedge clk) (##1 val) |-> (##1 val)) $display("[%0t] two delays implication stmt, fileline:%d", $time, 46);
| ^~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:67:44: Unsupported: ## (in sequence expression)
67 | assert property (@(posedge clk) not (##1 val))
| ^~~ | ^~~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:70:35: Unsupported: ## () cycle delay range expression %Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:48:52: Unsupported: Disable iff with sequence expression
70 | assert property (@(posedge clk) ##1 1 |=> 1) : ... note: In instance 't'
48 | assert property (@(posedge clk) disable iff (cyc != 5) ##1 0) $display("[%0t] disable iff stmt, fileline:%d", $time, 48);
| ^~ | ^~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:70:39: Unsupported: ## (in sequence expression) %Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:50:52: Unsupported: Disable iff with sequence expression
70 | assert property (@(posedge clk) ##1 1 |=> 1) : ... note: In instance 't'
| ^ 50 | assume property (@(posedge clk) disable iff (cyc != 5) ##1 0) $display("[%0t] disable iff stmt, fileline:%d", $time, 50);
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:73:35: Unsupported: ## () cycle delay range expression
73 | assert property (@(posedge clk) ##1 val |=> not val)
| ^~ | ^~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:73:39: Unsupported: ## (in sequence expression) %Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:52:51: Unsupported: Disable iff with sequence expression
73 | assert property (@(posedge clk) ##1 val |=> not val) : ... note: In instance 't'
| ^~~ 52 | cover property (@(posedge clk) disable iff (cyc != 5) ##1 0) $display("[%0t] disable iff stmt, fileline:%d", $time, 52);
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:76:35: Unsupported: ## () cycle delay range expression
76 | assert property (@(posedge clk) ##1 (val) |=> not (val))
| ^~ | ^~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:76:40: Unsupported: ## (in sequence expression)
76 | assert property (@(posedge clk) ##1 (val) |=> not (val))
| ^~~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:82:57: Unsupported: ## () cycle delay range expression
82 | assert property (@(posedge clk) disable iff (cyc < 3) ##1 1 |=> cyc > 3)
| ^~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:82:61: Unsupported: ## (in sequence expression)
82 | assert property (@(posedge clk) disable iff (cyc < 3) ##1 1 |=> cyc > 3)
| ^
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:85:36: Unsupported: ## () cycle delay range expression
85 | assert property (@(posedge clk) (##1 val) |=> (##1 val))
| ^~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:85:40: Unsupported: ## (in sequence expression)
85 | assert property (@(posedge clk) (##1 val) |=> (##1 val))
| ^~~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:85:50: Unsupported: ## () cycle delay range expression
85 | assert property (@(posedge clk) (##1 val) |=> (##1 val))
| ^~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:85:54: Unsupported: ## (in sequence expression)
85 | assert property (@(posedge clk) (##1 val) |=> (##1 val))
| ^~~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:103:14: Unsupported sequence match items
103 | ($rose(a), l_b = b) |-> ##[3:10] q[l_b];
| ^
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:103:29: Unsupported: ## range cycle delay range expression
103 | ($rose(a), l_b = b) |-> ##[3:10] q[l_b];
| ^~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:103:39: Unsupported: ## (in sequence expression)
103 | ($rose(a), l_b = b) |-> ##[3:10] q[l_b];
| ^
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:102:13: Unsupported: property variable declaration
102 | integer l_b;
| ^~~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:120:16: Unsupported sequence match items
120 | (count == 0, l_t = $realtime) ##1 (count == 7)[->1] |-> $realtime - l_t < 50.5;
| ^
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:120:35: Unsupported: ## () cycle delay range expression
120 | (count == 0, l_t = $realtime) ##1 (count == 7)[->1] |-> $realtime - l_t < 50.5;
| ^~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:120:51: Unsupported: [-> boolean abbrev expression
120 | (count == 0, l_t = $realtime) ##1 (count == 7)[->1] |-> $realtime - l_t < 50.5;
| ^~~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:120:54: Unsupported: boolean abbrev (in sequence expression)
120 | (count == 0, l_t = $realtime) ##1 (count == 7)[->1] |-> $realtime - l_t < 50.5;
| ^
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:120:37: Unsupported: ## (in sequence expression)
120 | (count == 0, l_t = $realtime) ##1 (count == 7)[->1] |-> $realtime - l_t < 50.5;
| ^
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:118:14: Unsupported: property variable declaration
118 | realtime l_t;
| ^~~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:124:31: Unsupported: ## () cycle delay range expression
124 | assert property (@clk not a ##1 b);
| ^~
%Error-UNSUPPORTED: t/t_property_sexpr_unsup.v:124:33: Unsupported: ## (in sequence expression)
124 | assert property (@clk not a ##1 b);
| ^
%Error: Exiting due to %Error: Exiting due to

View File

@ -13,77 +13,44 @@ module t ( /*AUTOARG*/
integer cyc = 1; integer cyc = 1;
bit val = 0; bit val = 0;
Test test ( /*AUTOINST*/
// Inputs
.clk(clk),
.val(val),
.cyc(cyc)
);
Ieee ieee(); Ieee ieee();
always @(posedge clk) begin always @(posedge clk) begin
if (cyc != 0) begin if (cyc != 0) begin
cyc <= cyc + 1; cyc <= cyc + 1;
val = ~val; val = ~val;
`ifdef TEST_VERBOSE
$display("cyc=%0d, val=%0d", cyc, val);
`endif
if (cyc == 10) begin if (cyc == 10) begin
$write("*-* All Finished *-*\n"); $write("*-* All Finished *-*\n");
$finish; $finish;
end end
end end
end end
endmodule `ifdef PARSING_TIME
assert property (@(posedge clk) val ##1 val) $display("[%0t] var with single delay stmt, fileline:%d", $time, `__LINE__);
assert property (@(posedge clk) ##1 val ##2 val) $display("[%0t] sequence stmt, fileline:%d", $time, `__LINE__);
`else
assert property (@(posedge clk) ##1 1 |-> 1) $display("[%0t] single delay with const implication stmt, fileline:%d", $time, `__LINE__);
module Test ( assert property (@(posedge clk) ##1 1 |-> not (val)) $display("[%0t] single delay implication with negated var stmt, fileline:%d", $time, `__LINE__);
input clk,
input bit val,
input integer cyc
);
assert property (@(posedge clk) ##2 val) assert property (@(posedge clk) 1 |-> ##1 val) $display("[%0t] single delay implication with negated var stmt, fileline:%d", $time, `__LINE__);
else $display("[%0t] assertion triggered, fileline:%d", $time, `__LINE__);
assert property (@(posedge clk) ##1 1 |=> 0) assert property (@(posedge clk) (##1 val) |-> (not val)) $display("[%0t] single delay with negated implication stmt, fileline:%d", $time, `__LINE__);
else $display("[%0t] assertion triggered, fileline:%d", $time, `__LINE__);
assert property (@(posedge clk) ##1 1 |=> not (val)) assert property (@(posedge clk) ##1 (val) |-> not (val)) $display("[%0t] single delay with negated implication brackets stmt, fileline:%d", $time, `__LINE__);
else $display("[%0t] assertion triggered, fileline:%d", $time, `__LINE__);
assert property (@(posedge clk) ##1 val) assert property (@(posedge clk) ((val) |-> not (val))) $display("[%0t] disable iff with negated implication stmt, fileline:%d", $time, `__LINE__);
else $display("[%0t] assertion triggered, fileline:%d", $time, `__LINE__);
assert property (@(posedge clk) ##1 (val)) assert property (@(posedge clk) ##1 1 |-> 0) $display("[%0t] disable iff with cond implication stmt, fileline:%d", $time, `__LINE__);
else $display("[%0t] assertion triggered, fileline:%d", $time, `__LINE__);
assert property (@(posedge clk) (##1 (val))) assert property (@(posedge clk) (##1 val) |-> (##1 val)) $display("[%0t] two delays implication stmt, fileline:%d", $time, `__LINE__);
else $display("[%0t] assertion triggered, fileline:%d", $time, `__LINE__);
assert property (@(posedge clk) (##1 (val))) assert property (@(posedge clk) disable iff (cyc != 5) ##1 0) $display("[%0t] disable iff stmt, fileline:%d", $time, `__LINE__);
else $display("[%0t] assertion triggered, fileline:%d", $time, `__LINE__);
assert property (@(posedge clk) not (##1 val)) assume property (@(posedge clk) disable iff (cyc != 5) ##1 0) $display("[%0t] disable iff stmt, fileline:%d", $time, `__LINE__);
else $display("[%0t] assertion triggered, fileline:%d", $time, `__LINE__);
assert property (@(posedge clk) ##1 1 |=> 1) cover property (@(posedge clk) disable iff (cyc != 5) ##1 0) $display("[%0t] disable iff stmt, fileline:%d", $time, `__LINE__);
else $display("[%0t] assertion triggered, fileline:%d", $time, `__LINE__); `endif
assert property (@(posedge clk) ##1 val |=> not val)
else $display("[%0t] assertion triggered, fileline:%d", $time, `__LINE__);
assert property (@(posedge clk) ##1 (val) |=> not (val))
else $display("[%0t] assertion triggered, fileline:%d", $time, `__LINE__);
assert property (@(posedge clk) ((val) |=> not (val)))
else $display("[%0t] assertion triggered, fileline:%d", $time, `__LINE__);
assert property (@(posedge clk) disable iff (cyc < 3) ##1 1 |=> cyc > 3)
else $display("[%0t] assertion triggered, fileline:%d", $time, `__LINE__);
assert property (@(posedge clk) (##1 val) |=> (##1 val))
else $display("[%0t] assertion triggered, fileline:%d", $time, `__LINE__);
endmodule endmodule
// Test parsing only // Test parsing only
@ -94,6 +61,7 @@ module Ieee;
byte q[$]; byte q[$];
logic clk; logic clk;
`ifdef PARSING_TIME
property p1; property p1;
$rose(a) |-> q[0]; $rose(a) |-> q[0];
endproperty endproperty
@ -122,4 +90,5 @@ module Ieee;
// IEEE 1800-2023 16.12.3 // IEEE 1800-2023 16.12.3
assert property (@clk not a ##1 b); assert property (@clk not a ##1 b);
`endif
endmodule endmodule

View File

@ -0,0 +1,20 @@
%Error-UNSUPPORTED: t/t_sequence_first_match_unsup.v:47:40: Unsupported: or (in sequence expression)
47 | initial p0: assert property ((##1 1) or (##2 1) |-> x==1);
| ^~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error-UNSUPPORTED: t/t_sequence_first_match_unsup.v:50:52: Unsupported: or (in sequence expression)
50 | initial p1: assert property (first_match((##1 1) or (##2 1)) |-> x==1);
| ^~
%Error-UNSUPPORTED: t/t_sequence_first_match_unsup.v:50:32: Unsupported: first_match (in sequence expression)
50 | initial p1: assert property (first_match((##1 1) or (##2 1)) |-> x==1);
| ^~~~~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_first_match_unsup.v:53:34: Unsupported: or (in sequence expression)
53 | initial p2: assert property (1 or ##1 1 |-> x==0);
| ^~
%Error-UNSUPPORTED: t/t_sequence_first_match_unsup.v:56:46: Unsupported: or (in sequence expression)
56 | initial p3: assert property (first_match(1 or ##1 1) |-> x==0);
| ^~
%Error-UNSUPPORTED: t/t_sequence_first_match_unsup.v:56:32: Unsupported: first_match (in sequence expression)
56 | initial p3: assert property (first_match(1 or ##1 1) |-> x==0);
| ^~~~~~~~~~~
%Error: Exiting due to

View File

@ -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.lint(expect_filename=test.golden_filename,
verilator_flags2=['--assert --error-limit 1000'],
fails=True)
test.passes()

View File

@ -0,0 +1,58 @@
// (C) 2001-2020, Daniel Kroening, Edmund Clarke,
// Computer Science Department, University of Oxford
// Computer Science Department, Carnegie Mellon University
//
// All rights reserved. Redistribution and use in source and binary forms, with
// or without modification, are permitted provided that the following
// conditions are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the University nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// You can contact the author at:
// - homepage : https://www.cprover.org/ebmc/
// - source repository : https://github.com/diffblue/hw-cbmc
module main(input clk);
reg [31:0] x = 0;
always @(posedge clk)
x<=x+1;
// Starting from a particular state,
// first_match yields the sequence that _ends_ first.
// fails
initial p0: assert property ((##1 1) or (##2 1) |-> x==1);
// passes
initial p1: assert property (first_match((##1 1) or (##2 1)) |-> x==1);
// fails
initial p2: assert property (1 or ##1 1 |-> x==0);
// passes
initial p3: assert property (first_match(1 or ##1 1) |-> x==0);
endmodule

View File

@ -36,209 +36,182 @@
52 | a intersect b; 52 | a intersect b;
| ^~~~~~~~~ | ^~~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:55:4: Unsupported: sequence %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:55:4: Unsupported: sequence
55 | sequence s_uni_cycdelay_int; 55 | sequence s_uni_cycdelay_id;
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:56:7: Unsupported: ## () cycle delay range expression %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:56:7: Unsupported: ## id cycle delay range expression
56 | ## 1 b; 56 | ## DELAY b;
| ^~ | ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:56:12: Unsupported: ## (in sequence expression)
56 | ## 1 b;
| ^
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:58:4: Unsupported: sequence %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:58:4: Unsupported: sequence
58 | sequence s_uni_cycdelay_id; 58 | sequence s_uni_cycdelay_pid;
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:59:7: Unsupported: ## id cycle delay range expression %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:59:7: Unsupported: ## () cycle delay range expression
59 | ## DELAY b; 59 | ## ( DELAY ) b;
| ^~ | ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:59:16: Unsupported: ## (in sequence expression)
59 | ## DELAY b;
| ^
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:61:4: Unsupported: sequence %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:61:4: Unsupported: sequence
61 | sequence s_uni_cycdelay_pid; 61 | sequence s_uni_cycdelay_range;
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:62:7: Unsupported: ## () cycle delay range expression %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:62:7: Unsupported: ## range cycle delay range expression
62 | ## ( DELAY ) b; 62 | ## [1:2] b;
| ^~ | ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:62:20: Unsupported: ## (in sequence expression)
62 | ## ( DELAY ) b;
| ^
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:64:4: Unsupported: sequence %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:64:4: Unsupported: sequence
64 | sequence s_uni_cycdelay_range; 64 | sequence s_uni_cycdelay_star;
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:65:7: Unsupported: ## range cycle delay range expression %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:65:7: Unsupported: ## [*] cycle delay range expression
65 | ## [1:2] b; 65 | ## [*] b;
| ^~ | ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:65:16: Unsupported: ## (in sequence expression)
65 | ## [1:2] b;
| ^
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:67:4: Unsupported: sequence %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:67:4: Unsupported: sequence
67 | sequence s_uni_cycdelay_star; 67 | sequence s_uni_cycdelay_plus;
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:68:7: Unsupported: ## [*] cycle delay range expression %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:68:7: Unsupported: ## [+] cycle delay range expression
68 | ## [*] b; 68 | ## [+] b;
| ^~ | ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:68:14: Unsupported: ## (in sequence expression) %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:71:4: Unsupported: sequence
68 | ## [*] b; 71 | sequence s_cycdelay_int;
| ^
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:70:4: Unsupported: sequence
70 | sequence s_uni_cycdelay_plus;
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:71:7: Unsupported: ## [+] cycle delay range expression %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:72:9: Unsupported: ## (in sequence expression)
71 | ## [+] b; 72 | a ## 1 b;
| ^~ | ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:71:14: Unsupported: ## (in sequence expression)
71 | ## [+] b;
| ^
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:74:4: Unsupported: sequence %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:74:4: Unsupported: sequence
74 | sequence s_cycdelay_int; 74 | sequence s_cycdelay_id;
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:75:9: Unsupported: ## () cycle delay range expression %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:75:9: Unsupported: ## id cycle delay range expression
75 | a ## 1 b; 75 | a ## DELAY b;
| ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:75:9: Unsupported: ## (in sequence expression)
75 | a ## DELAY b;
| ^~ | ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:75:12: Unsupported: ## (in sequence expression)
75 | a ## 1 b;
| ^
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:77:4: Unsupported: sequence %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:77:4: Unsupported: sequence
77 | sequence s_cycdelay_id; 77 | sequence s_cycdelay_pid;
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:78:9: Unsupported: ## id cycle delay range expression %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:78:9: Unsupported: ## () cycle delay range expression
78 | a ## DELAY b; 78 | a ## ( DELAY ) b;
| ^~ | ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:78:9: Unsupported: ## (in sequence expression) %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:78:9: Unsupported: ## (in sequence expression)
78 | a ## DELAY b; 78 | a ## ( DELAY ) b;
| ^~ | ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:80:4: Unsupported: sequence %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:80:4: Unsupported: sequence
80 | sequence s_cycdelay_pid; 80 | sequence s_cycdelay_range;
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:81:9: Unsupported: ## () cycle delay range expression %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:81:9: Unsupported: ## range cycle delay range expression
81 | a ## ( DELAY ) b; 81 | a ## [1:2] b;
| ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:81:9: Unsupported: ## (in sequence expression)
81 | a ## [1:2] b;
| ^~ | ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:81:14: Unsupported: ## (in sequence expression)
81 | a ## ( DELAY ) b;
| ^~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:83:4: Unsupported: sequence %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:83:4: Unsupported: sequence
83 | sequence s_cycdelay_range; 83 | sequence s_cycdelay_star;
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:84:9: Unsupported: ## range cycle delay range expression %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:84:9: Unsupported: ## [*] cycle delay range expression
84 | a ## [1:2] b; 84 | a ## [*] b;
| ^~ | ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:84:9: Unsupported: ## (in sequence expression) %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:84:9: Unsupported: ## (in sequence expression)
84 | a ## [1:2] b; 84 | a ## [*] b;
| ^~ | ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:86:4: Unsupported: sequence %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:86:4: Unsupported: sequence
86 | sequence s_cycdelay_star; 86 | sequence s_cycdelay_plus;
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:87:9: Unsupported: ## [*] cycle delay range expression %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:87:9: Unsupported: ## [+] cycle delay range expression
87 | a ## [*] b; 87 | a ## [+] b;
| ^~ | ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:87:9: Unsupported: ## (in sequence expression) %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:87:9: Unsupported: ## (in sequence expression)
87 | a ## [*] b; 87 | a ## [+] b;
| ^~ | ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:89:4: Unsupported: sequence %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:90:4: Unsupported: sequence
89 | sequence s_cycdelay_plus; 90 | sequence s_booleanabbrev_brastar_int;
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:90:9: Unsupported: ## [+] cycle delay range expression %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:91:9: Unsupported: [*] boolean abbrev expression
90 | a ## [+] b; 91 | a [* 1 ];
| ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:90:9: Unsupported: ## (in sequence expression)
90 | a ## [+] b;
| ^~ | ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:91:12: Unsupported: boolean abbrev (in sequence expression)
91 | a [* 1 ];
| ^
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:93:4: Unsupported: sequence %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:93:4: Unsupported: sequence
93 | sequence s_booleanabbrev_brastar_int; 93 | sequence s_booleanabbrev_brastar;
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:94:9: Unsupported: [*] boolean abbrev expression %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:94:9: Unsupported: [*] boolean abbrev expression
94 | a [* 1 ]; 94 | a [*];
| ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:94:9: Unsupported: boolean abbrev (in sequence expression)
94 | a [*];
| ^~ | ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:94:12: Unsupported: boolean abbrev (in sequence expression)
94 | a [* 1 ];
| ^
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:96:4: Unsupported: sequence %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:96:4: Unsupported: sequence
96 | sequence s_booleanabbrev_brastar; 96 | sequence s_booleanabbrev_plus;
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:97:9: Unsupported: [*] boolean abbrev expression %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:97:9: Unsupported: [+] boolean abbrev expression
97 | a [*]; 97 | a [+];
| ^~ | ^~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:97:9: Unsupported: boolean abbrev (in sequence expression) %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:97:9: Unsupported: boolean abbrev (in sequence expression)
97 | a [*]; 97 | a [+];
| ^~ | ^~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:99:4: Unsupported: sequence %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:99:4: Unsupported: sequence
99 | sequence s_booleanabbrev_plus; 99 | sequence s_booleanabbrev_eq;
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:100:9: Unsupported: [+] boolean abbrev expression %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:100:9: Unsupported: [= boolean abbrev expression
100 | a [+]; 100 | a [= 1];
| ^~~ | ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:100:9: Unsupported: boolean abbrev (in sequence expression) %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:100:12: Unsupported: boolean abbrev (in sequence expression)
100 | a [+]; 100 | a [= 1];
| ^~~ | ^
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:102:4: Unsupported: sequence %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:102:4: Unsupported: sequence
102 | sequence s_booleanabbrev_eq; 102 | sequence s_booleanabbrev_eq_range;
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:103:9: Unsupported: [= boolean abbrev expression %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:103:9: Unsupported: [= boolean abbrev expression
103 | a [= 1]; 103 | a [= 1:2];
| ^~ | ^~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:103:12: Unsupported: boolean abbrev (in sequence expression) %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:103:12: Unsupported: boolean abbrev (in sequence expression)
103 | a [= 1]; 103 | a [= 1:2];
| ^ | ^
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:105:4: Unsupported: sequence %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:105:4: Unsupported: sequence
105 | sequence s_booleanabbrev_eq_range; 105 | sequence s_booleanabbrev_minusgt;
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:106:9: Unsupported: [= boolean abbrev expression %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:106:9: Unsupported: [-> boolean abbrev expression
106 | a [= 1:2]; 106 | a [-> 1];
| ^~ | ^~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:106:12: Unsupported: boolean abbrev (in sequence expression) %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:106:13: Unsupported: boolean abbrev (in sequence expression)
106 | a [= 1:2]; 106 | a [-> 1];
| ^ | ^
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:108:4: Unsupported: sequence %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:108:4: Unsupported: sequence
108 | sequence s_booleanabbrev_minusgt; 108 | sequence s_booleanabbrev_minusgt_range;
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:109:9: Unsupported: [-> boolean abbrev expression %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:109:9: Unsupported: [-> boolean abbrev expression
109 | a [-> 1]; 109 | a [-> 1:2];
| ^~~ | ^~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:109:13: Unsupported: boolean abbrev (in sequence expression) %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:109:13: Unsupported: boolean abbrev (in sequence expression)
109 | a [-> 1]; 109 | a [-> 1:2];
| ^ | ^
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:111:4: Unsupported: sequence %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:112:4: Unsupported: sequence
111 | sequence s_booleanabbrev_minusgt_range; 112 | sequence p_arg_seqence(sequence inseq);
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:112:9: Unsupported: [-> boolean abbrev expression %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:112:27: Unsupported: sequence argument data type
112 | a [-> 1:2]; 112 | sequence p_arg_seqence(sequence inseq);
| ^~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:112:13: Unsupported: boolean abbrev (in sequence expression)
112 | a [-> 1:2];
| ^
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:115:4: Unsupported: sequence
115 | sequence p_arg_seqence(sequence inseq);
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:115:27: Unsupported: sequence argument data type %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:116:4: Unsupported: sequence
115 | sequence p_arg_seqence(sequence inseq); 116 | sequence s_firstmatch_a;
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:117:7: Unsupported: first_match (in sequence expression)
117 | first_match (a);
| ^~~~~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:119:4: Unsupported: sequence %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:119:4: Unsupported: sequence
119 | sequence s_firstmatch_a; 119 | sequence s_firstmatch_ab;
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:120:7: Unsupported: first_match (in sequence expression) %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:120:7: Unsupported: first_match (in sequence expression)
120 | first_match (a); 120 | first_match (a, res0 = 1);
| ^~~~~~~~~~~ | ^~~~~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:122:4: Unsupported: sequence %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:122:4: Unsupported: sequence
122 | sequence s_firstmatch_ab; 122 | sequence s_firstmatch_abc;
| ^~~~~~~~ | ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:123:7: Unsupported: first_match (in sequence expression) %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:123:7: Unsupported: first_match (in sequence expression)
123 | first_match (a, res0 = 1); 123 | first_match (a, res0 = 1, res1 = 2);
| ^~~~~~~~~~~ | ^~~~~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:125:4: Unsupported: sequence %Warning-COVERIGN: t/t_sequence_sexpr_unsup.v:126:10: Ignoring unsupported: cover sequence
125 | sequence s_firstmatch_abc; 126 | cover sequence (s_a) $display("");
| ^~~~~~~~
%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:126:7: Unsupported: first_match (in sequence expression)
126 | first_match (a, res0 = 1, res1 = 2);
| ^~~~~~~~~~~
%Warning-COVERIGN: t/t_sequence_sexpr_unsup.v:129:10: Ignoring unsupported: cover sequence
129 | cover sequence (s_a) $display("");
| ^~~~~~~~ | ^~~~~~~~
... For warning description see https://verilator.org/warn/COVERIGN?v=latest ... For warning description see https://verilator.org/warn/COVERIGN?v=latest
... Use "/* verilator lint_off COVERIGN */" and lint_on around source to disable this message. ... Use "/* verilator lint_off COVERIGN */" and lint_on around source to disable this message.
%Warning-COVERIGN: t/t_sequence_sexpr_unsup.v:130:10: Ignoring unsupported: cover sequence %Warning-COVERIGN: t/t_sequence_sexpr_unsup.v:127:10: Ignoring unsupported: cover sequence
130 | cover sequence (@(posedge a) disable iff (b) s_a) $display(""); 127 | cover sequence (@(posedge a) disable iff (b) s_a) $display("");
| ^~~~~~~~ | ^~~~~~~~
%Warning-COVERIGN: t/t_sequence_sexpr_unsup.v:131:10: Ignoring unsupported: cover sequence %Warning-COVERIGN: t/t_sequence_sexpr_unsup.v:128:10: Ignoring unsupported: cover sequence
131 | cover sequence (disable iff (b) s_a) $display(""); 128 | cover sequence (disable iff (b) s_a) $display("");
| ^~~~~~~~ | ^~~~~~~~
%Error: Exiting due to %Error: Exiting due to

View File

@ -52,9 +52,6 @@ module t (/*AUTOARG*/
a intersect b; a intersect b;
endsequence endsequence
sequence s_uni_cycdelay_int;
## 1 b;
endsequence
sequence s_uni_cycdelay_id; sequence s_uni_cycdelay_id;
## DELAY b; ## DELAY b;
endsequence endsequence