mirror of
https://github.com/verilator/verilator.git
synced 2026-08-30 01:38:21 +02:00
+47
-14
@@ -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); }
|
||||
|
||||
Reference in New Issue
Block a user