Apply 'make format'

This commit is contained in:
github action 2026-04-22 19:20:00 +00:00
parent a680919edc
commit e4da16caf0
23 changed files with 89 additions and 101 deletions

View File

@ -227,13 +227,13 @@ public:
"ENCAPSULATED", "ENDLABEL", "ENUMITEMWIDTH", "ENUMVALUE", "EOFNEWLINE", "FSMMULTI",
"FUNCTIMECTL", "FUTURE", "GENCLK", "GENUNNAMED", "HIERBLOCK", "HIERPARAM", "IFDEPTH",
"IGNOREDRETURN", "IMPERFECTSCH", "IMPLICIT", "IMPLICITSTATIC", "IMPORTSTAR", "IMPURE",
"INCABSPATH","INFINITELOOP", "INITIALDLY", "INSECURE", "INSIDETRUE", "LATCH",
"INCABSPATH", "INFINITELOOP", "INITIALDLY", "INSECURE", "INSIDETRUE", "LATCH",
"LITENDIAN", "MINTYPMAXDLY", "MISINDENT", "MODDUP", "MODMISSING", "MULTIDRIVEN",
"MULTITOP", "NEWERSTD", "NOEFFECT", "NOLATCH", "NONSTD", "NORETURN", "NULLPORT",
"PARAMNODEFAULT", "PINCONNECTEMPTY", "PINMISSING", "PINNOCONNECT", "PINNOTFOUND",
"PKGNODECL", "PREPROCZERO", "PROCASSINIT", "PROCASSWIRE", "PROFOUTOFDATE", "PROTECTED",
"PROTOTYPEMIS", "RANDC", "REALCVT", "REDEFMACRO", "RISEFALLDLY", "SELRANGE",
"SHORTREAL", "SIDEEFFECT", "SPECIFYIGN", "SPLITVAR", "STATICVAR","STMTDLY",
"SHORTREAL", "SIDEEFFECT", "SPECIFYIGN", "SPLITVAR", "STATICVAR", "STMTDLY",
"SUPERNFIRST", "SYMRSVDWORD", "SYNCASYNCNET", "TICKCOUNT", "TIMESCALEMOD", "UNDRIVEN",
"UNOPT", "UNOPTFLAT", "UNOPTTHREADS", "UNPACKED", "UNSATCONSTR", "UNSIGNED", "UNUSED",
"UNUSEDGENVAR", "UNUSEDLOOP", "UNUSEDPARAM", "UNUSEDSIGNAL", "USERERROR", "USERFATAL",

View File

