mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Optimize consecutive repetiton and goto repetition using ring-buffer (#8096)
This commit is contained in:
@@ -671,9 +671,11 @@ class AssertVisitor final : public VNVisitor {
|
||||
|
||||
AstNode* propExprp;
|
||||
AstNodeExpr* disablep = nullptr;
|
||||
AstNodeExpr* matchCountp = nullptr;
|
||||
if (AstPropSpec* const specp = VN_CAST(nodep->propp(), PropSpec)) {
|
||||
propExprp = specp->propp()->unlinkFrBack();
|
||||
if (specp->disablep()) disablep = specp->disablep()->unlinkFrBack();
|
||||
matchCountp = specp->matchCountp();
|
||||
} else {
|
||||
propExprp = nodep->propp()->unlinkFrBack();
|
||||
}
|
||||
@@ -688,6 +690,28 @@ class AssertVisitor final : public VNVisitor {
|
||||
if (failsp && !VN_IS(propExprp, PExpr)) {
|
||||
failsp = newIfAssertFailOn(failsp, nodep->directive(), nodep->userType());
|
||||
}
|
||||
if (coverp && matchCountp && passsp) {
|
||||
// Convert the match count into a loop that decrements a temporary variable until it
|
||||
// reaches zero.
|
||||
matchCountp->unlinkFrBack();
|
||||
AstVar* const remainingp = new AstVar{
|
||||
flp, VVarType::BLOCKTEMP, "__VnfaRemainingMatchCount", matchCountp->dtypep()};
|
||||
remainingp->lifetime(VLifetime::AUTOMATIC_EXPLICIT);
|
||||
AstBegin* const replayp = new AstBegin{flp, "", remainingp, true};
|
||||
replayp->addStmtsp(
|
||||
new AstAssign{flp, new AstVarRef{flp, remainingp, VAccess::WRITE}, matchCountp});
|
||||
AstLoop* const loopp = new AstLoop{flp};
|
||||
loopp->addStmtsp(
|
||||
new AstLoopTest{flp, loopp, new AstVarRef{flp, remainingp, VAccess::READ}});
|
||||
loopp->addStmtsp(passsp);
|
||||
loopp->addStmtsp(
|
||||
new AstAssign{flp, new AstVarRef{flp, remainingp, VAccess::WRITE},
|
||||
new AstSub{flp, new AstVarRef{flp, remainingp, VAccess::READ},
|
||||
new AstConst{flp, AstConst::WidthedValue{},
|
||||
remainingp->dtypep()->width(), 1}}});
|
||||
replayp->addStmtsp(loopp);
|
||||
passsp = replayp;
|
||||
}
|
||||
AstNode* bodysp = assertBody(nodep, propExprp, passsp, failsp);
|
||||
if (disablep) bodysp = new AstIf{flp, new AstLogNot{flp, disablep}, bodysp};
|
||||
// Add assertOn check last, for better combining
|
||||
|
||||
Reference in New Issue
Block a user