Fix expression coverage on additional nodes (#5849 partial) (#5867)

This commit is contained in:
Todd Strader
2025-03-19 19:01:31 -04:00
committed by GitHub
parent 39bdd427d6
commit d2b7b567df
7 changed files with 74 additions and 14 deletions
+47 -14
View File
@@ -35,6 +35,23 @@
VL_DEFINE_DEBUG_FUNCTIONS;
class ExprCoverageEligibleVisitor final : public VNVisitor {
// STATE
bool m_eligible = true;
void visit(AstNode* nodep) override {
if (!nodep->isExprCoverageEligible()) { m_eligible = false; }
iterateChildren(nodep);
}
public:
// CONSTRUCTORS
explicit ExprCoverageEligibleVisitor(AstNode* nodep) { iterateChildren(nodep); }
~ExprCoverageEligibleVisitor() override = default;
bool eligible() { return m_eligible; }
};
//######################################################################
// Coverage state, as a visitor of each AstNode
@@ -669,6 +686,7 @@ class CoverageVisitor final : public VNVisitor {
m_objective = true;
iterate(nodep);
if (checkMaxExprs(falseExprs.size())) return;
if (m_seeking == ABORTED) return;
addExprCoverInc(nodep);
const int start = m_exprs.size();
@@ -872,26 +890,30 @@ class CoverageVisitor final : public VNVisitor {
lineTrack(nodep);
}
// Lambdas not supported for expression coverage
void visit(AstWith* nodep) override {
VL_RESTORER(m_seeking);
if (m_seeking == SEEKING) abortExprCoverage();
m_seeking = ABORTED;
iterateChildren(nodep);
lineTrack(nodep);
void visit(AstFuncRef* nodep) override {
if (nodep->taskp()->lifetime().isAutomatic()) {
visit(static_cast<AstNodeExpr*>(nodep));
} else {
exprUnsupported(nodep, "non-automatic function");
}
}
void visit(AstNodeExpr* nodep) override {
if (m_seeking != SEEKING) {
iterateChildren(nodep);
} else {
std::stringstream emitV;
V3EmitV::verilogForTree(nodep, emitV);
// Add new expression with a single term
CoverExpr expr;
expr.emplace_back(nodep, m_objective, emitV.str());
m_exprs.push_back(std::move(expr));
checkMaxExprs();
ExprCoverageEligibleVisitor elgibleVisitor(nodep);
if (elgibleVisitor.eligible()) {
std::stringstream emitV;
V3EmitV::verilogForTree(nodep, emitV);
// Add new expression with a single term
CoverExpr expr;
expr.emplace_back(nodep, m_objective, emitV.str());
m_exprs.push_back(std::move(expr));
checkMaxExprs();
} else {
exprUnsupported(nodep, "not coverage eligible");
}
}
lineTrack(nodep);
}
@@ -902,6 +924,17 @@ class CoverageVisitor final : public VNVisitor {
lineTrack(nodep);
}
void exprUnsupported(AstNode* nodep, const string& why) {
UINFO(9, "unsupported: " << why << " " << nodep << endl);
bool wasSeeking = m_seeking == SEEKING;
Objective oldSeeking = m_seeking;
if (wasSeeking) { abortExprCoverage(); }
m_seeking = ABORTED;
iterateChildren(nodep);
lineTrack(nodep);
if (!wasSeeking) { m_seeking = oldSeeking; }
}
public:
// CONSTRUCTORS
explicit CoverageVisitor(AstNetlist* rootp) { iterateChildren(rootp); }