@ -65,16 +65,16 @@ public:
enum class Kind : uint8_t { STATE, RESET_ANY, DEFAULT_ANY };
private:
Kind m_kind; // State vs synthetic ANY/default vertex role.
Kind m_kind; // State vs synthetic ANY/default vertex role.
string m_label; // User-facing state or pseudo-state label.
int m_value = 0; // Encoded state value for real state vertices.
protected:
FsmVertex(V3Graph* graphp, Kind kind, string label, int value) VL_MT_DISABLED
: V3GraphVertex{graphp}
, m_kind{kind}
, m_label{label}
, m_value{value} {}
: V3GraphVertex{graphp},
m_kind{kind},
m_label{label},
m_value{value} {}
~FsmVertex() override = default;
public:
@ -116,18 +116,17 @@ public:
class FsmArcEdge final : public V3GraphEdge {
VL_RTTI_IMPL(FsmArcEdge, V3GraphEdge)
bool m_isReset = false; // Arc originates from the synthetic reset source.
bool m_isCond = false; // Arc came from a conditional next-state split.
bool m_isCond = false; // Arc came from a conditional next-state split.
bool m_isDefault = false; // Arc represents a case default source.
FileLine* m_flp = nullptr; // Source location for emitted coverage metadata.
public:
FsmArcEdge(V3Graph* graphp, FsmVertex* fromp, FsmStateVertex* top, bool isReset,
bool isCond, bool isDefault, FileLine* flp) VL_MT_DISABLED
: V3GraphEdge{graphp, fromp, top, 1}
, m_isReset{isReset}
, m_isCond{isCond}
, m_isDefault{isDefault}
, m_flp{flp} {}
FsmArcEdge(V3Graph* graphp, FsmVertex* fromp, FsmStateVertex* top, bool isReset, bool isCond,
bool isDefault, FileLine* flp) VL_MT_DISABLED : V3GraphEdge{graphp, fromp, top, 1},
m_isReset{isReset},
m_isCond{isCond},
m_isDefault{isDefault},
m_flp{flp} {}
~FsmArcEdge() override = default;
bool isReset() const { return m_isReset; }
@ -159,18 +158,18 @@ class FsmGraph final : public V3Graph {
AstVarScope* m_stateVarScopep = nullptr; // Scoped state variable being tracked.
std::vector<FsmSenDesc> m_senses; // Saved event controls for recreated active blocks.
FsmResetCondDesc m_resetCond; // Saved reset predicate shape, if one exists.
bool m_hasResetCond = false; // Whether the detected FSM had a reset branch.
bool m_hasResetCond = false; // Whether the detected FSM had a reset branch.
bool m_resetInclude = false; // Whether reset arcs count toward coverage totals.
bool m_inclCond = false; // Whether conditional arcs should be kept explicitly.
FileLine* m_flp = nullptr; // Representative source location for declarations/arcs.
bool m_inclCond = false; // Whether conditional arcs should be kept explicitly.
FileLine* m_flp = nullptr; // Representative source location for declarations/arcs.
std::unordered_map<int, FsmStateVertex*> m_stateVertices; // Value to state-vertex map.
FsmPseudoVertex* m_resetVertexp = nullptr; // Synthetic ANY source for reset arcs.
FsmPseudoVertex* m_defaultVertexp = nullptr; // Synthetic default source for case defaults.
public:
FsmGraph() VL_MT_DISABLED
: m_resetVertexp{new FsmPseudoVertex{this, FsmVertex::Kind::RESET_ANY, "ANY"}}
, m_defaultVertexp{new FsmPseudoVertex{this, FsmVertex::Kind::DEFAULT_ANY, "default"}} {}
: m_resetVertexp{new FsmPseudoVertex{this, FsmVertex::Kind::RESET_ANY, "ANY"}},
m_defaultVertexp{new FsmPseudoVertex{this, FsmVertex::Kind::DEFAULT_ANY, "default"}} {}
AstScope* scopep() const { return m_scopep; }
void scopep(AstScope* scopep) { m_scopep = scopep; }
@ -269,9 +268,7 @@ class FsmDetectVisitor final : public VNVisitor {
// Reset arcs are only modeled for the simple signal form that survives to
// this pass after earlier normalization.
static bool isSimpleResetCond(AstNodeExpr* condp) {
return VN_IS(condp, VarRef);
}
static bool isSimpleResetCond(AstNodeExpr* condp) { return VN_IS(condp, VarRef); }
// Normalize the reset condition into a compact description so the lowering
// phase can regenerate the same predicate after detection. By the time
@ -358,9 +355,8 @@ class FsmDetectVisitor final : public VNVisitor {
static bool validateKnownStateValue(AstNode* nodep,
const std::unordered_map<int, string>& labels, int value) {
if (labels.find(value) != labels.end()) return true;
nodep->v3warn(COVERIGN,
"Ignoring unsupported: FSM coverage on enum state transitions "
"that assign a constant not present in the declared enum");
nodep->v3warn(COVERIGN, "Ignoring unsupported: FSM coverage on enum state transitions "
"that assign a constant not present in the declared enum");
return false;
}
@ -405,8 +401,8 @@ class FsmDetectVisitor final : public VNVisitor {
if (!validateKnownStateValue(condp->elsep(), labels, elseValue)) return true;
for (const int branchValue : {thenValue, elseValue}) {
for (const std::pair<string, int>& from : froms) {
graph.addArc(from.second, branchValue, false, true,
itemp->isDefault(), assp->fileline());
graph.addArc(from.second, branchValue, false, true, itemp->isDefault(),
assp->fileline());
}
}
return true;
@ -425,7 +421,8 @@ class FsmDetectVisitor final : public VNVisitor {
if (AstNodeAssign* const assp = VN_CAST(nodep, NodeAssign)) {
AstVarRef* const vrefp = VN_CAST(assp->lhsp(), VarRef);
int toValue = 0;
if (vrefp && vrefp->varScopep() == stateVscp && exprConstValue(assp->rhsp(), toValue)) {
if (vrefp && vrefp->varScopep() == stateVscp
&& exprConstValue(assp->rhsp(), toValue)) {
if (!validateKnownStateValue(assp, labels, toValue)) continue;
graph.addArc(0, toValue, true, false, false, assp->fileline());
}
@ -450,12 +447,12 @@ class FsmDetectVisitor final : public VNVisitor {
std::unordered_map<int, string> labels;
if (enump) {
if (stateVscp->width() < 1 || stateVscp->width() > 32) {
casep->v3warn(COVERIGN,
"Ignoring unsupported: FSM coverage on enum-typed state "
"variables wider than 32 bits");
casep->v3warn(COVERIGN, "Ignoring unsupported: FSM coverage on enum-typed state "
"variables wider than 32 bits");
return;
}
for (AstEnumItem* itemp = enump->itemsp(); itemp; itemp = VN_AS(itemp->nextp(), EnumItem)) {
for (AstEnumItem* itemp = enump->itemsp(); itemp;
itemp = VN_AS(itemp->nextp(), EnumItem)) {
const AstConst* const constp = VN_AS(itemp->valuep(), Const);
const int value = constp->toSInt();
states.emplace_back(itemp->name(), value);
@ -491,7 +488,8 @@ class FsmDetectVisitor final : public VNVisitor {
entry.graphp->addStateVertex(state.first, state.second);
}
}
for (AstCaseItem* itemp = casep->itemsp(); itemp; itemp = VN_AS(itemp->nextp(), CaseItem)) {
for (AstCaseItem* itemp = casep->itemsp(); itemp;
itemp = VN_AS(itemp->nextp(), CaseItem)) {
emitCaseItemArcs(*entry.graphp, itemp, stateVscp, labels, entry.graphp->inclCond());
}
}
@ -508,12 +506,13 @@ class FsmDetectVisitor final : public VNVisitor {
AstIf* const firstIfp = VN_CAST(stmtsp, If);
if (firstIfp) {
if (AstCase* const casep = VN_CAST(firstIfp->elsesp(), Case)) {
candidates.emplace_back(casep, isSimpleResetCond(firstIfp->condp()) ? firstIfp->condp()
: nullptr);
candidates.emplace_back(
casep, isSimpleResetCond(firstIfp->condp()) ? firstIfp->condp() : nullptr);
}
}
for (AstNode* nodep = stmtsp; nodep; nodep = nodep->nextp()) {
if (AstCase* const casep = VN_CAST(nodep, Case)) candidates.emplace_back(casep, nullptr);
if (AstCase* const casep = VN_CAST(nodep, Case))
candidates.emplace_back(casep, nullptr);
}
if (candidates.empty()) return;
@ -531,11 +530,10 @@ class FsmDetectVisitor final : public VNVisitor {
"the same always block. Only the first candidate will be "
"instrumented.");
} else {
cand.first->v3warn(
COVERIGN,
"Ignoring unsupported: FSM coverage on multiple supported case "
"statements found in the same always block. Only the first "
"candidate will be instrumented.");
cand.first->v3warn(COVERIGN,
"Ignoring unsupported: FSM coverage on multiple supported case "
"statements found in the same always block. Only the first "
"candidate will be instrumented.");
}
}
@ -608,13 +606,12 @@ class FsmLowerVisitor final {
// Rebuild the original event control from the saved sense description so
// post-state coverage sampling runs on the same triggering edges.
static AstSenTree* buildSenTree(
FileLine* flp, const std::vector<FsmSenDesc>& senses) {
static AstSenTree* buildSenTree(FileLine* flp, const std::vector<FsmSenDesc>& senses) {
AstSenTree* const sentreep = new AstSenTree{flp, nullptr};
for (const FsmSenDesc& sense : senses) {
AstSenItem* const senItemp = new AstSenItem{
flp, VEdgeType{sense.edgeType},
new AstVarRef{flp, sense.varScopep, VAccess::READ}};
AstSenItem* const senItemp
= new AstSenItem{flp, VEdgeType{sense.edgeType},
new AstVarRef{flp, sense.varScopep, VAccess::READ}};
sentreep->addSensesp(senItemp);
}
return sentreep;
@ -629,9 +626,8 @@ class FsmLowerVisitor final {
AstVarScope* const stateVscp = graph.stateVarScopep();
FileLine* const flp = graph.fileline();
AstNodeModule* const modp = scopep->modp();
AstNodeDType* const prevDTypep
= scopep->findLogicDType(stateVscp->width(), stateVscp->width(),
stateVscp->dtypep()->numeric());
AstNodeDType* const prevDTypep = scopep->findLogicDType(
stateVscp->width(), stateVscp->width(), stateVscp->dtypep()->numeric());
AstVarScope* const prevVscp
= scopep->createTemp("__Vfsmcov_prev__" + stateVscp->varp()->shortName(), prevDTypep);
// The saved previous-state temp crosses the scheduler's pre/post split
@ -667,10 +663,15 @@ class FsmLowerVisitor final {
const FsmStateVertex* const statep = vtx.as<FsmStateVertex>();
// State coverage fires when the FSM enters a state from any other
// value, so repeated self-holds do not count as new entries.
AstCoverOtherDecl* const declp = new AstCoverOtherDecl{
flp, "v_fsm_state/" + modp->prettyName(),
graph.stateVarName() + "::" + statep->label(), "", 0, graph.stateVarName(), "",
statep->label()};
AstCoverOtherDecl* const declp
= new AstCoverOtherDecl{flp,
"v_fsm_state/" + modp->prettyName(),
graph.stateVarName() + "::" + statep->label(),
"",
0,
graph.stateVarName(),
"",
statep->label()};
declp->hier(scopep->prettyName());
modp->addStmtsp(declp);
AstNodeExpr* const guardp
@ -691,21 +692,23 @@ class FsmLowerVisitor final {
// reset and synthetic-default sources, so reports match the
// reviewer-visible graph dump and the user-visible annotation.
const string resetTag
= arcp->isReset() ? (graph.resetInclude() ? "[reset_include]" : "[reset]") : "";
const string fsmTag = arcp->isReset() ? (graph.resetInclude() ? "reset_include"
: "reset")
: arcp->isDefault() ? "default"
: "";
AstCoverOtherDecl* const declp = new AstCoverOtherDecl{
flp, "v_fsm_arc/" + modp->prettyName(),
graph.stateVarName() + "::" + fromVertexp->label() + "->" + toStatep->label()
+ resetTag,
"",
0,
graph.stateVarName(),
fromVertexp->label(),
toStatep->label(),
fsmTag};
= arcp->isReset() ? (graph.resetInclude() ? "[reset_include]" : "[reset]")
: "";
const string fsmTag = arcp->isReset()
? (graph.resetInclude() ? "reset_include" : "reset")
: arcp->isDefault() ? "default"
: "";
AstCoverOtherDecl* const declp
= new AstCoverOtherDecl{flp,
"v_fsm_arc/" + modp->prettyName(),
graph.stateVarName() + "::" + fromVertexp->label()
+ "->" + toStatep->label() + resetTag,
"",
0,
graph.stateVarName(),
fromVertexp->label(),
toStatep->label(),
fsmTag};
declp->hier(scopep->prettyName());
modp->addStmtsp(declp);
AstNodeExpr* guardp = nullptr;
@ -733,12 +736,12 @@ class FsmLowerVisitor final {
new AstEq{flp, new AstVarRef{flp, stateVscp, VAccess::READ},
makeStateConst(flp, stateVscp, toStatep->value())});
} else {
guardp = andExpr(
flp,
new AstEq{flp, new AstVarRef{flp, prevVscp, VAccess::READ},
makeStateConst(flp, prevVscp, fromVertexp->value())},
new AstEq{flp, new AstVarRef{flp, stateVscp, VAccess::READ},
makeStateConst(flp, stateVscp, toStatep->value())});
guardp
= andExpr(flp,
new AstEq{flp, new AstVarRef{flp, prevVscp, VAccess::READ},
makeStateConst(flp, prevVscp, fromVertexp->value())},
new AstEq{flp, new AstVarRef{flp, stateVscp, VAccess::READ},
makeStateConst(flp, stateVscp, toStatep->value())});
}
covPostp->addStmtsp(new AstIf{flp, guardp, new AstCoverInc{flp, declp}});
}

View File

@ -448,8 +448,7 @@ private:
void optimize(int level);
void showVersion(bool verbose);
void coverage(bool flag) {
m_coverageLine = m_coverageToggle = m_coverageExpr = m_coverageFsm = m_coverageUser
= flag;
m_coverageLine = m_coverageToggle = m_coverageExpr = m_coverageFsm = m_coverageUser = flag;
}
static bool suffixed(const string& sw, const char* arg);
static string parseFileArg(const string& optdir, const string& relfilename);

View File

@ -54,8 +54,8 @@
#include "V3Expand.h"
#include "V3File.h"
#include "V3Force.h"
#include "V3FsmDetect.h"
#include "V3Fork.h"
#include "V3FsmDetect.h"
#include "V3FuncOpt.h"
#include "V3Gate.h"
#include "V3Global.h"

0
test_regress/t/t_cover_fsm_basic.py Normal file → Executable file
View File

0
test_regress/t/t_cover_fsm_beginif.py Normal file → Executable file
View File

10
test_regress/t/t_cover_fsm_decldump.py Normal file → Executable file
View File

@ -25,12 +25,8 @@ tree_texts = [filename.read_text(encoding="utf8") for filename in tree_files]
assert any("COVEROTHERDECL" in text and " fv=t.state" in text for text in tree_texts)
assert any(
"COVEROTHERDECL" in text and " ff=ANY" in text and " ft=S0" in text and " fg=reset" in text
for text in tree_texts
)
assert any(
"COVEROTHERDECL" in text and " ff=default" in text and " ft=S0" in text and " fg=default"
in text
for text in tree_texts
)
for text in tree_texts)
assert any("COVEROTHERDECL" in text and " ff=default" in text and " ft=S0" in text
and " fg=default" in text for text in tree_texts)
test.passes()

4
test_regress/t/t_cover_fsm_enum_bad.py Normal file → Executable file
View File

@ -14,9 +14,7 @@ test.scenarios('vlt')
# When an enum-backed FSM assigns a constant that is not one of the declared
# enum items, FSM coverage should warn and skip the unsupported edge rather
# than turning optional coverage into a hard compile failure.
test.lint(
verilator_flags2=["--coverage-fsm"],
fails=True)
test.lint(verilator_flags2=["--coverage-fsm"], fails=True)
test.file_grep(
test.compile_log_filename,

4
test_regress/t/t_cover_fsm_enumwide_bad.py Normal file → Executable file
View File

@ -13,9 +13,7 @@ test.scenarios('vlt')
# FSM coverage currently stores recovered enum state values in the detector's
# 32-bit internal representation, so wider enum-backed FSMs are rejected.
test.lint(
verilator_flags2=["--coverage-fsm"],
fails=True)
test.lint(verilator_flags2=["--coverage-fsm"], fails=True)
test.file_grep(
test.compile_log_filename,

0
test_regress/t/t_cover_fsm_flag_off.py Normal file → Executable file
View File

0
test_regress/t/t_cover_fsm_forced.py Normal file → Executable file
View File

0
test_regress/t/t_cover_fsm_graphdump.py Normal file → Executable file
View File

0
test_regress/t/t_cover_fsm_negative_extract.py Normal file → Executable file
View File

0
test_regress/t/t_cover_fsm_noreset.py Normal file → Executable file
View File

0
test_regress/t/t_cover_fsm_reset.py Normal file → Executable file
View File

0
test_regress/t/t_cover_fsm_reset_multi.py Normal file → Executable file
View File

0
test_regress/t/t_cover_fsm_styles.py Normal file → Executable file
View File

5
test_regress/t/t_cover_otherdecl_dump.py Normal file → Executable file
View File

@ -24,9 +24,8 @@ tree_texts = [filename.read_text(encoding="utf8") for filename in tree_files]
generic_lines = []
for text in tree_texts:
generic_lines.extend(
line for line in text.splitlines() if "COVEROTHERDECL" in line and " page=v_line/" in line
)
generic_lines.extend(line for line in text.splitlines()
if "COVEROTHERDECL" in line and " page=v_line/" in line)
assert generic_lines
assert any(" fv=" not in line and " ff=" not in line and " ft=" not in line and " fg=" not in line

0
test_regress/t/t_fsm_metacmt_dump.py Normal file → Executable file
View File

4
test_regress/t/t_fsmmulti_same_bad.py Normal file → Executable file
View File

@ -15,9 +15,7 @@ test.scenarios('vlt')
# always_ff now warn and keep only the first candidate instrumented. Different-
# state multi-candidate cases still use the existing FSMMULTI warning path; this
# test locks down only the same-state unsupported form.
test.lint(
verilator_flags2=["--coverage-fsm"],
fails=True)
test.lint(verilator_flags2=["--coverage-fsm"], fails=True)
test.file_grep(
test.compile_log_filename,

5
test_regress/t/t_fsmmulti_warn_bad.py Normal file → Executable file
View File

@ -11,9 +11,6 @@ import vltest_bootstrap
test.scenarios('vlt')
test.lint(
verilator_flags2=["--coverage-fsm"],
fails=True,
expect_filename=test.golden_filename)
test.lint(verilator_flags2=["--coverage-fsm"], fails=True, expect_filename=test.golden_filename)
test.passes()

0
test_regress/t/t_fsmmulti_warn_off.py Normal file → Executable file
View File

0
test_regress/t/t_vlcov_fsm_report.py Normal file → Executable file
View File