parent
39bdd427d6
commit
d2b7b567df
|
|
@ -2486,6 +2486,8 @@ public:
|
|||
virtual bool isGateOptimizable() const { return !isTimingControl(); }
|
||||
// GateDedupable is a slightly larger superset of GateOptimzable (eg, AstNodeIf)
|
||||
virtual bool isGateDedupable() const { return isGateOptimizable(); }
|
||||
// Whether the node can be used in expression coverage
|
||||
virtual bool isExprCoverageEligible() const { return isGateDedupable(); }
|
||||
// Else creates output or exits, etc, not unconsumed
|
||||
virtual bool isOutputter() { return false; }
|
||||
// Else a AstTime etc which output can't be predicted from input
|
||||
|
|
|
|||
|
|
@ -1600,6 +1600,7 @@ public:
|
|||
string name() const override VL_MT_STABLE { return m_name; } // * = Var name
|
||||
void name(const string& name) override { m_name = name; }
|
||||
bool index() const { return m_index; }
|
||||
bool isExprCoverageEligible() const override { return false; }
|
||||
};
|
||||
class AstMemberSel final : public AstNodeExpr {
|
||||
// @astgen op1 := fromp : AstNodeExpr
|
||||
|
|
|
|||
|
|
@ -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); }
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@
|
|||
// any use, without warranty, 2024 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
class cls;
|
||||
rand int x;
|
||||
endclass
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
|
|
@ -284,6 +288,7 @@
|
|||
|
||||
logic ta, tb, tc;
|
||||
initial begin
|
||||
cls obj = new;
|
||||
int q[5];
|
||||
int qv[$];
|
||||
|
||||
|
|
@ -304,6 +309,7 @@
|
|||
tb = ta;
|
||||
ta = '0;
|
||||
end
|
||||
if (!bit'(obj.randomize() with {x < 100;})) $write("");
|
||||
end
|
||||
|
||||
sub the_sub_1 (.p(t1), .q(t2));
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@
|
|||
// any use, without warranty, 2024 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
class cls;
|
||||
rand int x;
|
||||
endclass
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
|
|
@ -124,6 +128,7 @@ module t (/*AUTOARG*/
|
|||
|
||||
logic ta, tb, tc;
|
||||
initial begin
|
||||
cls obj = new;
|
||||
int q[5];
|
||||
int qv[$];
|
||||
|
||||
|
|
@ -140,6 +145,7 @@ module t (/*AUTOARG*/
|
|||
tb = ta;
|
||||
ta = '0;
|
||||
end
|
||||
if (!bit'(obj.randomize() with {x < 100;})) $write("");
|
||||
end
|
||||
|
||||
sub the_sub_1 (.p(t1), .q(t2));
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@
|
|||
// any use, without warranty, 2024 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
class cls;
|
||||
rand int x;
|
||||
endclass
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
|
|
@ -412,6 +416,7 @@
|
|||
|
||||
logic ta, tb, tc;
|
||||
initial begin
|
||||
cls obj = new;
|
||||
int q[5];
|
||||
int qv[$];
|
||||
|
||||
|
|
@ -432,6 +437,7 @@
|
|||
tb = ta;
|
||||
ta = '0;
|
||||
end
|
||||
if (!bit'(obj.randomize() with {x < 100;})) $write("");
|
||||
end
|
||||
|
||||
sub the_sub_1 (.p(t1), .q(t2));
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@
|
|||
// any use, without warranty, 2024 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
class cls;
|
||||
rand int x;
|
||||
endclass
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
|
|
@ -284,6 +288,7 @@
|
|||
|
||||
logic ta, tb, tc;
|
||||
initial begin
|
||||
cls obj = new;
|
||||
int q[5];
|
||||
int qv[$];
|
||||
|
||||
|
|
@ -304,6 +309,7 @@
|
|||
tb = ta;
|
||||
ta = '0;
|
||||
end
|
||||
if (!bit'(obj.randomize() with {x < 100;})) $write("");
|
||||
end
|
||||
|
||||
sub the_sub_1 (.p(t1), .q(t2));
|
||||
|
|
|
|||
Loading…
Reference in New Issue