Internals: Add more const. No functional change intended.
This commit is contained in:
parent
4cb5c1e1db
commit
37e3c6da70
|
|
@ -108,9 +108,10 @@ protected:
|
|||
}
|
||||
break;
|
||||
case LatchDetectGraphVertex::VT_BRANCH: // (AND of both sibling)
|
||||
// A BRANCH vertex always has exactly 2 siblings
|
||||
LatchDetectGraphVertex* ifp = castVertexp(vertexp->outBeginp()->top());
|
||||
LatchDetectGraphVertex* elsp = castVertexp(vertexp->outBeginp()->outNextp()->top());
|
||||
// A BRANCH vertex always has exactly 2 siblings
|
||||
LatchDetectGraphVertex* const ifp = castVertexp(vertexp->outBeginp()->top());
|
||||
LatchDetectGraphVertex* const elsp
|
||||
= castVertexp(vertexp->outBeginp()->outNextp()->top());
|
||||
result = latchCheckInternal(ifp) && latchCheckInternal(elsp);
|
||||
break;
|
||||
}
|
||||
|
|
@ -151,7 +152,7 @@ public:
|
|||
// Add a new output variable vertex and store a pointer to it in the user1 field of the
|
||||
// variables AstNode
|
||||
LatchDetectGraphVertex* addOutputVertex(AstVarRef* nodep) {
|
||||
LatchDetectGraphVertex* outVertexp
|
||||
LatchDetectGraphVertex* const outVertexp
|
||||
= new LatchDetectGraphVertex{this, nodep->name(), LatchDetectGraphVertex::VT_OUTPUT};
|
||||
nodep->varp()->user1p(outVertexp);
|
||||
m_outputs.push_back(nodep);
|
||||
|
|
@ -172,7 +173,7 @@ public:
|
|||
void latchCheck(AstNode* nodep, bool latch_expected) {
|
||||
bool latch_detected = false;
|
||||
for (const auto& vrp : m_outputs) {
|
||||
LatchDetectGraphVertex* vertp = castVertexp(vrp->varp()->user1p());
|
||||
LatchDetectGraphVertex* const vertp = castVertexp(vrp->varp()->user1p());
|
||||
vertp->user(true); // Identify the output vertex we are checking paths _to_
|
||||
if (!latchCheckInternal(castVertexp(verticesBeginp()))) latch_detected = true;
|
||||
if (latch_detected && !latch_expected) {
|
||||
|
|
@ -262,7 +263,7 @@ public:
|
|||
// Return a sentree in this scope that matches given sense list.
|
||||
|
||||
AstActive* activep = nullptr;
|
||||
AstSenTree* activeSenp = m_activeSens.find(sensesp);
|
||||
AstSenTree* const activeSenp = m_activeSens.find(sensesp);
|
||||
if (activeSenp) {
|
||||
const auto it = m_activeMap.find(activeSenp);
|
||||
UASSERT(it != m_activeMap.end(), "Corrupt active map");
|
||||
|
|
@ -271,7 +272,7 @@ public:
|
|||
|
||||
// Not found, form a new one
|
||||
if (!activep) {
|
||||
AstSenTree* newsenp = sensesp->cloneTree(false);
|
||||
AstSenTree* const newsenp = sensesp->cloneTree(false);
|
||||
activep = new AstActive(fl, "sequent", newsenp);
|
||||
activep->sensesStorep(activep->sensesp());
|
||||
UINFO(8, " New ACTIVE " << activep << endl);
|
||||
|
|
@ -303,15 +304,15 @@ private:
|
|||
LatchDetectGraph m_graph; // Graph used to detect latches in combo always
|
||||
// VISITORS
|
||||
virtual void visit(AstVarRef* nodep) {
|
||||
AstVar* varp = nodep->varp();
|
||||
const AstVar* const varp = nodep->varp();
|
||||
if (nodep->access().isWriteOrRW() && varp->isSignal() && !varp->isUsedLoopIdx()) {
|
||||
m_graph.addAssignment(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeIf* nodep) {
|
||||
if (!nodep->isBoundsCheck()) {
|
||||
LatchDetectGraphVertex* parentp = m_graph.currentp();
|
||||
LatchDetectGraphVertex* branchp = m_graph.addPathVertex(parentp, "BRANCH", true);
|
||||
LatchDetectGraphVertex* const parentp = m_graph.currentp();
|
||||
LatchDetectGraphVertex* const branchp = m_graph.addPathVertex(parentp, "BRANCH", true);
|
||||
m_graph.addPathVertex(branchp, "IF");
|
||||
iterateAndNextNull(nodep->ifsp());
|
||||
m_graph.addPathVertex(branchp, "ELSE");
|
||||
|
|
@ -340,8 +341,8 @@ public:
|
|||
enum CheckType : uint8_t { CT_SEQ, CT_COMBO, CT_INITIAL, CT_LATCH };
|
||||
|
||||
private:
|
||||
CheckType m_check; // Combo logic or other
|
||||
AstNode* m_alwaysp; // Always we're under
|
||||
const CheckType m_check; // Combo logic or other
|
||||
AstNode* const m_alwaysp; // Always we're under
|
||||
AstNode* m_assignp = nullptr; // In assign
|
||||
// VISITORS
|
||||
virtual void visit(AstAssignDly* nodep) override {
|
||||
|
|
@ -363,8 +364,8 @@ private:
|
|||
// Conversely, we could also suggest latches use delayed assignments, as
|
||||
// recommended by Cliff Cummings?
|
||||
}
|
||||
AstNode* newp = new AstAssign(nodep->fileline(), nodep->lhsp()->unlinkFrBack(),
|
||||
nodep->rhsp()->unlinkFrBack());
|
||||
AstNode* const newp = new AstAssign(nodep->fileline(), nodep->lhsp()->unlinkFrBack(),
|
||||
nodep->rhsp()->unlinkFrBack());
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
|
|
@ -377,7 +378,7 @@ private:
|
|||
}
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
AstVar* varp = nodep->varp();
|
||||
const AstVar* const varp = nodep->varp();
|
||||
if (m_check == CT_SEQ && m_assignp && !varp->isUsedLoopIdx() // Ignore loop indices
|
||||
&& !varp->isTemp()) {
|
||||
// Allow turning off warnings on the always, or the variable also
|
||||
|
|
@ -438,28 +439,28 @@ private:
|
|||
// Relink to IACTIVE, unless already under it
|
||||
UINFO(4, " INITIAL " << nodep << endl);
|
||||
ActiveDlyVisitor dlyvisitor{nodep, ActiveDlyVisitor::CT_INITIAL};
|
||||
AstActive* wantactivep = m_namer.getIActive(nodep->fileline());
|
||||
AstActive* const wantactivep = m_namer.getIActive(nodep->fileline());
|
||||
nodep->unlinkFrBack();
|
||||
wantactivep->addStmtsp(nodep);
|
||||
}
|
||||
virtual void visit(AstAssignAlias* nodep) override {
|
||||
// Relink to CACTIVE, unless already under it
|
||||
UINFO(4, " ASSIGNW " << nodep << endl);
|
||||
AstActive* wantactivep = m_namer.getCActive(nodep->fileline());
|
||||
AstActive* const wantactivep = m_namer.getCActive(nodep->fileline());
|
||||
nodep->unlinkFrBack();
|
||||
wantactivep->addStmtsp(nodep);
|
||||
}
|
||||
virtual void visit(AstAssignW* nodep) override {
|
||||
// Relink to CACTIVE, unless already under it
|
||||
UINFO(4, " ASSIGNW " << nodep << endl);
|
||||
AstActive* wantactivep = m_namer.getCActive(nodep->fileline());
|
||||
AstActive* const wantactivep = m_namer.getCActive(nodep->fileline());
|
||||
nodep->unlinkFrBack();
|
||||
wantactivep->addStmtsp(nodep);
|
||||
}
|
||||
virtual void visit(AstCoverToggle* nodep) override {
|
||||
// Relink to CACTIVE, unless already under it
|
||||
UINFO(4, " COVERTOGGLE " << nodep << endl);
|
||||
AstActive* wantactivep = m_namer.getCActive(nodep->fileline());
|
||||
AstActive* const wantactivep = m_namer.getCActive(nodep->fileline());
|
||||
nodep->unlinkFrBack();
|
||||
wantactivep->addStmtsp(nodep);
|
||||
}
|
||||
|
|
@ -577,7 +578,7 @@ private:
|
|||
}
|
||||
virtual void visit(AstSenItem* nodep) override {
|
||||
if (nodep->varrefp()) {
|
||||
if (AstBasicDType* basicp = nodep->varrefp()->dtypep()->basicp()) {
|
||||
if (const AstBasicDType* const basicp = nodep->varrefp()->dtypep()->basicp()) {
|
||||
if (basicp->isEventValue()) {
|
||||
// Events need to be treated as active high so we only activate on event being
|
||||
// 1
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ private:
|
|||
UINFO(4, " ACTIVE " << nodep << endl);
|
||||
// Remove duplicate clocks and such; sensesp() may change!
|
||||
V3Const::constifyExpensiveEdit(nodep);
|
||||
AstSenTree* sensesp = nodep->sensesp();
|
||||
AstSenTree* const sensesp = nodep->sensesp();
|
||||
UASSERT_OBJ(sensesp, nodep, "nullptr");
|
||||
if (sensesp->sensesp() && sensesp->sensesp()->isNever()) {
|
||||
// Never executing. Kill it.
|
||||
|
|
@ -72,16 +72,16 @@ private:
|
|||
}
|
||||
// Copy combo tree to settlement tree with duplicated statements
|
||||
if (sensesp->hasCombo()) {
|
||||
AstSenTree* newsentreep = new AstSenTree(
|
||||
AstSenTree* const newsentreep = new AstSenTree(
|
||||
nodep->fileline(), new AstSenItem(nodep->fileline(), AstSenItem::Settle()));
|
||||
AstActive* newp = new AstActive(nodep->fileline(), "settle", newsentreep);
|
||||
AstActive* const newp = new AstActive(nodep->fileline(), "settle", newsentreep);
|
||||
newp->sensesStorep(newsentreep);
|
||||
if (nodep->stmtsp()) newp->addStmtsp(nodep->stmtsp()->cloneTree(true));
|
||||
nodep->addNextHere(newp);
|
||||
}
|
||||
// Move the SENTREE for each active up to the global level.
|
||||
// This way we'll easily see what clock domains are identical
|
||||
AstSenTree* wantp = m_finder.getSenTree(sensesp);
|
||||
AstSenTree* const wantp = m_finder.getSenTree(sensesp);
|
||||
UINFO(4, " lookdone\n");
|
||||
if (wantp != sensesp) {
|
||||
// Move the active's contents to the other active
|
||||
|
|
|
|||
|
|
@ -56,8 +56,8 @@ private:
|
|||
nodep->displayType(AstDisplayType::DT_WRITE);
|
||||
nodep->fmtp()->text(assertDisplayMessage(nodep, prefix, nodep->fmtp()->text()));
|
||||
// cppcheck-suppress nullPointer
|
||||
AstNode* timenewp = new AstTime(nodep->fileline(), m_modp->timeunit());
|
||||
if (AstNode* timesp = nodep->fmtp()->exprsp()) {
|
||||
AstNode* const timenewp = new AstTime(nodep->fileline(), m_modp->timeunit());
|
||||
if (AstNode* const timesp = nodep->fmtp()->exprsp()) {
|
||||
timesp->unlinkFrBackWithNext();
|
||||
timenewp->addNext(timesp);
|
||||
}
|
||||
|
|
@ -89,8 +89,8 @@ private:
|
|||
AstNode* newIfAssertOn(AstNode* nodep, bool force) {
|
||||
// Add a internal if to check assertions are on.
|
||||
// Don't make this a AND term, as it's unlikely to need to test this.
|
||||
FileLine* fl = nodep->fileline();
|
||||
AstNode* newp = new AstIf(
|
||||
FileLine* const fl = nodep->fileline();
|
||||
AstNode* const newp = new AstIf(
|
||||
fl,
|
||||
(force ? new AstConst(fl, AstConst::BitTrue())
|
||||
: // If assertions are off, have constant propagation rip them out later
|
||||
|
|
@ -106,10 +106,10 @@ private:
|
|||
|
||||
AstNode* newFireAssertUnchecked(AstNode* nodep, const string& message) {
|
||||
// Like newFireAssert() but omits the asserts-on check
|
||||
AstDisplay* dispp = new AstDisplay(nodep->fileline(), AstDisplayType::DT_ERROR, message,
|
||||
nullptr, nullptr);
|
||||
AstDisplay* const dispp = new AstDisplay(nodep->fileline(), AstDisplayType::DT_ERROR,
|
||||
message, nullptr, nullptr);
|
||||
dispp->fmtp()->timeunit(m_modp->timeunit());
|
||||
AstNode* bodysp = dispp;
|
||||
AstNode* const bodysp = dispp;
|
||||
replaceDisplay(dispp, "%%Error"); // Convert to standard DISPLAY format
|
||||
bodysp->addNext(new AstStop(nodep->fileline(), true));
|
||||
return bodysp;
|
||||
|
|
@ -124,8 +124,8 @@ private:
|
|||
void newPslAssertion(AstNodeCoverOrAssert* nodep, AstNode* failsp) {
|
||||
if (m_beginp && nodep->name() == "") nodep->name(m_beginp->name());
|
||||
|
||||
AstNode* propp = nodep->propp()->unlinkFrBackWithNext();
|
||||
AstSenTree* sentreep = nodep->sentreep();
|
||||
AstNode* const propp = nodep->propp()->unlinkFrBackWithNext();
|
||||
AstSenTree* const sentreep = nodep->sentreep();
|
||||
const string& message = nodep->name();
|
||||
AstNode* passsp = nodep->passsp();
|
||||
if (passsp) passsp->unlinkFrBackWithNext();
|
||||
|
|
@ -141,13 +141,13 @@ private:
|
|||
AstNode* bodysp = nullptr;
|
||||
bool selfDestruct = false;
|
||||
AstIf* ifp = nullptr;
|
||||
if (AstCover* snodep = VN_CAST(nodep, Cover)) {
|
||||
if (const AstCover* const snodep = VN_CAST(nodep, Cover)) {
|
||||
++m_statCover;
|
||||
if (!v3Global.opt.coverageUser()) {
|
||||
selfDestruct = true;
|
||||
} else {
|
||||
// V3Coverage assigned us a bucket to increment.
|
||||
AstCoverInc* covincp = VN_AS(snodep->coverincp(), CoverInc);
|
||||
AstCoverInc* const covincp = VN_AS(snodep->coverincp(), CoverInc);
|
||||
UASSERT_OBJ(covincp, snodep, "Missing AstCoverInc under assertion");
|
||||
covincp->unlinkFrBackWithNext(); // next() might have AstAssign for trace
|
||||
if (message != "") covincp->declp()->comment(message);
|
||||
|
|
@ -199,13 +199,13 @@ private:
|
|||
virtual void visit(AstIf* nodep) override {
|
||||
if (nodep->user1SetOnce()) return;
|
||||
if (nodep->uniquePragma() || nodep->unique0Pragma()) {
|
||||
AstNodeIf* ifp = nodep;
|
||||
const AstNodeIf* ifp = nodep;
|
||||
AstNode* propp = nullptr;
|
||||
bool hasDefaultElse = false;
|
||||
do {
|
||||
// If this statement ends with 'else if', then nextIf will point to the
|
||||
// nextIf statement. Otherwise it will be null.
|
||||
AstNodeIf* nextifp = dynamic_cast<AstNodeIf*>(ifp->elsesp());
|
||||
const AstNodeIf* const nextifp = dynamic_cast<AstNodeIf*>(ifp->elsesp());
|
||||
iterateAndNextNull(ifp->condp());
|
||||
|
||||
// Recurse into the true case.
|
||||
|
|
@ -217,7 +217,7 @@ private:
|
|||
}
|
||||
|
||||
// Build a bitmask of the true predicates
|
||||
AstNode* predp = ifp->condp()->cloneTree(false);
|
||||
AstNode* const predp = ifp->condp()->cloneTree(false);
|
||||
if (propp) {
|
||||
propp = new AstConcat(nodep->fileline(), predp, propp);
|
||||
} else {
|
||||
|
|
@ -230,7 +230,7 @@ private:
|
|||
ifp = nextifp;
|
||||
} while (ifp);
|
||||
|
||||
AstNode* newifp = nodep->cloneTree(false);
|
||||
AstNode* const newifp = nodep->cloneTree(false);
|
||||
const bool allow_none = nodep->unique0Pragma();
|
||||
|
||||
// Empty case means no property
|
||||
|
|
@ -238,10 +238,11 @@ private:
|
|||
|
||||
// Note: if this ends with an 'else', then we don't need to validate that one of the
|
||||
// predicates evaluates to true.
|
||||
AstNode* ohot = ((allow_none || hasDefaultElse)
|
||||
? static_cast<AstNode*>(new AstOneHot0(nodep->fileline(), propp))
|
||||
: static_cast<AstNode*>(new AstOneHot(nodep->fileline(), propp)));
|
||||
AstIf* checkifp
|
||||
AstNode* const ohot
|
||||
= ((allow_none || hasDefaultElse)
|
||||
? static_cast<AstNode*>(new AstOneHot0(nodep->fileline(), propp))
|
||||
: static_cast<AstNode*>(new AstOneHot(nodep->fileline(), propp)));
|
||||
AstIf* const checkifp
|
||||
= new AstIf(nodep->fileline(), new AstLogNot(nodep->fileline(), ohot),
|
||||
newFireAssert(nodep, "'unique if' statement violated"), newifp);
|
||||
checkifp->branchPred(VBranchPred::BP_UNLIKELY);
|
||||
|
|
@ -282,7 +283,7 @@ private:
|
|||
itemp = VN_AS(itemp->nextp(), CaseItem)) {
|
||||
for (AstNode* icondp = itemp->condsp(); icondp; icondp = icondp->nextp()) {
|
||||
AstNode* onep;
|
||||
if (AstInsideRange* rcondp = VN_CAST(icondp, InsideRange)) {
|
||||
if (AstInsideRange* const rcondp = VN_CAST(icondp, InsideRange)) {
|
||||
onep = rcondp->newAndFromInside(nodep->exprp(),
|
||||
rcondp->lhsp()->cloneTree(true),
|
||||
rcondp->rhsp()->cloneTree(true));
|
||||
|
|
@ -306,11 +307,11 @@ private:
|
|||
if (!propp) propp = new AstConst(nodep->fileline(), AstConst::BitFalse());
|
||||
|
||||
const bool allow_none = has_default || nodep->unique0Pragma();
|
||||
AstNode* ohot
|
||||
AstNode* const ohot
|
||||
= (allow_none
|
||||
? static_cast<AstNode*>(new AstOneHot0(nodep->fileline(), propp))
|
||||
: static_cast<AstNode*>(new AstOneHot(nodep->fileline(), propp)));
|
||||
AstIf* ifp = new AstIf(
|
||||
AstIf* const ifp = new AstIf(
|
||||
nodep->fileline(), new AstLogNot(nodep->fileline(), ohot),
|
||||
newFireAssert(nodep,
|
||||
"synthesis parallel_case, but multiple matches found"),
|
||||
|
|
@ -334,17 +335,17 @@ private:
|
|||
UASSERT_OBJ(ticks >= 1, nodep, "0 tick should have been checked in V3Width");
|
||||
AstNode* inp = nodep->exprp()->unlinkFrBack();
|
||||
AstVar* invarp = nullptr;
|
||||
AstSenTree* sentreep = nodep->sentreep();
|
||||
AstSenTree* const sentreep = nodep->sentreep();
|
||||
sentreep->unlinkFrBack();
|
||||
AstAlways* alwaysp
|
||||
AstAlways* const alwaysp
|
||||
= new AstAlways(nodep->fileline(), VAlwaysKwd::ALWAYS, sentreep, nullptr);
|
||||
m_modp->addStmtp(alwaysp);
|
||||
for (uint32_t i = 0; i < ticks; ++i) {
|
||||
AstVar* outvarp = new AstVar(nodep->fileline(), AstVarType::MODULETEMP,
|
||||
"_Vpast_" + cvtToStr(m_modPastNum++) + "_" + cvtToStr(i),
|
||||
inp->dtypep());
|
||||
AstVar* const outvarp = new AstVar(
|
||||
nodep->fileline(), AstVarType::MODULETEMP,
|
||||
"_Vpast_" + cvtToStr(m_modPastNum++) + "_" + cvtToStr(i), inp->dtypep());
|
||||
m_modp->addStmtp(outvarp);
|
||||
AstNode* assp = new AstAssignDly(
|
||||
AstNode* const assp = new AstAssignDly(
|
||||
nodep->fileline(), new AstVarRef(nodep->fileline(), outvarp, VAccess::WRITE), inp);
|
||||
alwaysp->addStmtp(assp);
|
||||
// if (debug() >= 9) assp->dumpTree(cout, "-ass: ");
|
||||
|
|
@ -378,15 +379,15 @@ private:
|
|||
new AstConst{fl, monNum}};
|
||||
nodep->replaceWith(newsetp);
|
||||
// Add "always_comb if (__VmonitorOn && __VmonitorNum==N) $display(...);"
|
||||
AstNode* stmtsp = nodep;
|
||||
AstIf* ifp = new AstIf{
|
||||
AstNode* const stmtsp = nodep;
|
||||
AstIf* const ifp = new AstIf{
|
||||
fl,
|
||||
new AstLogAnd{fl, new AstLogNot{fl, newMonitorOffVarRefp(nodep, VAccess::READ)},
|
||||
new AstEq{fl, new AstConst{fl, monNum},
|
||||
newMonitorNumVarRefp(nodep, VAccess::READ)}},
|
||||
stmtsp, nullptr};
|
||||
ifp->branchPred(VBranchPred::BP_UNLIKELY);
|
||||
AstNode* newp = new AstAlwaysPostponed{fl, ifp};
|
||||
AstNode* const newp = new AstAlwaysPostponed{fl, ifp};
|
||||
m_modp->addStmtp(newp);
|
||||
} else if (nodep->displayType() == AstDisplayType::DT_STROBE) {
|
||||
nodep->displayType(AstDisplayType::DT_DISPLAY);
|
||||
|
|
@ -401,10 +402,11 @@ private:
|
|||
new AstConst{fl, AstConst::BitTrue{}}};
|
||||
nodep->replaceWith(newsetp);
|
||||
// Add "always_comb if (__Vstrobe) begin $display(...); __Vstrobe = '0; end"
|
||||
AstNode* stmtsp = nodep;
|
||||
AstIf* ifp = new AstIf{fl, new AstVarRef{fl, varp, VAccess::READ}, stmtsp, nullptr};
|
||||
AstNode* const stmtsp = nodep;
|
||||
AstIf* const ifp
|
||||
= new AstIf{fl, new AstVarRef{fl, varp, VAccess::READ}, stmtsp, nullptr};
|
||||
ifp->branchPred(VBranchPred::BP_UNLIKELY);
|
||||
AstNode* newp = new AstAlwaysPostponed{fl, ifp};
|
||||
AstNode* const newp = new AstAlwaysPostponed{fl, ifp};
|
||||
stmtsp->addNext(new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE},
|
||||
new AstConst{fl, AstConst::BitFalse{}}});
|
||||
m_modp->addStmtp(newp);
|
||||
|
|
|
|||
|
|
@ -97,10 +97,10 @@ private:
|
|||
virtual void visit(AstFell* nodep) override {
|
||||
if (nodep->sentreep()) return; // Already processed
|
||||
iterateChildren(nodep);
|
||||
FileLine* fl = nodep->fileline();
|
||||
FileLine* const fl = nodep->fileline();
|
||||
AstNode* exprp = nodep->exprp()->unlinkFrBack();
|
||||
if (exprp->width() > 1) exprp = new AstSel(fl, exprp, 0, 1);
|
||||
AstNode* past = new AstPast(fl, exprp, nullptr);
|
||||
AstNode* const past = new AstPast(fl, exprp, nullptr);
|
||||
past->dtypeFrom(exprp);
|
||||
exprp = new AstAnd(fl, past, new AstNot(fl, exprp->cloneTree(false)));
|
||||
exprp->dtypeSetBit();
|
||||
|
|
@ -116,10 +116,10 @@ private:
|
|||
virtual void visit(AstRose* nodep) override {
|
||||
if (nodep->sentreep()) return; // Already processed
|
||||
iterateChildren(nodep);
|
||||
FileLine* fl = nodep->fileline();
|
||||
FileLine* const fl = nodep->fileline();
|
||||
AstNode* exprp = nodep->exprp()->unlinkFrBack();
|
||||
if (exprp->width() > 1) exprp = new AstSel(fl, exprp, 0, 1);
|
||||
AstNode* past = new AstPast(fl, exprp, nullptr);
|
||||
AstNode* const past = new AstPast(fl, exprp, nullptr);
|
||||
past->dtypeFrom(exprp);
|
||||
exprp = new AstAnd(fl, new AstNot(fl, past), exprp->cloneTree(false));
|
||||
exprp->dtypeSetBit();
|
||||
|
|
@ -130,9 +130,9 @@ private:
|
|||
virtual void visit(AstStable* nodep) override {
|
||||
if (nodep->sentreep()) return; // Already processed
|
||||
iterateChildren(nodep);
|
||||
FileLine* fl = nodep->fileline();
|
||||
FileLine* const fl = nodep->fileline();
|
||||
AstNode* exprp = nodep->exprp()->unlinkFrBack();
|
||||
AstNode* past = new AstPast(fl, exprp, nullptr);
|
||||
AstNode* const past = new AstPast(fl, exprp, nullptr);
|
||||
past->dtypeFrom(exprp);
|
||||
exprp = new AstEq(fl, past, exprp->cloneTree(false));
|
||||
exprp->dtypeSetBit();
|
||||
|
|
@ -144,15 +144,15 @@ private:
|
|||
virtual void visit(AstImplication* nodep) override {
|
||||
if (nodep->sentreep()) return; // Already processed
|
||||
|
||||
FileLine* fl = nodep->fileline();
|
||||
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
|
||||
FileLine* const fl = nodep->fileline();
|
||||
AstNode* const rhsp = nodep->rhsp()->unlinkFrBack();
|
||||
AstNode* lhsp = nodep->lhsp()->unlinkFrBack();
|
||||
|
||||
if (m_disablep) lhsp = new AstAnd(fl, new AstNot(fl, m_disablep), lhsp);
|
||||
|
||||
AstNode* past = new AstPast(fl, lhsp, nullptr);
|
||||
AstNode* const past = new AstPast(fl, lhsp, nullptr);
|
||||
past->dtypeFrom(lhsp);
|
||||
AstNode* exprp = new AstOr(fl, new AstNot(fl, past), rhsp);
|
||||
AstNode* const exprp = new AstOr(fl, new AstNot(fl, past), rhsp);
|
||||
exprp->dtypeSetBit();
|
||||
nodep->replaceWith(exprp);
|
||||
nodep->sentreep(newSenTree(nodep));
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ AstNode* AstNode::abovep() const {
|
|||
// Avoid supporting at other locations as would require walking
|
||||
// list which is likely to cause performance issues.
|
||||
UASSERT_OBJ(!m_nextp || firstAbovep(), this, "abovep() not allowed when in midlist");
|
||||
const AstNode* firstp = firstAbovep() ? this : m_headtailp;
|
||||
const AstNode* const firstp = firstAbovep() ? this : m_headtailp;
|
||||
return firstp->backp();
|
||||
}
|
||||
|
||||
|
|
@ -277,8 +277,8 @@ AstNode* AstNode::addNext(AstNode* nodep, AstNode* newp) {
|
|||
oldtailp->m_nextp = newp;
|
||||
newp->m_backp = oldtailp;
|
||||
// New tail needs the head
|
||||
AstNode* newtailp = newp->m_headtailp;
|
||||
AstNode* headp = oldtailp->m_headtailp;
|
||||
AstNode* const newtailp = newp->m_headtailp;
|
||||
AstNode* const headp = oldtailp->m_headtailp;
|
||||
oldtailp->m_headtailp = nullptr; // May be written again as new head
|
||||
newp->m_headtailp = nullptr; // May be written again as new tail
|
||||
newtailp->m_headtailp = headp;
|
||||
|
|
@ -305,11 +305,11 @@ void AstNode::addNextHere(AstNode* newp) {
|
|||
debugTreeChange(newp, "-addHereNew: ", __LINE__, true);
|
||||
newp->editCountInc();
|
||||
|
||||
AstNode* addlastp = newp->m_headtailp; // Last node in list to be added
|
||||
AstNode* const addlastp = newp->m_headtailp; // Last node in list to be added
|
||||
UASSERT(!addlastp->m_nextp, "Headtailp tail isn't at the tail");
|
||||
|
||||
// Forward links
|
||||
AstNode* oldnextp = this->m_nextp;
|
||||
AstNode* const oldnextp = this->m_nextp;
|
||||
this->m_nextp = newp;
|
||||
addlastp->m_nextp = oldnextp; // Perhaps null if 'this' is not list
|
||||
|
||||
|
|
@ -318,7 +318,7 @@ void AstNode::addNextHere(AstNode* newp) {
|
|||
newp->m_backp = this;
|
||||
|
||||
// Head/tail
|
||||
AstNode* oldheadtailp = this->m_headtailp;
|
||||
AstNode* const oldheadtailp = this->m_headtailp;
|
||||
// (!oldheadtailp) // this was&is middle of list
|
||||
// (oldheadtailp==this && !oldnext)// this was head AND tail (one node long list)
|
||||
// (oldheadtailp && oldnextp) // this was&is head of list of not just one node, not
|
||||
|
|
@ -455,10 +455,10 @@ void AstNRelinker::dump(std::ostream& str) const {
|
|||
|
||||
AstNode* AstNode::unlinkFrBackWithNext(AstNRelinker* linkerp) {
|
||||
debugTreeChange(this, "-unlinkWNextThs: ", __LINE__, true);
|
||||
AstNode* oldp = this;
|
||||
AstNode* const oldp = this;
|
||||
UASSERT(oldp->m_backp, "Node has no back, already unlinked?");
|
||||
oldp->editCountInc();
|
||||
AstNode* backp = oldp->m_backp;
|
||||
AstNode* const backp = oldp->m_backp;
|
||||
if (linkerp) {
|
||||
linkerp->m_oldp = oldp;
|
||||
linkerp->m_backp = backp;
|
||||
|
|
@ -487,7 +487,7 @@ AstNode* AstNode::unlinkFrBackWithNext(AstNRelinker* linkerp) {
|
|||
AstNode* oldtailp = oldp;
|
||||
while (oldtailp->m_nextp) oldtailp = oldtailp->m_nextp;
|
||||
// Create new head/tail of old list
|
||||
AstNode* oldheadp = oldtailp->m_headtailp;
|
||||
AstNode* const oldheadp = oldtailp->m_headtailp;
|
||||
oldheadp->m_headtailp = oldp->m_backp;
|
||||
oldheadp->m_headtailp->m_headtailp = oldheadp;
|
||||
// Create new head/tail of extracted list
|
||||
|
|
@ -515,10 +515,10 @@ AstNode* AstNode::unlinkFrBackWithNext(AstNRelinker* linkerp) {
|
|||
|
||||
AstNode* AstNode::unlinkFrBack(AstNRelinker* linkerp) {
|
||||
debugTreeChange(this, "-unlinkFrBkThs: ", __LINE__, true);
|
||||
AstNode* oldp = this;
|
||||
AstNode* const oldp = this;
|
||||
UASSERT(oldp->m_backp, "Node has no back, already unlinked?");
|
||||
oldp->editCountInc();
|
||||
AstNode* backp = oldp->m_backp;
|
||||
AstNode* const backp = oldp->m_backp;
|
||||
if (linkerp) {
|
||||
linkerp->m_oldp = oldp;
|
||||
linkerp->m_backp = backp;
|
||||
|
|
@ -560,7 +560,7 @@ AstNode* AstNode::unlinkFrBack(AstNRelinker* linkerp) {
|
|||
this->v3fatalSrc("Unlink of node with back not pointing to it.");
|
||||
}
|
||||
if (oldp->m_nextp) {
|
||||
AstNode* newheadp = oldp->m_nextp;
|
||||
AstNode* const newheadp = oldp->m_nextp;
|
||||
newheadp->m_backp = backp;
|
||||
newheadp->m_headtailp = oldp->m_headtailp;
|
||||
newheadp->m_headtailp->m_headtailp = newheadp;
|
||||
|
|
@ -582,7 +582,7 @@ void AstNode::relink(AstNRelinker* linkerp) {
|
|||
UINFO(0, " EDIT: relink: ");
|
||||
dumpPtrs();
|
||||
}
|
||||
AstNode* newp = this;
|
||||
AstNode* const newp = this;
|
||||
UASSERT(linkerp && linkerp->m_backp, "Need non-empty linker");
|
||||
UASSERT(!newp->backp(), "New node already linked?");
|
||||
newp->editCountInc();
|
||||
|
|
@ -592,7 +592,7 @@ void AstNode::relink(AstNRelinker* linkerp) {
|
|||
cout << endl;
|
||||
}
|
||||
|
||||
AstNode* backp = linkerp->m_backp;
|
||||
AstNode* const backp = linkerp->m_backp;
|
||||
debugTreeChange(this, "-relinkNew: ", __LINE__, true);
|
||||
debugTreeChange(backp, "-relinkTre: ", __LINE__, true);
|
||||
|
||||
|
|
@ -631,10 +631,10 @@ void AstNode::relinkOneLink(AstNode*& pointpr, // Ref to pointer that gets set
|
|||
// Likewise there may be a old list.
|
||||
// Insert the whole old list following the new node's list.
|
||||
// Thus a unlink without next, followed by relink, gives the same list.
|
||||
AstNode* newlistlastp = newp->m_headtailp;
|
||||
AstNode* const newlistlastp = newp->m_headtailp;
|
||||
UASSERT_OBJ(!(newlistlastp->m_nextp && newlistlastp != newp), newp,
|
||||
"Headtailp tail isn't at the tail");
|
||||
AstNode* oldlistlastp = pointpr->m_headtailp;
|
||||
AstNode* const oldlistlastp = pointpr->m_headtailp;
|
||||
UASSERT_OBJ(!(oldlistlastp->m_nextp && oldlistlastp != pointpr), newp,
|
||||
"Old headtailp tail isn't at the tail");
|
||||
// Next links
|
||||
|
|
@ -671,7 +671,7 @@ void AstNode::swapWith(AstNode* bp) {
|
|||
|
||||
AstNode* AstNode::cloneTreeIter() {
|
||||
// private: Clone single node and children
|
||||
AstNode* newp = this->clone();
|
||||
AstNode* const newp = this->clone();
|
||||
if (this->m_op1p) newp->op1p(this->m_op1p->cloneTreeIterList());
|
||||
if (this->m_op2p) newp->op2p(this->m_op2p->cloneTreeIterList());
|
||||
if (this->m_op3p) newp->op3p(this->m_op3p->cloneTreeIterList());
|
||||
|
|
@ -688,7 +688,7 @@ AstNode* AstNode::cloneTreeIterList() {
|
|||
AstNode* newtailp = nullptr;
|
||||
// Audited to make sure this is never nullptr
|
||||
for (AstNode* oldp = this; oldp; oldp = oldp->m_nextp) {
|
||||
AstNode* newp = oldp->cloneTreeIter();
|
||||
AstNode* const newp = oldp->cloneTreeIter();
|
||||
newp->m_headtailp = nullptr;
|
||||
newp->m_backp = newtailp;
|
||||
if (newtailp) newtailp->m_nextp = newp;
|
||||
|
|
@ -777,14 +777,14 @@ void AstNode::deleteTree() {
|
|||
#ifdef VL_LEAK_CHECKS
|
||||
void* AstNode::operator new(size_t size) {
|
||||
// Optimization note: Aligning to cache line is a loss, due to lost packing
|
||||
AstNode* objp = static_cast<AstNode*>(::operator new(size));
|
||||
AstNode* const objp = static_cast<AstNode*>(::operator new(size));
|
||||
V3Broken::addNewed(objp);
|
||||
return objp;
|
||||
}
|
||||
|
||||
void AstNode::operator delete(void* objp, size_t size) {
|
||||
if (!objp) return;
|
||||
AstNode* nodep = static_cast<AstNode*>(objp);
|
||||
AstNode* const nodep = static_cast<AstNode*>(objp);
|
||||
V3Broken::deleted(nodep);
|
||||
::operator delete(objp);
|
||||
}
|
||||
|
|
@ -877,7 +877,7 @@ void AstNode::iterateAndNextConst(AstNVisitor& v) {
|
|||
// Keep following the current list even if edits change it
|
||||
AstNode* nodep = this;
|
||||
do {
|
||||
AstNode* nnextp = nodep->m_nextp;
|
||||
AstNode* const nnextp = nodep->m_nextp;
|
||||
ASTNODE_PREFETCH(nnextp);
|
||||
nodep->accept(v);
|
||||
nodep = nnextp;
|
||||
|
|
@ -898,7 +898,7 @@ AstNode* AstNode::iterateSubtreeReturnEdits(AstNVisitor& v) {
|
|||
} else if (!nodep->backp()) {
|
||||
// Calling on standalone tree; insert a shim node so we can keep
|
||||
// track, then delete it on completion
|
||||
AstBegin* tempp = new AstBegin(nodep->fileline(), "[EditWrapper]", nodep);
|
||||
AstBegin* const tempp = new AstBegin(nodep->fileline(), "[EditWrapper]", nodep);
|
||||
{
|
||||
VL_DO_DANGLING(tempp->stmtsp()->accept(v),
|
||||
nodep); // nodep to null as may be replaced
|
||||
|
|
@ -994,7 +994,7 @@ void AstNode::checkTreeIter(AstNode* backp) {
|
|||
void AstNode::checkTreeIterList(AstNode* backp) {
|
||||
// private: Check a (possible) list of nodes, this is always the head of the list
|
||||
// Audited to make sure this is never nullptr
|
||||
AstNode* headp = this;
|
||||
AstNode* const headp = this;
|
||||
AstNode* tailp = this;
|
||||
for (AstNode* nodep = headp; nodep; nodep = nodep->nextp()) {
|
||||
nodep->checkTreeIter(backp);
|
||||
|
|
@ -1143,7 +1143,7 @@ void AstNode::dumpTreeFile(const string& filename, bool append, bool doDump, boo
|
|||
checkTree();
|
||||
// Broken isn't part of check tree because it can munge iterp's
|
||||
// set by other steps if it is called in the middle of other operations
|
||||
if (AstNetlist* netp = VN_CAST(this, Netlist)) V3Broken::brokenAll(netp);
|
||||
if (AstNetlist* const netp = VN_CAST(this, Netlist)) V3Broken::brokenAll(netp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ using MTaskIdSet = std::set<int>; // Set of mtaskIds for Var sorting
|
|||
// For broken() function, return error string if a base of this class has a match
|
||||
#define BROKEN_BASE_RTN(test) \
|
||||
do { \
|
||||
const char* reasonp = (test); \
|
||||
const char* const reasonp = (test); \
|
||||
if (VL_UNCOVERABLE(reasonp)) return reasonp; \
|
||||
} while (false)
|
||||
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ const char* AstAddrOfCFunc::broken() const {
|
|||
}
|
||||
|
||||
int AstNodeSel::bitConst() const {
|
||||
AstConst* constp = VN_AS(bitp(), Const);
|
||||
const AstConst* const constp = VN_AS(bitp(), Const);
|
||||
return (constp ? constp->toSInt() : 0);
|
||||
}
|
||||
|
||||
|
|
@ -214,11 +214,11 @@ AstExecGraph::AstExecGraph(FileLine* fileline)
|
|||
AstExecGraph::~AstExecGraph() { VL_DO_DANGLING(delete m_depGraphp, m_depGraphp); }
|
||||
|
||||
AstNode* AstInsideRange::newAndFromInside(AstNode* exprp, AstNode* lhsp, AstNode* rhsp) {
|
||||
AstNode* ap = new AstGte(fileline(), exprp->cloneTree(true), lhsp);
|
||||
AstNode* bp = new AstLte(fileline(), exprp->cloneTree(true), rhsp);
|
||||
AstNode* const ap = new AstGte(fileline(), exprp->cloneTree(true), lhsp);
|
||||
AstNode* const bp = new AstLte(fileline(), exprp->cloneTree(true), rhsp);
|
||||
ap->fileline()->modifyWarnOff(V3ErrorCode::UNSIGNED, true);
|
||||
bp->fileline()->modifyWarnOff(V3ErrorCode::CMPCONST, true);
|
||||
AstNode* newp = new AstAnd(fileline(), ap, bp);
|
||||
AstNode* const newp = new AstAnd(fileline(), ap, bp);
|
||||
return newp;
|
||||
}
|
||||
|
||||
|
|
@ -336,7 +336,7 @@ string AstVar::vlArgType(bool named, bool forReturn, bool forFunc, const string&
|
|||
|
||||
string AstVar::vlEnumType() const {
|
||||
string arg;
|
||||
AstBasicDType* bdtypep = basicp();
|
||||
const AstBasicDType* const bdtypep = basicp();
|
||||
const bool strtype = bdtypep && bdtypep->keyword() == AstBasicDTypeKwd::STRING;
|
||||
if (bdtypep && bdtypep->keyword() == AstBasicDTypeKwd::CHARPTR) {
|
||||
return "VLVT_PTR";
|
||||
|
|
@ -377,7 +377,7 @@ string AstVar::vlEnumDir() const {
|
|||
out += "|VLVF_PUB_RD";
|
||||
}
|
||||
//
|
||||
if (AstBasicDType* bdtypep = basicp()) {
|
||||
if (const AstBasicDType* const bdtypep = basicp()) {
|
||||
if (bdtypep->keyword().isDpiCLayout()) out += "|VLVF_DPI_CLAY";
|
||||
}
|
||||
return out;
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ public:
|
|||
class BeginVisitor final : public AstNVisitor {
|
||||
private:
|
||||
// STATE
|
||||
BeginState* m_statep; // Current global state
|
||||
BeginState* const m_statep; // Current global state
|
||||
AstNodeModule* m_modp = nullptr; // Current module
|
||||
AstNodeFTask* m_ftaskp = nullptr; // Current function/task
|
||||
AstNode* m_liftedp = nullptr; // Local nodes we are lifting into m_ftaskp
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ private:
|
|||
|
||||
void processEnter(AstNode* nodep) {
|
||||
nodep->brokenState(m_brokenCntCurrentUnder);
|
||||
const char* whyp = nodep->broken();
|
||||
const char* const whyp = nodep->broken();
|
||||
UASSERT_OBJ(!whyp, nodep,
|
||||
"Broken link in node (or something without maybePointedTo): " << whyp);
|
||||
if (nodep->dtypep()) {
|
||||
|
|
@ -210,7 +210,8 @@ private:
|
|||
}
|
||||
UASSERT_OBJ(!nodep->getChildDTypep(), nodep,
|
||||
"childDTypep() non-null on node after should have removed");
|
||||
if (const AstNodeDType* dnodep = VN_CAST(nodep, NodeDType)) checkWidthMin(dnodep);
|
||||
if (const AstNodeDType* const dnodep = VN_CAST(nodep, NodeDType))
|
||||
checkWidthMin(dnodep);
|
||||
}
|
||||
checkWidthMin(nodep);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ void V3CCtors::evalAsserts() {
|
|||
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
|
||||
if (AstVar* const varp = VN_CAST(np, Var)) {
|
||||
if (varp->isPrimaryInish() && !varp->isSc()) {
|
||||
if (AstBasicDType* basicp = VN_CAST(varp->dtypeSkipRefp(), BasicDType)) {
|
||||
if (const AstBasicDType* basicp = VN_CAST(varp->dtypeSkipRefp(), BasicDType)) {
|
||||
const int storedWidth = basicp->widthAlignBytes() * 8;
|
||||
const int lastWordWidth = varp->width() % storedWidth;
|
||||
if (lastWordWidth != 0) {
|
||||
|
|
@ -200,7 +200,7 @@ void V3CCtors::cctorsAll() {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (AstClass* const classp = VN_CAST(modp, Class)) {
|
||||
if (const AstClass* const classp = VN_CAST(modp, Class)) {
|
||||
AstCFunc* const funcp = new AstCFunc{modp->fileline(), "~", nullptr, ""};
|
||||
funcp->isDestructor(true);
|
||||
funcp->isStatic(false);
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ private:
|
|||
itemp = VN_AS(itemp->nextp(), CaseItem)) {
|
||||
for (AstNode* icondp = itemp->condsp(); icondp; icondp = icondp->nextp()) {
|
||||
// if (debug() >= 9) icondp->dumpTree(cout, " caseitem: ");
|
||||
AstConst* iconstp = VN_AS(icondp, Const);
|
||||
AstConst* const iconstp = VN_AS(icondp, Const);
|
||||
UASSERT_OBJ(iconstp, nodep, "above 'can't parse' should have caught this");
|
||||
if (neverItem(nodep, iconstp)) {
|
||||
// X in casez can't ever be executed
|
||||
|
|
@ -289,10 +289,11 @@ private:
|
|||
// V3Number nummask (cexprp, cexprp->width(), (1UL<<msb));
|
||||
// AstNode* and1p = new AstAnd(cexprp->fileline(), cexprp->cloneTree(false),
|
||||
// new AstConst(cexprp->fileline(), nummask));
|
||||
AstNode* and1p = new AstSel(cexprp->fileline(), cexprp->cloneTree(false), msb, 1);
|
||||
AstNode* eqp
|
||||
AstNode* const and1p
|
||||
= new AstSel(cexprp->fileline(), cexprp->cloneTree(false), msb, 1);
|
||||
AstNode* const eqp
|
||||
= new AstNeq(cexprp->fileline(), new AstConst(cexprp->fileline(), 0), and1p);
|
||||
AstIf* ifp = new AstIf(cexprp->fileline(), eqp, tree1p, tree0p);
|
||||
AstIf* const ifp = new AstIf(cexprp->fileline(), eqp, tree1p, tree0p);
|
||||
ifp->user3(1); // So we don't bother to clone it
|
||||
return ifp;
|
||||
}
|
||||
|
|
@ -302,11 +303,11 @@ private:
|
|||
// CASEx(cexpr,....
|
||||
// -> tree of IF(msb, IF(msb-1, 11, 10)
|
||||
// IF(msb-1, 01, 00))
|
||||
AstNode* cexprp = nodep->exprp()->unlinkFrBack();
|
||||
AstNode* const cexprp = nodep->exprp()->unlinkFrBack();
|
||||
|
||||
if (debug() >= 9) { // LCOV_EXCL_START
|
||||
for (uint32_t i = 0; i < (1UL << m_caseWidth); ++i) {
|
||||
if (AstNode* itemp = m_valueItem[i]) {
|
||||
if (const AstNode* const itemp = m_valueItem[i]) {
|
||||
UINFO(9, "Value " << std::hex << i << " " << itemp << endl);
|
||||
}
|
||||
}
|
||||
|
|
@ -335,7 +336,7 @@ private:
|
|||
// -> IF((cexpr==icond1),istmts1,
|
||||
// IF((EQ (AND MASK cexpr) (AND MASK icond1)
|
||||
// ,istmts2, istmts3
|
||||
AstNode* cexprp = nodep->exprp()->unlinkFrBack();
|
||||
AstNode* const cexprp = nodep->exprp()->unlinkFrBack();
|
||||
// We'll do this in two stages. First stage, convert the conditions to
|
||||
// the appropriate IF AND terms.
|
||||
if (debug() >= 9) nodep->dumpTree(cout, " _comp_IN: ");
|
||||
|
|
@ -355,7 +356,7 @@ private:
|
|||
icondp->unlinkFrBack();
|
||||
|
||||
AstNode* condp = nullptr; // Default is to use and1p/and2p
|
||||
AstConst* iconstp = VN_CAST(icondp, Const);
|
||||
AstConst* const iconstp = VN_CAST(icondp, Const);
|
||||
if (iconstp && neverItem(nodep, iconstp)) {
|
||||
// X in casez can't ever be executed
|
||||
VL_DO_DANGLING(icondp->deleteTree(), icondp);
|
||||
|
|
@ -373,18 +374,19 @@ private:
|
|||
nummask.opBitsNonX(iconstp->num());
|
||||
V3Number numval(itemp, iconstp->width());
|
||||
numval.opBitsOne(iconstp->num());
|
||||
AstNode* and1p = new AstAnd(itemp->fileline(), cexprp->cloneTree(false),
|
||||
new AstConst(itemp->fileline(), nummask));
|
||||
AstNode* and2p = new AstAnd(itemp->fileline(),
|
||||
new AstConst(itemp->fileline(), numval),
|
||||
new AstConst(itemp->fileline(), nummask));
|
||||
AstNode* const and1p
|
||||
= new AstAnd(itemp->fileline(), cexprp->cloneTree(false),
|
||||
new AstConst(itemp->fileline(), nummask));
|
||||
AstNode* const and2p = new AstAnd(
|
||||
itemp->fileline(), new AstConst(itemp->fileline(), numval),
|
||||
new AstConst(itemp->fileline(), nummask));
|
||||
VL_DO_DANGLING(icondp->deleteTree(), icondp);
|
||||
VL_DANGLING(iconstp);
|
||||
condp = AstEq::newTyped(itemp->fileline(), and1p, and2p);
|
||||
} else {
|
||||
// Not a caseX mask, we can simply build CASEEQ(cexpr icond)
|
||||
AstNode* and1p = cexprp->cloneTree(false);
|
||||
AstNode* and2p = icondp;
|
||||
AstNode* const and1p = cexprp->cloneTree(false);
|
||||
AstNode* const and2p = icondp;
|
||||
condp = AstEq::newTyped(itemp->fileline(), and1p, and2p);
|
||||
}
|
||||
if (!ifexprp) {
|
||||
|
|
@ -417,15 +419,15 @@ private:
|
|||
AstIf* itemnextp = nullptr;
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp;
|
||||
itemp = VN_AS(itemp->nextp(), CaseItem)) {
|
||||
AstNode* istmtsp = itemp->bodysp(); // Maybe null -- no action.
|
||||
AstNode* const istmtsp = itemp->bodysp(); // Maybe null -- no action.
|
||||
if (istmtsp) istmtsp->unlinkFrBackWithNext();
|
||||
// Expressioned clause
|
||||
AstNode* ifexprp = itemp->condsp()->unlinkFrBack();
|
||||
AstNode* const ifexprp = itemp->condsp()->unlinkFrBack();
|
||||
{ // Prepare for next group
|
||||
if (++depth > CASE_ENCODER_GROUP_DEPTH) depth = 1;
|
||||
if (depth == 1) { // First group or starting new group
|
||||
itemnextp = nullptr;
|
||||
AstIf* newp
|
||||
AstIf* const newp
|
||||
= new AstIf(itemp->fileline(), ifexprp->cloneTree(true), nullptr, nullptr);
|
||||
if (groupnextp) {
|
||||
groupnextp->addElsesp(newp);
|
||||
|
|
@ -434,7 +436,7 @@ private:
|
|||
}
|
||||
groupnextp = newp;
|
||||
} else { // Continue group, modify if condition to OR in this new condition
|
||||
AstNode* condp = groupnextp->condp()->unlinkFrBack();
|
||||
AstNode* const condp = groupnextp->condp()->unlinkFrBack();
|
||||
groupnextp->condp(
|
||||
new AstOr(ifexprp->fileline(), condp, ifexprp->cloneTree(true)));
|
||||
}
|
||||
|
|
@ -446,7 +448,7 @@ private:
|
|||
VL_DO_DANGLING(itemexprp->deleteTree(), itemexprp);
|
||||
itemexprp = new AstConst(itemp->fileline(), AstConst::BitTrue());
|
||||
}
|
||||
AstIf* newp = new AstIf(itemp->fileline(), itemexprp, istmtsp, nullptr);
|
||||
AstIf* const newp = new AstIf(itemp->fileline(), itemexprp, istmtsp, nullptr);
|
||||
if (itemnextp) {
|
||||
itemnextp->addElsesp(newp);
|
||||
} else {
|
||||
|
|
@ -474,7 +476,7 @@ private:
|
|||
// covered, we're done with it.
|
||||
// Else, convert to a normal statement parallel with the case statement.
|
||||
if (nodep->notParallelp() && !noOverlapsAllCovered) {
|
||||
AstNode* parp = nodep->notParallelp()->unlinkFrBackWithNext();
|
||||
AstNode* const parp = nodep->notParallelp()->unlinkFrBackWithNext();
|
||||
nodep->addNextHere(parp);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,8 +50,8 @@ public:
|
|||
// Graph support classes
|
||||
|
||||
class CdcEitherVertex VL_NOT_FINAL : public V3GraphVertex {
|
||||
AstScope* m_scopep;
|
||||
AstNode* m_nodep;
|
||||
AstScope* const m_scopep;
|
||||
AstNode* const m_nodep;
|
||||
AstSenTree* m_srcDomainp = nullptr;
|
||||
AstSenTree* m_dstDomainp = nullptr;
|
||||
bool m_srcDomainSet : 1;
|
||||
|
|
@ -84,7 +84,7 @@ public:
|
|||
};
|
||||
|
||||
class CdcVarVertex final : public CdcEitherVertex {
|
||||
AstVarScope* m_varScp;
|
||||
AstVarScope* const m_varScp;
|
||||
int m_cntAsyncRst = 0;
|
||||
bool m_fromFlop = false;
|
||||
|
||||
|
|
@ -266,7 +266,7 @@ private:
|
|||
if (varscp->varp()->isPrimaryIO()) {
|
||||
// Create IO vertex - note it's relative to the pointed to var, not where we are
|
||||
// now This allows reporting to easily print the input statement
|
||||
CdcLogicVertex* ioVertexp
|
||||
CdcLogicVertex* const ioVertexp
|
||||
= new CdcLogicVertex(&m_graph, varscp->scopep(), varscp->varp(), nullptr);
|
||||
if (varscp->varp()->isWritable()) {
|
||||
new V3GraphEdge(&m_graph, vertexp, ioVertexp, 1);
|
||||
|
|
@ -351,12 +351,12 @@ private:
|
|||
// userClearVertices is very slow, so we use a generation count instead
|
||||
m_graph.userClearVertices(); // user1: uint32_t - was analyzed generation
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (CdcVarVertex* vvertexp = dynamic_cast<CdcVarVertex*>(itp)) {
|
||||
if (CdcVarVertex* const vvertexp = dynamic_cast<CdcVarVertex*>(itp)) {
|
||||
if (vvertexp->cntAsyncRst()) {
|
||||
m_userGeneration++; // Effectively a userClearVertices()
|
||||
UINFO(8, " Trace One async: " << vvertexp << endl);
|
||||
// Twice, as we need to detect, then propagate
|
||||
CdcEitherVertex* markp = traceAsyncRecurse(vvertexp, false);
|
||||
CdcEitherVertex* const markp = traceAsyncRecurse(vvertexp, false);
|
||||
if (markp) { // Mark is non-nullptr if something bad on this path
|
||||
UINFO(9, " Trace One bad! " << vvertexp << endl);
|
||||
m_userGeneration++; // Effectively a userClearVertices()
|
||||
|
|
@ -381,7 +381,7 @@ private:
|
|||
// Clear out in prep for marking next path
|
||||
if (!mark) vertexp->asyncPath(false);
|
||||
|
||||
if (CdcLogicVertex* vvertexp = dynamic_cast<CdcLogicVertex*>(vertexp)) {
|
||||
if (CdcLogicVertex* const vvertexp = dynamic_cast<CdcLogicVertex*>(vertexp)) {
|
||||
// Any logic considered bad, at the moment, anyhow
|
||||
if (vvertexp->hazard() && !mark_outp) mark_outp = vvertexp;
|
||||
// And keep tracing back so the user can understand what's up
|
||||
|
|
@ -391,7 +391,8 @@ private:
|
|||
if (vvertexp->varScp()->varp()->isPrimaryInish()) {
|
||||
// Show the source "input" statement if it exists
|
||||
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
CdcEitherVertex* eFromVertexp = static_cast<CdcEitherVertex*>(edgep->fromp());
|
||||
CdcEitherVertex* const eFromVertexp
|
||||
= static_cast<CdcEitherVertex*>(edgep->fromp());
|
||||
eFromVertexp->asyncPath(true);
|
||||
}
|
||||
return nullptr;
|
||||
|
|
@ -399,7 +400,8 @@ private:
|
|||
// Also ok if from flop, but partially trace the flop so more obvious to users
|
||||
if (vvertexp->fromFlop()) {
|
||||
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
CdcEitherVertex* eFromVertexp = static_cast<CdcEitherVertex*>(edgep->fromp());
|
||||
CdcEitherVertex* const eFromVertexp
|
||||
= static_cast<CdcEitherVertex*>(edgep->fromp());
|
||||
eFromVertexp->asyncPath(true);
|
||||
}
|
||||
return nullptr;
|
||||
|
|
@ -407,8 +409,8 @@ private:
|
|||
}
|
||||
|
||||
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
CdcEitherVertex* eFromVertexp = static_cast<CdcEitherVertex*>(edgep->fromp());
|
||||
CdcEitherVertex* submarkp = traceAsyncRecurse(eFromVertexp, mark);
|
||||
CdcEitherVertex* const eFromVertexp = static_cast<CdcEitherVertex*>(edgep->fromp());
|
||||
CdcEitherVertex* const submarkp = traceAsyncRecurse(eFromVertexp, mark);
|
||||
if (submarkp && !mark_outp) mark_outp = submarkp;
|
||||
}
|
||||
|
||||
|
|
@ -417,14 +419,14 @@ private:
|
|||
}
|
||||
|
||||
void dumpAsync(CdcVarVertex* vertexp, CdcEitherVertex* markp) {
|
||||
AstNode* nodep = vertexp->varScp();
|
||||
const AstNode* const nodep = vertexp->varScp();
|
||||
*m_ofp << "\n";
|
||||
*m_ofp << "\n";
|
||||
CdcEitherVertex* targetp = vertexp; // One example destination flop (of possibly many)
|
||||
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||
CdcEitherVertex* eToVertexp = static_cast<CdcEitherVertex*>(edgep->top());
|
||||
CdcEitherVertex* const eToVertexp = static_cast<CdcEitherVertex*>(edgep->top());
|
||||
if (!eToVertexp) targetp = eToVertexp;
|
||||
if (CdcLogicVertex* vvertexp = dynamic_cast<CdcLogicVertex*>(eToVertexp)) {
|
||||
if (const CdcLogicVertex* const vvertexp = dynamic_cast<CdcLogicVertex*>(eToVertexp)) {
|
||||
if (vvertexp->isFlop() // IE the target flop that is upsetting us
|
||||
&& edgep->weight() >= CDC_WEIGHT_ASYNC) { // And var feeds an async reset line
|
||||
targetp = eToVertexp;
|
||||
|
|
@ -452,13 +454,13 @@ private:
|
|||
const string cont = prefix + sep;
|
||||
string nextsep = " ";
|
||||
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
CdcEitherVertex* eFromVertexp = static_cast<CdcEitherVertex*>(edgep->fromp());
|
||||
CdcEitherVertex* const eFromVertexp = static_cast<CdcEitherVertex*>(edgep->fromp());
|
||||
if (dumpAsyncRecurse(eFromVertexp, cont, nextsep, level + 1)) nextsep = " | ";
|
||||
}
|
||||
|
||||
// Dump single variable/logic block
|
||||
// See also OrderGraph::loopsVertexCb(V3GraphVertex* vertexp)
|
||||
AstNode* nodep = vertexp->nodep();
|
||||
AstNode* const nodep = vertexp->nodep();
|
||||
string front
|
||||
= pad(filelineWidth(), nodep->fileline()->ascii() + ":") + " " + prefix + " +- ";
|
||||
if (VN_IS(nodep, VarScope)) {
|
||||
|
|
@ -473,7 +475,7 @@ private:
|
|||
if (level)
|
||||
*m_ofp << V3OutFile::indentSpaces(filelineWidth()) << " " << prefix << nextsep << "\n";
|
||||
|
||||
if (CdcLogicVertex* vvertexp = dynamic_cast<CdcLogicVertex*>(vertexp)) {
|
||||
if (CdcLogicVertex* const vvertexp = dynamic_cast<CdcLogicVertex*>(vertexp)) {
|
||||
// Now that we've printed a path with this hazard, don't bother to print any more
|
||||
// Otherwise, we'd get a path for almost every destination flop
|
||||
vvertexp->clearHazard();
|
||||
|
|
@ -499,7 +501,7 @@ private:
|
|||
UINFO(9, " Trace Direction " << (traceDests ? "dst" : "src") << endl);
|
||||
m_graph.userClearVertices(); // user1: bool - was analyzed
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (CdcVarVertex* vvertexp = dynamic_cast<CdcVarVertex*>(itp)) {
|
||||
if (CdcVarVertex* const vvertexp = dynamic_cast<CdcVarVertex*>(itp)) {
|
||||
UINFO(9, " Trace One edge: " << vvertexp << endl);
|
||||
edgeDomainRecurse(vvertexp, traceDests, 0);
|
||||
}
|
||||
|
|
@ -514,8 +516,8 @@ private:
|
|||
|
||||
std::deque<string> report; // Sort output by name
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (CdcVarVertex* vvertexp = dynamic_cast<CdcVarVertex*>(itp)) {
|
||||
AstVar* varp = vvertexp->varScp()->varp();
|
||||
if (const CdcVarVertex* const vvertexp = dynamic_cast<CdcVarVertex*>(itp)) {
|
||||
const AstVar* const varp = vvertexp->varScp()->varp();
|
||||
{
|
||||
string what = "wire";
|
||||
if (varp->isPrimaryIO()) what = varp->direction().prettyName();
|
||||
|
|
@ -558,11 +560,11 @@ private:
|
|||
} // Fully computed
|
||||
|
||||
std::set<AstSenTree*> senouts; // List of all sensitivities for new signal
|
||||
if (CdcLogicVertex* vvertexp = dynamic_cast<CdcLogicVertex*>(vertexp)) {
|
||||
if (const CdcLogicVertex* const vvertexp = dynamic_cast<CdcLogicVertex*>(vertexp)) {
|
||||
if (vvertexp) {} // Unused
|
||||
} else if (CdcVarVertex* vvertexp = dynamic_cast<CdcVarVertex*>(vertexp)) {
|
||||
// If primary I/O, give it domain of the input
|
||||
AstVar* varp = vvertexp->varScp()->varp();
|
||||
const AstVar* const varp = vvertexp->varScp()->varp();
|
||||
if (varp->isPrimaryIO() && varp->isNonOutput() && !traceDests) {
|
||||
senouts.insert(new AstSenTree(
|
||||
varp->fileline(), new AstSenItem(varp->fileline(), AstSenItem::Combo())));
|
||||
|
|
@ -572,13 +574,14 @@ private:
|
|||
// Now combine domains of sources/dests
|
||||
if (traceDests) {
|
||||
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||
CdcEitherVertex* eToVertexp = static_cast<CdcEitherVertex*>(edgep->top());
|
||||
CdcEitherVertex* const eToVertexp = static_cast<CdcEitherVertex*>(edgep->top());
|
||||
edgeDomainRecurse(eToVertexp, traceDests, level + 1);
|
||||
if (eToVertexp->dstDomainp()) senouts.insert(eToVertexp->dstDomainp());
|
||||
}
|
||||
} else {
|
||||
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
CdcEitherVertex* eFromVertexp = static_cast<CdcEitherVertex*>(edgep->fromp());
|
||||
CdcEitherVertex* const eFromVertexp
|
||||
= static_cast<CdcEitherVertex*>(edgep->fromp());
|
||||
edgeDomainRecurse(eFromVertexp, traceDests, level + 1);
|
||||
if (eFromVertexp->srcDomainp()) senouts.insert(eFromVertexp->srcDomainp());
|
||||
}
|
||||
|
|
@ -653,9 +656,9 @@ private:
|
|||
virtual void visit(AstNodeVarRef* nodep) override {
|
||||
if (m_scopep) {
|
||||
UASSERT_OBJ(m_logicVertexp, nodep, "Var ref not under a logic block");
|
||||
AstVarScope* varscp = nodep->varScopep();
|
||||
AstVarScope* const varscp = nodep->varScopep();
|
||||
UASSERT_OBJ(varscp, nodep, "Var didn't get varscoped in V3Scope.cpp");
|
||||
CdcVarVertex* varvertexp = makeVarVertex(varscp);
|
||||
CdcVarVertex* const varvertexp = makeVarVertex(varscp);
|
||||
UINFO(5, " VARREF to " << varscp << endl);
|
||||
// We use weight of one for normal edges,
|
||||
// Weight of CDC_WEIGHT_ASYNC to indicate feeds async (for reporting)
|
||||
|
|
|
|||
|
|
@ -53,14 +53,16 @@ private:
|
|||
v3Global.rootp()->addModulep(nodep);
|
||||
// Make containing package
|
||||
// Note origName is the same as the class origName so errors look correct
|
||||
AstClassPackage* packagep = new AstClassPackage(nodep->fileline(), nodep->origName());
|
||||
AstClassPackage* const packagep
|
||||
= new AstClassPackage(nodep->fileline(), nodep->origName());
|
||||
packagep->name(nodep->name() + "__Vclpkg");
|
||||
nodep->classOrPackagep(packagep);
|
||||
packagep->classp(nodep);
|
||||
v3Global.rootp()->addModulep(packagep);
|
||||
// Add package to hierarchy
|
||||
AstCell* cellp = new AstCell(packagep->fileline(), packagep->fileline(), packagep->name(),
|
||||
packagep->name(), nullptr, nullptr, nullptr);
|
||||
AstCell* const cellp
|
||||
= new AstCell(packagep->fileline(), packagep->fileline(), packagep->name(),
|
||||
packagep->name(), nullptr, nullptr, nullptr);
|
||||
cellp->modp(packagep);
|
||||
v3Global.rootp()->topModulep()->addStmtp(cellp);
|
||||
// Find class's scope
|
||||
|
|
@ -72,8 +74,9 @@ private:
|
|||
UASSERT_OBJ(classScopep, nodep, "No scope under class");
|
||||
|
||||
// Add scope
|
||||
AstScope* scopep = new AstScope(nodep->fileline(), packagep, classScopep->name(),
|
||||
classScopep->aboveScopep(), classScopep->aboveCellp());
|
||||
AstScope* const scopep
|
||||
= new AstScope(nodep->fileline(), packagep, classScopep->name(),
|
||||
classScopep->aboveScopep(), classScopep->aboveCellp());
|
||||
packagep->addStmtp(scopep);
|
||||
// Iterate
|
||||
VL_RESTORER(m_prefix);
|
||||
|
|
|
|||
|
|
@ -67,16 +67,16 @@ private:
|
|||
}
|
||||
void setCppWidth(AstNode* nodep) {
|
||||
nodep->user2(true); // Don't resize it again
|
||||
AstNodeDType* old_dtypep = nodep->dtypep();
|
||||
AstNodeDType* const old_dtypep = nodep->dtypep();
|
||||
const int width = cppWidth(nodep); // widthMin is unchanged
|
||||
if (old_dtypep->width() != width) {
|
||||
// Since any given dtype's cppWidth() is the same, we can just
|
||||
// remember one conversion for each, and reuse it
|
||||
if (AstNodeDType* new_dtypep = VN_CAST(old_dtypep->user3p(), NodeDType)) {
|
||||
if (AstNodeDType* const new_dtypep = VN_CAST(old_dtypep->user3p(), NodeDType)) {
|
||||
nodep->dtypep(new_dtypep);
|
||||
} else {
|
||||
nodep->dtypeChgWidth(width, nodep->widthMin());
|
||||
AstNodeDType* new_dtypep2 = nodep->dtypep();
|
||||
AstNodeDType* const new_dtypep2 = nodep->dtypep();
|
||||
UASSERT_OBJ(new_dtypep2 != old_dtypep, nodep,
|
||||
"Dtype didn't change when width changed");
|
||||
old_dtypep->user3p(new_dtypep2); // Remember for next time
|
||||
|
|
@ -126,7 +126,7 @@ private:
|
|||
computeCppWidth(nodep);
|
||||
V3Number mask(nodep, cppWidth(nodep));
|
||||
mask.setMask(nodep->widthMin());
|
||||
AstNode* cleanp
|
||||
AstNode* const cleanp
|
||||
= new AstAnd(nodep->fileline(), new AstConst(nodep->fileline(), mask), nodep);
|
||||
cleanp->dtypeFrom(nodep); // Otherwise the AND normally picks LHS
|
||||
relinkHandle.relink(cleanp);
|
||||
|
|
@ -138,7 +138,7 @@ private:
|
|||
void ensureCleanAndNext(AstNode* nodep) {
|
||||
// Editing list, careful looping!
|
||||
for (AstNode* exprp = nodep; exprp;) {
|
||||
AstNode* nextp = exprp->nextp();
|
||||
AstNode* const nextp = exprp->nextp();
|
||||
ensureClean(exprp);
|
||||
exprp = nextp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,30 +92,30 @@ private:
|
|||
|
||||
AstVarScope* getCreateLastClk(AstVarScope* vscp) {
|
||||
if (vscp->user1p()) return static_cast<AstVarScope*>(vscp->user1p());
|
||||
AstVar* varp = vscp->varp();
|
||||
const AstVar* const varp = vscp->varp();
|
||||
if (!varp->width1()) {
|
||||
varp->v3warn(E_UNSUPPORTED, "Unsupported: Clock edge on non-single bit signal: "
|
||||
<< varp->prettyNameQ());
|
||||
}
|
||||
string newvarname
|
||||
= (string("__Vclklast__") + vscp->scopep()->nameDotless() + "__" + varp->name());
|
||||
AstVar* newvarp = new AstVar(vscp->fileline(), AstVarType::MODULETEMP, newvarname,
|
||||
VFlagLogicPacked(), 1);
|
||||
AstVar* const newvarp = new AstVar(vscp->fileline(), AstVarType::MODULETEMP, newvarname,
|
||||
VFlagLogicPacked(), 1);
|
||||
newvarp->noReset(true); // Reset by below assign
|
||||
m_modp->addStmtp(newvarp);
|
||||
AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopep, newvarp);
|
||||
AstVarScope* const newvscp = new AstVarScope(vscp->fileline(), m_scopep, newvarp);
|
||||
vscp->user1p(newvscp);
|
||||
m_scopep->addVarp(newvscp);
|
||||
// Add init
|
||||
AstNode* fromp = new AstVarRef(newvarp->fileline(), vscp, VAccess::READ);
|
||||
if (v3Global.opt.xInitialEdge()) fromp = new AstNot(fromp->fileline(), fromp);
|
||||
AstNode* newinitp = new AstAssign(
|
||||
AstNode* const newinitp = new AstAssign(
|
||||
vscp->fileline(), new AstVarRef(newvarp->fileline(), newvscp, VAccess::WRITE), fromp);
|
||||
addToInitial(newinitp);
|
||||
// At bottom, assign them
|
||||
AstAssign* finalp = new AstAssign(vscp->fileline(),
|
||||
new AstVarRef(vscp->fileline(), newvscp, VAccess::WRITE),
|
||||
new AstVarRef(vscp->fileline(), vscp, VAccess::READ));
|
||||
AstAssign* const finalp = new AstAssign(
|
||||
vscp->fileline(), new AstVarRef(vscp->fileline(), newvscp, VAccess::WRITE),
|
||||
new AstVarRef(vscp->fileline(), vscp, VAccess::READ));
|
||||
m_evalFuncp->addFinalsp(finalp);
|
||||
//
|
||||
UINFO(4, "New Last: " << newvscp << endl);
|
||||
|
|
@ -137,16 +137,16 @@ private:
|
|||
return nullptr;
|
||||
}
|
||||
UASSERT_OBJ(nodep->varrefp(), nodep, "No clock found on sense item");
|
||||
AstVarScope* clkvscp = nodep->varrefp()->varScopep();
|
||||
AstVarScope* const clkvscp = nodep->varrefp()->varScopep();
|
||||
if (nodep->edgeType() == VEdgeType::ET_POSEDGE) {
|
||||
AstVarScope* lastVscp = getCreateLastClk(clkvscp);
|
||||
AstVarScope* const lastVscp = getCreateLastClk(clkvscp);
|
||||
newp = new AstAnd(
|
||||
nodep->fileline(),
|
||||
new AstVarRef(nodep->fileline(), nodep->varrefp()->varScopep(), VAccess::READ),
|
||||
new AstNot(nodep->fileline(),
|
||||
new AstVarRef(nodep->fileline(), lastVscp, VAccess::READ)));
|
||||
} else if (nodep->edgeType() == VEdgeType::ET_NEGEDGE) {
|
||||
AstVarScope* lastVscp = getCreateLastClk(clkvscp);
|
||||
AstVarScope* const lastVscp = getCreateLastClk(clkvscp);
|
||||
newp = new AstAnd(
|
||||
nodep->fileline(),
|
||||
new AstNot(nodep->fileline(),
|
||||
|
|
@ -154,7 +154,7 @@ private:
|
|||
VAccess::READ)),
|
||||
new AstVarRef(nodep->fileline(), lastVscp, VAccess::READ));
|
||||
} else if (nodep->edgeType() == VEdgeType::ET_BOTHEDGE) {
|
||||
AstVarScope* lastVscp = getCreateLastClk(clkvscp);
|
||||
AstVarScope* const lastVscp = getCreateLastClk(clkvscp);
|
||||
newp = new AstXor(
|
||||
nodep->fileline(),
|
||||
new AstVarRef(nodep->fileline(), nodep->varrefp()->varScopep(), VAccess::READ),
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ static void makeToStringMiddle(AstClass* nodep) {
|
|||
funcp->addStmtsp(new AstCStmt{nodep->fileline(), "std::string out;\n"});
|
||||
std::string comma;
|
||||
for (AstNode* itemp = nodep->membersp(); itemp; itemp = itemp->nextp()) {
|
||||
if (auto* const varp = VN_CAST(itemp, Var)) {
|
||||
if (const auto* const varp = VN_CAST(itemp, Var)) {
|
||||
if (!varp->isParam()) {
|
||||
string stmt = "out += \"";
|
||||
stmt += comma;
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ public:
|
|||
// Apply all attributes to the variable
|
||||
void apply(AstVar* varp) {
|
||||
for (const_iterator it = begin(); it != end(); ++it) {
|
||||
AstNode* newp = new AstAttrOf(varp->fileline(), it->m_type);
|
||||
AstNode* const newp = new AstAttrOf(varp->fileline(), it->m_type);
|
||||
varp->addAttrsp(newp);
|
||||
if (it->m_type == AstAttrType::VAR_PUBLIC_FLAT_RW && it->m_sentreep) {
|
||||
newp->addNext(new AstAlwaysPublic(varp->fileline(), it->m_sentreep, nullptr));
|
||||
|
|
@ -192,11 +192,11 @@ public:
|
|||
if (m_inline) {
|
||||
AstPragmaType type
|
||||
= m_inlineValue ? AstPragmaType::INLINE_MODULE : AstPragmaType::NO_INLINE_MODULE;
|
||||
AstNode* nodep = new AstPragma(modp->fileline(), type);
|
||||
AstNode* const nodep = new AstPragma(modp->fileline(), type);
|
||||
modp->addStmtp(nodep);
|
||||
}
|
||||
for (auto it = m_modPragmas.cbegin(); it != m_modPragmas.cend(); ++it) {
|
||||
AstNode* nodep = new AstPragma(modp->fileline(), *it);
|
||||
AstNode* const nodep = new AstPragma(modp->fileline(), *it);
|
||||
modp->addStmtp(nodep);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,20 +116,20 @@ private:
|
|||
// Someday the user might be allowed to specify a different page suffix
|
||||
const string page = page_prefix + "/" + m_modp->prettyName();
|
||||
|
||||
AstCoverDecl* declp = new AstCoverDecl(fl, page, comment, linescov, offset);
|
||||
AstCoverDecl* const declp = new AstCoverDecl(fl, page, comment, linescov, offset);
|
||||
declp->hier(hier);
|
||||
m_modp->addStmtp(declp);
|
||||
UINFO(9, "new " << declp << endl);
|
||||
|
||||
AstCoverInc* incp = new AstCoverInc(fl, declp);
|
||||
AstCoverInc* const incp = new AstCoverInc(fl, declp);
|
||||
if (!trace_var_name.empty() && v3Global.opt.traceCoverage()) {
|
||||
AstVar* varp = new AstVar(incp->fileline(), AstVarType::MODULETEMP, trace_var_name,
|
||||
incp->findUInt32DType());
|
||||
AstVar* const varp = new AstVar(incp->fileline(), AstVarType::MODULETEMP,
|
||||
trace_var_name, incp->findUInt32DType());
|
||||
varp->trace(true);
|
||||
varp->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true);
|
||||
m_modp->addStmtp(varp);
|
||||
UINFO(5, "New coverage trace: " << varp << endl);
|
||||
AstAssign* assp = new AstAssign(
|
||||
AstAssign* const assp = new AstAssign(
|
||||
incp->fileline(), new AstVarRef(incp->fileline(), varp, VAccess::WRITE),
|
||||
new AstAdd(incp->fileline(), new AstVarRef(incp->fileline(), varp, VAccess::READ),
|
||||
new AstConst(incp->fileline(), AstConst::WidthedValue(), 32, 1)));
|
||||
|
|
@ -209,7 +209,7 @@ private:
|
|||
|
||||
// VISITORS - BOTH
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
AstNodeModule* origModp = m_modp;
|
||||
AstNodeModule* const origModp = m_modp;
|
||||
VL_RESTORER(m_modp);
|
||||
VL_RESTORER(m_state);
|
||||
{
|
||||
|
|
@ -240,10 +240,10 @@ private:
|
|||
iterateChildren(nodep);
|
||||
if (m_state.lineCoverageOn(nodep)) {
|
||||
lineTrack(nodep);
|
||||
AstNode* newp
|
||||
AstNode* const newp
|
||||
= newCoverInc(nodep->fileline(), "", "v_line", "block",
|
||||
linesCov(m_state, nodep), 0, traceNameForLine(nodep, "block"));
|
||||
if (AstNodeProcedure* itemp = VN_CAST(nodep, NodeProcedure)) {
|
||||
if (AstNodeProcedure* const itemp = VN_CAST(nodep, NodeProcedure)) {
|
||||
itemp->addStmtp(newp);
|
||||
} else if (AstNodeFTask* itemp = VN_CAST(nodep, NodeFTask)) {
|
||||
itemp->addStmtsp(newp);
|
||||
|
|
@ -261,7 +261,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
if (m_modp && !m_inToggleOff && !m_state.m_inModOff && nodep->fileline()->coverageOn()
|
||||
&& v3Global.opt.coverageToggle()) {
|
||||
const char* disablep = varIgnoreToggle(nodep);
|
||||
const char* const disablep = varIgnoreToggle(nodep);
|
||||
if (disablep) {
|
||||
UINFO(4, " Disable Toggle: " << disablep << " " << nodep << endl);
|
||||
} else {
|
||||
|
|
@ -279,7 +279,7 @@ private:
|
|||
|
||||
// Add signal to hold the old value
|
||||
const string newvarname = string("__Vtogcov__") + nodep->shortName();
|
||||
AstVar* chgVarp
|
||||
AstVar* const chgVarp
|
||||
= new AstVar(nodep->fileline(), AstVarType::MODULETEMP, newvarname, nodep);
|
||||
chgVarp->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true);
|
||||
m_modp->addStmtp(chgVarp);
|
||||
|
|
@ -298,7 +298,7 @@ private:
|
|||
}
|
||||
|
||||
void toggleVarBottom(const ToggleEnt& above, const AstVar* varp) {
|
||||
AstCoverToggle* newp = new AstCoverToggle(
|
||||
AstCoverToggle* const newp = new AstCoverToggle(
|
||||
varp->fileline(),
|
||||
newCoverInc(varp->fileline(), "", "v_toggle", varp->name() + above.m_comment, "", 0,
|
||||
""),
|
||||
|
|
@ -308,7 +308,7 @@ private:
|
|||
|
||||
void toggleVarRecurse(AstNodeDType* dtypep, int depth, // per-iteration
|
||||
const ToggleEnt& above, AstVar* varp, AstVar* chgVarp) { // Constant
|
||||
if (const AstBasicDType* bdtypep = VN_CAST(dtypep, BasicDType)) {
|
||||
if (const AstBasicDType* const bdtypep = VN_CAST(dtypep, BasicDType)) {
|
||||
if (bdtypep->isRanged()) {
|
||||
for (int index_docs = bdtypep->lo(); index_docs < bdtypep->hi() + 1;
|
||||
++index_docs) {
|
||||
|
|
@ -338,7 +338,7 @@ private:
|
|||
}
|
||||
} else if (AstPackArrayDType* adtypep = VN_CAST(dtypep, PackArrayDType)) {
|
||||
for (int index_docs = adtypep->lo(); index_docs <= adtypep->hi(); ++index_docs) {
|
||||
AstNodeDType* subtypep = adtypep->subDTypep()->skipRefp();
|
||||
AstNodeDType* const subtypep = adtypep->subDTypep()->skipRefp();
|
||||
const int index_code = index_docs - adtypep->lo();
|
||||
ToggleEnt newent(above.m_comment + string("[") + cvtToStr(index_docs) + "]",
|
||||
new AstSel(varp->fileline(), above.m_varRefp->cloneTree(true),
|
||||
|
|
@ -353,7 +353,7 @@ private:
|
|||
// For now it's packed, so similar to array
|
||||
for (AstMemberDType* itemp = adtypep->membersp(); itemp;
|
||||
itemp = VN_AS(itemp->nextp(), MemberDType)) {
|
||||
AstNodeDType* subtypep = itemp->subDTypep()->skipRefp();
|
||||
AstNodeDType* const subtypep = itemp->subDTypep()->skipRefp();
|
||||
const int index_code = itemp->lsb();
|
||||
ToggleEnt newent(above.m_comment + string(".") + itemp->name(),
|
||||
new AstSel(varp->fileline(), above.m_varRefp->cloneTree(true),
|
||||
|
|
@ -365,8 +365,8 @@ private:
|
|||
}
|
||||
} else if (AstUnionDType* adtypep = VN_CAST(dtypep, UnionDType)) {
|
||||
// Arbitrarily handle only the first member of the union
|
||||
if (AstMemberDType* itemp = adtypep->membersp()) {
|
||||
AstNodeDType* subtypep = itemp->subDTypep()->skipRefp();
|
||||
if (AstMemberDType* const itemp = adtypep->membersp()) {
|
||||
AstNodeDType* const subtypep = itemp->subDTypep()->skipRefp();
|
||||
ToggleEnt newent(above.m_comment + string(".") + itemp->name(),
|
||||
above.m_varRefp->cloneTree(true),
|
||||
above.m_chgRefp->cloneTree(true));
|
||||
|
|
|
|||
|
|
@ -60,18 +60,18 @@ private:
|
|||
const auto dupit = dupFinder.findDuplicate(nodep->origp());
|
||||
if (dupit == dupFinder.end()) break;
|
||||
//
|
||||
AstNode* duporigp = dupit->second;
|
||||
const AstNode* const duporigp = dupit->second;
|
||||
// Note hashed will point to the original variable (what's
|
||||
// duplicated), not the covertoggle, but we need to get back to the
|
||||
// covertoggle which is immediately above, so:
|
||||
AstCoverToggle* removep = VN_AS(duporigp->backp(), CoverToggle);
|
||||
AstCoverToggle* const removep = VN_AS(duporigp->backp(), CoverToggle);
|
||||
UASSERT_OBJ(removep, nodep, "CoverageJoin duplicate of wrong type");
|
||||
UINFO(8, " Orig " << nodep << " -->> " << nodep->incp()->declp() << endl);
|
||||
UINFO(8, " dup " << removep << " -->> " << removep->incp()->declp() << endl);
|
||||
// The CoverDecl the duplicate pointed to now needs to point to the
|
||||
// original's data. I.e. the duplicate will get the coverage number
|
||||
// from the non-duplicate
|
||||
AstCoverDecl* datadeclp = nodep->incp()->declp()->dataDeclThisp();
|
||||
AstCoverDecl* const datadeclp = nodep->incp()->declp()->dataDeclThisp();
|
||||
removep->incp()->declp()->dataDeclp(datadeclp);
|
||||
UINFO(8, " new " << removep->incp()->declp() << endl);
|
||||
// Mark the found node as a duplicate of the first node
|
||||
|
|
|
|||
|
|
@ -102,9 +102,9 @@ private:
|
|||
|
||||
void checkAll(AstNode* nodep) {
|
||||
if (nodep != nodep->dtypep()) { // NodeDTypes reference themselves
|
||||
if (AstNode* subnodep = nodep->dtypep()) subnodep->user1Inc();
|
||||
if (AstNode* const subnodep = nodep->dtypep()) subnodep->user1Inc();
|
||||
}
|
||||
if (AstNode* subnodep = nodep->getChildDTypep()) subnodep->user1Inc();
|
||||
if (AstNode* const subnodep = nodep->getChildDTypep()) subnodep->user1Inc();
|
||||
}
|
||||
void checkVarRef(AstNodeVarRef* nodep) {
|
||||
if (nodep->classOrPackagep() && m_elimCells) nodep->classOrPackagep(nullptr);
|
||||
|
|
@ -116,8 +116,8 @@ private:
|
|||
) {
|
||||
m_dtypesp.push_back(nodep);
|
||||
}
|
||||
if (AstNode* subnodep = nodep->virtRefDTypep()) subnodep->user1Inc();
|
||||
if (AstNode* subnodep = nodep->virtRefDType2p()) subnodep->user1Inc();
|
||||
if (AstNode* const subnodep = nodep->virtRefDTypep()) subnodep->user1Inc();
|
||||
if (AstNode* const subnodep = nodep->virtRefDType2p()) subnodep->user1Inc();
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
|
|
@ -129,7 +129,7 @@ private:
|
|||
if (!nodep->dead()) {
|
||||
iterateChildren(nodep);
|
||||
checkAll(nodep);
|
||||
if (AstClass* classp = VN_CAST(nodep, Class)) {
|
||||
if (AstClass* const classp = VN_CAST(nodep, Class)) {
|
||||
if (classp->extendsp()) classp->extendsp()->user1Inc();
|
||||
if (classp->classOrPackagep()) classp->classOrPackagep()->user1Inc();
|
||||
m_classesp.push_back(classp);
|
||||
|
|
@ -282,7 +282,7 @@ private:
|
|||
iterateAndNextNull(nodep->rhsp());
|
||||
checkAll(nodep);
|
||||
// Has to be direct assignment without any EXTRACTing.
|
||||
AstVarRef* varrefp = VN_CAST(nodep->lhsp(), VarRef);
|
||||
AstVarRef* const varrefp = VN_CAST(nodep->lhsp(), VarRef);
|
||||
if (varrefp && !m_sideEffect
|
||||
&& varrefp->varScopep()) { // For simplicity, we only remove post-scoping
|
||||
m_assignMap.emplace(varrefp->varScopep(), nodep);
|
||||
|
|
@ -338,7 +338,7 @@ private:
|
|||
retry = false;
|
||||
for (std::vector<AstScope*>::iterator it = m_scopesp.begin(); it != m_scopesp.end();
|
||||
++it) {
|
||||
AstScope* scp = *it;
|
||||
AstScope* const scp = *it;
|
||||
if (!scp) continue;
|
||||
if (scp->user1() == 0) {
|
||||
UINFO(4, " Dead AstScope " << scp << endl);
|
||||
|
|
@ -364,7 +364,7 @@ private:
|
|||
for (bool retry = true; retry;) {
|
||||
retry = false;
|
||||
for (auto& itr : m_classesp) {
|
||||
if (AstClass* nodep = itr) { // nullptr if deleted earlier
|
||||
if (AstClass* const nodep = itr) { // nullptr if deleted earlier
|
||||
if (nodep->user1() == 0) {
|
||||
if (nodep->extendsp()) nodep->extendsp()->user1Inc(-1);
|
||||
if (nodep->classOrPackagep()) nodep->classOrPackagep()->user1Inc(-1);
|
||||
|
|
@ -385,7 +385,7 @@ private:
|
|||
std::pair<AssignMap::iterator, AssignMap::iterator> eqrange
|
||||
= m_assignMap.equal_range(vscp);
|
||||
for (AssignMap::iterator itr = eqrange.first; itr != eqrange.second; ++itr) {
|
||||
AstNodeAssign* assp = itr->second;
|
||||
AstNodeAssign* const assp = itr->second;
|
||||
UINFO(4, " Dead assign " << assp << endl);
|
||||
assp->dtypep()->user1Inc(-1);
|
||||
VL_DO_DANGLING(assp->unlinkFrBack()->deleteTree(), assp);
|
||||
|
|
@ -398,7 +398,7 @@ private:
|
|||
for (bool retry = true; retry;) {
|
||||
retry = false;
|
||||
for (std::vector<AstVar*>::iterator it = m_varsp.begin(); it != m_varsp.end(); ++it) {
|
||||
AstVar* varp = *it;
|
||||
AstVar* const varp = *it;
|
||||
if (!varp) continue;
|
||||
if (varp->user1() == 0) {
|
||||
UINFO(4, " Dead " << varp << endl);
|
||||
|
|
@ -411,7 +411,7 @@ private:
|
|||
}
|
||||
for (std::vector<AstNode*>::iterator it = m_dtypesp.begin(); it != m_dtypesp.end(); ++it) {
|
||||
if ((*it)->user1() == 0) {
|
||||
AstNodeUOrStructDType* classp;
|
||||
const AstNodeUOrStructDType* classp;
|
||||
// It's possible that there if a reference to each individual member, but
|
||||
// not to the dtype itself. Check and don't remove the parent dtype if
|
||||
// members are still alive.
|
||||
|
|
|
|||
|
|
@ -104,16 +104,16 @@ private:
|
|||
|
||||
void markVarUsage(AstNodeVarRef* nodep, bool blocking) {
|
||||
if (blocking) nodep->user5(true);
|
||||
AstVarScope* vscp = nodep->varScopep();
|
||||
AstVarScope* const vscp = nodep->varScopep();
|
||||
// UINFO(4, " MVU " << blocking << " " << nodep << endl);
|
||||
AstNode* lastrefp = vscp->user5p();
|
||||
AstNode* const lastrefp = vscp->user5p();
|
||||
if (!lastrefp) {
|
||||
vscp->user5p(nodep);
|
||||
} else {
|
||||
const bool last_was_blocking = lastrefp->user5();
|
||||
if (last_was_blocking != blocking) {
|
||||
AstNode* nonblockingp = blocking ? nodep : lastrefp;
|
||||
AstNode* blockingp = blocking ? lastrefp : nodep;
|
||||
const AstNode* const nonblockingp = blocking ? nodep : lastrefp;
|
||||
const AstNode* const blockingp = blocking ? lastrefp : nodep;
|
||||
vscp->v3warn(
|
||||
BLKANDNBLK,
|
||||
"Unsupported: Blocked and non-blocking assignments to same variable: "
|
||||
|
|
@ -131,7 +131,7 @@ private:
|
|||
// Because we've already scoped it, we may need to add both the AstVar and the AstVarScope
|
||||
UASSERT_OBJ(oldvarscp->scopep(), oldvarscp, "Var unscoped");
|
||||
AstVar* varp;
|
||||
AstNodeModule* addmodp = oldvarscp->scopep()->modp();
|
||||
AstNodeModule* const addmodp = oldvarscp->scopep()->modp();
|
||||
// We need a new AstVar, but only one for all scopes, to match the new AstVarScope
|
||||
const auto it = m_modVarMap.find(std::make_pair(addmodp, name));
|
||||
if (it != m_modVarMap.end()) {
|
||||
|
|
@ -152,13 +152,14 @@ private:
|
|||
m_modVarMap.emplace(std::make_pair(addmodp, name), varp);
|
||||
}
|
||||
|
||||
AstVarScope* varscp = new AstVarScope(oldvarscp->fileline(), oldvarscp->scopep(), varp);
|
||||
AstVarScope* const varscp
|
||||
= new AstVarScope(oldvarscp->fileline(), oldvarscp->scopep(), varp);
|
||||
oldvarscp->scopep()->addVarp(varscp);
|
||||
return varscp;
|
||||
}
|
||||
|
||||
AstActive* createActivePost(AstVarRef* varrefp) {
|
||||
AstActive* newactp
|
||||
AstActive* const newactp
|
||||
= new AstActive(varrefp->fileline(), "sequentdly", m_activep->sensesp());
|
||||
// Was addNext(), but addNextHere() avoids a linear search.
|
||||
m_activep->addNextHere(newactp);
|
||||
|
|
@ -184,11 +185,11 @@ private:
|
|||
UINFO(4, " Act: " << m_activep << endl);
|
||||
UINFO(4, " Act: " << oldactivep << endl);
|
||||
// Make a new sensitivity list, which is the combination of both blocks
|
||||
AstSenItem* sena = m_activep->sensesp()->sensesp()->cloneTree(true);
|
||||
AstSenItem* senb = oldactivep->sensesp()->sensesp()->cloneTree(true);
|
||||
AstSenTree* treep = new AstSenTree(m_activep->fileline(), sena);
|
||||
AstSenItem* const sena = m_activep->sensesp()->sensesp()->cloneTree(true);
|
||||
AstSenItem* const senb = oldactivep->sensesp()->sensesp()->cloneTree(true);
|
||||
AstSenTree* const treep = new AstSenTree(m_activep->fileline(), sena);
|
||||
if (senb) treep->addSensesp(senb);
|
||||
if (AstSenTree* storep = oldactivep->sensesStorep()) {
|
||||
if (AstSenTree* const storep = oldactivep->sensesStorep()) {
|
||||
storep->unlinkFrBack();
|
||||
pushDeletep(storep);
|
||||
}
|
||||
|
|
@ -203,7 +204,7 @@ private:
|
|||
// Return the new LHS for the assignment, Null = unlink
|
||||
// Find selects
|
||||
AstNode* newlhsp = nullptr; // nullptr = unlink old assign
|
||||
AstSel* bitselp = nullptr;
|
||||
const AstSel* bitselp = nullptr;
|
||||
AstArraySel* arrayselp = nullptr;
|
||||
if (VN_IS(lhsp, Sel)) {
|
||||
bitselp = VN_AS(lhsp, Sel);
|
||||
|
|
@ -220,27 +221,27 @@ private:
|
|||
std::deque<AstNode*> dimvalp; // Assignment value for each dimension of assignment
|
||||
AstNode* dimselp = arrayselp;
|
||||
for (; VN_IS(dimselp, ArraySel); dimselp = VN_AS(dimselp, ArraySel)->fromp()) {
|
||||
AstNode* valp = VN_AS(dimselp, ArraySel)->bitp()->unlinkFrBack();
|
||||
AstNode* const valp = VN_AS(dimselp, ArraySel)->bitp()->unlinkFrBack();
|
||||
dimvalp.push_front(valp);
|
||||
}
|
||||
AstVarRef* varrefp = VN_AS(dimselp, VarRef);
|
||||
AstVarRef* const varrefp = VN_AS(dimselp, VarRef);
|
||||
UASSERT_OBJ(varrefp, nodep, "No var underneath arraysels");
|
||||
UASSERT_OBJ(varrefp->varScopep(), varrefp, "Var didn't get varscoped in V3Scope.cpp");
|
||||
varrefp->unlinkFrBack();
|
||||
AstVar* oldvarp = varrefp->varp();
|
||||
const AstVar* const oldvarp = varrefp->varp();
|
||||
const int modVecNum = m_scopeVecMap[varrefp->varScopep()]++;
|
||||
//
|
||||
std::deque<AstNode*> dimreadps; // Read value for each dimension of assignment
|
||||
for (unsigned dimension = 0; dimension < dimvalp.size(); dimension++) {
|
||||
AstNode* dimp = dimvalp[dimension];
|
||||
AstNode* const dimp = dimvalp[dimension];
|
||||
if (VN_IS(dimp, Const)) { // bit = const, can just use it
|
||||
dimreadps.push_front(dimp);
|
||||
} else {
|
||||
const string bitvarname = (string("__Vdlyvdim") + cvtToStr(dimension) + "__"
|
||||
+ oldvarp->shortName() + "__v" + cvtToStr(modVecNum));
|
||||
AstVarScope* bitvscp
|
||||
AstVarScope* const bitvscp
|
||||
= createVarSc(varrefp->varScopep(), bitvarname, dimp->width(), nullptr);
|
||||
AstAssign* bitassignp = new AstAssign(
|
||||
AstAssign* const bitassignp = new AstAssign(
|
||||
nodep->fileline(), new AstVarRef(nodep->fileline(), bitvscp, VAccess::WRITE),
|
||||
dimp);
|
||||
nodep->addNextHere(bitassignp);
|
||||
|
|
@ -251,16 +252,16 @@ private:
|
|||
//=== Bitselect: __Vdlyvlsb__
|
||||
AstNode* bitreadp = nullptr; // Code to read Vdlyvlsb
|
||||
if (bitselp) {
|
||||
AstNode* lsbvaluep = bitselp->lsbp()->unlinkFrBack();
|
||||
AstNode* const lsbvaluep = bitselp->lsbp()->unlinkFrBack();
|
||||
if (VN_IS(bitselp->fromp(), Const)) {
|
||||
// vlsb = constant, can just push constant into where we use it
|
||||
bitreadp = lsbvaluep;
|
||||
} else {
|
||||
const string bitvarname = (string("__Vdlyvlsb__") + oldvarp->shortName() + "__v"
|
||||
+ cvtToStr(modVecNum));
|
||||
AstVarScope* bitvscp
|
||||
AstVarScope* const bitvscp
|
||||
= createVarSc(varrefp->varScopep(), bitvarname, lsbvaluep->width(), nullptr);
|
||||
AstAssign* bitassignp = new AstAssign(
|
||||
AstAssign* const bitassignp = new AstAssign(
|
||||
nodep->fileline(), new AstVarRef(nodep->fileline(), bitvscp, VAccess::WRITE),
|
||||
lsbvaluep);
|
||||
nodep->addNextHere(bitassignp);
|
||||
|
|
@ -276,7 +277,7 @@ private:
|
|||
} else {
|
||||
string valvarname
|
||||
= (string("__Vdlyvval__") + oldvarp->shortName() + "__v" + cvtToStr(modVecNum));
|
||||
AstVarScope* valvscp
|
||||
AstVarScope* const valvscp
|
||||
= createVarSc(varrefp->varScopep(), valvarname, 0, nodep->rhsp()->dtypep());
|
||||
newlhsp = new AstVarRef(nodep->fileline(), valvscp, VAccess::WRITE);
|
||||
valreadp = new AstVarRef(nodep->fileline(), valvscp, VAccess::READ);
|
||||
|
|
@ -300,7 +301,7 @@ private:
|
|||
setinitp = new AstAssignPre(nodep->fileline(),
|
||||
new AstVarRef(nodep->fileline(), setvscp, VAccess::WRITE),
|
||||
new AstConst(nodep->fileline(), 0));
|
||||
AstAssign* setassignp = new AstAssign(
|
||||
AstAssign* const setassignp = new AstAssign(
|
||||
nodep->fileline(), new AstVarRef(nodep->fileline(), setvscp, VAccess::WRITE),
|
||||
new AstConst(nodep->fileline(), AstConst::BitTrue()));
|
||||
nodep->addNextHere(setassignp);
|
||||
|
|
@ -327,13 +328,13 @@ private:
|
|||
UINFO(9, " & " << varrefp << endl);
|
||||
AstAlwaysPost* finalp = VN_AS(varrefp->varScopep()->user4p(), AlwaysPost);
|
||||
if (finalp) {
|
||||
AstActive* oldactivep = VN_AS(finalp->user2p(), Active);
|
||||
AstActive* const oldactivep = VN_AS(finalp->user2p(), Active);
|
||||
checkActivePost(varrefp, oldactivep);
|
||||
if (setinitp) oldactivep->addStmtsp(setinitp);
|
||||
} else { // first time we've dealt with this memory
|
||||
finalp = new AstAlwaysPost(nodep->fileline(), nullptr /*sens*/, nullptr /*body*/);
|
||||
UINFO(9, " Created " << finalp << endl);
|
||||
AstActive* newactp = createActivePost(varrefp);
|
||||
AstActive* const newactp = createActivePost(varrefp);
|
||||
newactp->addStmtsp(finalp);
|
||||
varrefp->varScopep()->user4p(finalp);
|
||||
finalp->user2p(newactp);
|
||||
|
|
@ -398,13 +399,13 @@ private:
|
|||
if (VN_IS(nodep->lhsp(), ArraySel)
|
||||
|| (VN_IS(nodep->lhsp(), Sel)
|
||||
&& VN_IS(VN_AS(nodep->lhsp(), Sel)->fromp(), ArraySel))) {
|
||||
AstNode* lhsp = nodep->lhsp()->unlinkFrBack();
|
||||
AstNode* newlhsp = createDlyArray(nodep, lhsp);
|
||||
AstNode* const lhsp = nodep->lhsp()->unlinkFrBack();
|
||||
AstNode* const newlhsp = createDlyArray(nodep, lhsp);
|
||||
if (m_inLoop) {
|
||||
nodep->v3warn(BLKLOOPINIT, "Unsupported: Delayed assignment to array inside for "
|
||||
"loops (non-delayed is ok - see docs)");
|
||||
}
|
||||
AstBasicDType* basicp = lhsp->dtypep()->basicp();
|
||||
const AstBasicDType* const basicp = lhsp->dtypep()->basicp();
|
||||
if (basicp && basicp->isEventValue()) {
|
||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: event arrays");
|
||||
}
|
||||
|
|
@ -432,18 +433,18 @@ private:
|
|||
nodep->v3error("Internal: Blocking <= assignment in non-clocked block, should "
|
||||
"have converted in V3Active");
|
||||
}
|
||||
AstVarScope* oldvscp = nodep->varScopep();
|
||||
AstVarScope* const oldvscp = nodep->varScopep();
|
||||
UASSERT_OBJ(oldvscp, nodep, "Var didn't get varscoped in V3Scope.cpp");
|
||||
AstVarScope* dlyvscp = VN_AS(oldvscp->user1p(), VarScope);
|
||||
if (dlyvscp) { // Multiple use of delayed variable
|
||||
AstActive* oldactivep = VN_AS(dlyvscp->user2p(), Active);
|
||||
AstActive* const oldactivep = VN_AS(dlyvscp->user2p(), Active);
|
||||
checkActivePost(nodep, oldactivep);
|
||||
}
|
||||
if (!dlyvscp) { // First use of this delayed variable
|
||||
const string newvarname = (string("__Vdly__") + nodep->varp()->shortName());
|
||||
dlyvscp = createVarSc(oldvscp, newvarname, 0, nullptr);
|
||||
AstNodeAssign* prep;
|
||||
AstBasicDType* basicp = oldvscp->dtypep()->basicp();
|
||||
const AstBasicDType* const basicp = oldvscp->dtypep()->basicp();
|
||||
if (basicp && basicp->isEventValue()) {
|
||||
// Events go to zero on next timestep unless reactivated
|
||||
prep = new AstAssignPre(
|
||||
|
|
@ -456,19 +457,20 @@ private:
|
|||
new AstVarRef(nodep->fileline(), dlyvscp, VAccess::WRITE),
|
||||
new AstVarRef(nodep->fileline(), oldvscp, VAccess::READ));
|
||||
}
|
||||
AstNodeAssign* postp = new AstAssignPost(
|
||||
AstNodeAssign* const postp = new AstAssignPost(
|
||||
nodep->fileline(),
|
||||
new AstVarRef(nodep->fileline(), oldvscp, VAccess::WRITE),
|
||||
new AstVarRef(nodep->fileline(), dlyvscp, VAccess::READ));
|
||||
postp->lhsp()->user2(true); // Don't detect this assignment
|
||||
oldvscp->user1p(dlyvscp); // So we can find it later
|
||||
// Make new ACTIVE with identical sensitivity tree
|
||||
AstActive* newactp = createActivePost(nodep);
|
||||
AstActive* const newactp = createActivePost(nodep);
|
||||
dlyvscp->user2p(newactp);
|
||||
newactp->addStmtsp(prep); // Add to FRONT of statements
|
||||
newactp->addStmtsp(postp);
|
||||
}
|
||||
AstVarRef* newrefp = new AstVarRef(nodep->fileline(), dlyvscp, VAccess::WRITE);
|
||||
AstVarRef* const newrefp
|
||||
= new AstVarRef(nodep->fileline(), dlyvscp, VAccess::WRITE);
|
||||
newrefp->user2(true); // No reason to do it again
|
||||
nodep->replaceWith(newrefp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ private:
|
|||
if (m_depth > v3Global.opt.compLimitBlocks()
|
||||
&& !VN_IS(nodep, NodeCCall)) { // Already done
|
||||
UINFO(4, "DeepBlocks " << m_depth << " " << nodep << endl);
|
||||
AstNode* backp = nodep->backp(); // Only for debug
|
||||
const AstNode* backp = nodep->backp(); // Only for debug
|
||||
if (debug() >= 9) backp->dumpTree(cout, "- pre : ");
|
||||
AstCFunc* funcp = createDeepFunc(nodep);
|
||||
iterate(funcp);
|
||||
|
|
|
|||
|
|
@ -107,14 +107,14 @@ private:
|
|||
// If multiple functions exist, we need to select the appropriate scope.
|
||||
for (FuncMmap::iterator it = m_modFuncs.begin(); it != m_modFuncs.end(); ++it) {
|
||||
const string name = it->first;
|
||||
AstCFunc* topFuncp = it->second;
|
||||
AstCFunc* const topFuncp = it->second;
|
||||
auto nextIt1 = it;
|
||||
++nextIt1;
|
||||
bool moreOfSame1 = (nextIt1 != m_modFuncs.end() && nextIt1->first == name);
|
||||
if (moreOfSame1) {
|
||||
// Multiple functions under this name, need a wrapper function
|
||||
UINFO(6, " Wrapping " << name << " multifuncs\n");
|
||||
AstCFunc* newfuncp = topFuncp->cloneTree(false);
|
||||
AstCFunc* const newfuncp = topFuncp->cloneTree(false);
|
||||
if (newfuncp->initsp()) newfuncp->initsp()->unlinkFrBackWithNext()->deleteTree();
|
||||
if (newfuncp->stmtsp()) newfuncp->stmtsp()->unlinkFrBackWithNext()->deleteTree();
|
||||
if (newfuncp->finalsp()) newfuncp->finalsp()->unlinkFrBackWithNext()->deleteTree();
|
||||
|
|
@ -125,7 +125,7 @@ private:
|
|||
for (FuncMmap::iterator eachIt = it;
|
||||
eachIt != m_modFuncs.end() && eachIt->first == name; ++eachIt) {
|
||||
it = eachIt;
|
||||
AstCFunc* funcp = eachIt->second;
|
||||
AstCFunc* const funcp = eachIt->second;
|
||||
auto nextIt2 = eachIt;
|
||||
++nextIt2;
|
||||
const bool moreOfSame
|
||||
|
|
@ -138,21 +138,21 @@ private:
|
|||
funcp->declPrivate(true);
|
||||
AstNode* argsp = nullptr;
|
||||
for (AstNode* stmtp = newfuncp->argsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (AstVar* const portp = VN_CAST(stmtp, Var)) {
|
||||
if (portp->isIO() && !portp->isFuncReturn()) {
|
||||
AstNode* newp = new AstVarRef(portp->fileline(), portp,
|
||||
portp->isWritable() ? VAccess::WRITE
|
||||
: VAccess::READ);
|
||||
AstNode* const newp = new AstVarRef(
|
||||
portp->fileline(), portp,
|
||||
portp->isWritable() ? VAccess::WRITE : VAccess::READ);
|
||||
argsp = argsp ? argsp->addNextNull(newp) : newp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AstNode* returnp = new AstCReturn(
|
||||
AstNode* const returnp = new AstCReturn(
|
||||
funcp->fileline(), new AstCCall(funcp->fileline(), funcp, argsp));
|
||||
|
||||
if (moreOfSame) {
|
||||
AstIf* ifp = new AstIf(
|
||||
AstIf* const ifp = new AstIf(
|
||||
funcp->fileline(),
|
||||
new AstEq(
|
||||
funcp->fileline(), new AstCMath(funcp->fileline(), "this", 64),
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ string EmitCBaseVisitor::funcNameProtect(const AstCFunc* nodep, const AstNodeMod
|
|||
}
|
||||
|
||||
AstCFile* EmitCBaseVisitor::newCFile(const string& filename, bool slow, bool source) {
|
||||
AstCFile* cfilep = new AstCFile(v3Global.rootp()->fileline(), filename);
|
||||
AstCFile* const cfilep = new AstCFile(v3Global.rootp()->fileline(), filename);
|
||||
cfilep->slow(slow);
|
||||
cfilep->source(source);
|
||||
v3Global.rootp()->addFilesp(cfilep);
|
||||
|
|
@ -78,7 +78,7 @@ string EmitCBaseVisitor::cFuncArgs(const AstCFunc* nodep) {
|
|||
}
|
||||
// Might be a user function with argument list.
|
||||
for (const AstNode* stmtp = nodep->argsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (const AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (const AstVar* const portp = VN_CAST(stmtp, Var)) {
|
||||
if (portp->isIO() && !portp->isFuncReturn()) {
|
||||
if (args != "") args += ", ";
|
||||
if (nodep->dpiImportPrototype() || nodep->dpiExportDispatcher()) {
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ void EmitCFunc::displayEmit(AstNode* nodep, bool isScan) {
|
|||
} else {
|
||||
// Format
|
||||
bool isStmt = false;
|
||||
if (const AstFScanF* dispp = VN_CAST(nodep, FScanF)) {
|
||||
if (const AstFScanF* const dispp = VN_CAST(nodep, FScanF)) {
|
||||
isStmt = false;
|
||||
puts("VL_FSCANF_IX(");
|
||||
iterate(dispp->filep());
|
||||
|
|
@ -238,7 +238,7 @@ void EmitCFunc::displayEmit(AstNode* nodep, bool isScan) {
|
|||
// Arguments
|
||||
for (unsigned i = 0; i < emitDispState.m_argsp.size(); i++) {
|
||||
const char fmt = emitDispState.m_argsChar[i];
|
||||
AstNode* argp = emitDispState.m_argsp[i];
|
||||
AstNode* const argp = emitDispState.m_argsp[i];
|
||||
const string func = emitDispState.m_argsFunc[i];
|
||||
if (func != "" || argp) {
|
||||
puts(",");
|
||||
|
|
@ -316,7 +316,7 @@ void EmitCFunc::displayArg(AstNode* dispp, AstNode** elistp, bool isScan, const
|
|||
emitDispState.pushArg(fmtLetter, argp, "");
|
||||
if (fmtLetter == 't' || fmtLetter == '^') {
|
||||
AstSFormatF* fmtp = nullptr;
|
||||
if (AstDisplay* nodep = VN_CAST(dispp, Display))
|
||||
if (AstDisplay* const nodep = VN_CAST(dispp, Display))
|
||||
fmtp = nodep->fmtp();
|
||||
else if (AstSFormat* nodep = VN_CAST(dispp, SFormat))
|
||||
fmtp = nodep->fmtp();
|
||||
|
|
@ -472,7 +472,7 @@ void EmitCFunc::emitDereference(const string& pointer) {
|
|||
}
|
||||
|
||||
void EmitCFunc::emitCvtPackStr(AstNode* nodep) {
|
||||
if (const AstConst* constp = VN_CAST(nodep, Const)) {
|
||||
if (const AstConst* const constp = VN_CAST(nodep, Const)) {
|
||||
putbs("std::string(");
|
||||
putsQuoted(constp->num().toString());
|
||||
puts(")");
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ class CMakeEmitter final {
|
|||
std::vector<string> global;
|
||||
for (AstNodeFile* nodep = v3Global.rootp()->filesp(); nodep;
|
||||
nodep = VN_AS(nodep->nextp(), NodeFile)) {
|
||||
AstCFile* cfilep = VN_CAST(nodep, CFile);
|
||||
const AstCFile* const cfilep = VN_CAST(nodep, CFile);
|
||||
if (cfilep && cfilep->source()) {
|
||||
if (cfilep->support()) {
|
||||
if (cfilep->slow()) {
|
||||
|
|
|
|||
|
|
@ -50,9 +50,9 @@ class EmitCSyms final : EmitCBaseVisitor {
|
|||
, m_type{type} {}
|
||||
};
|
||||
struct ScopeFuncData {
|
||||
AstScopeName* m_scopep;
|
||||
AstCFunc* m_cfuncp;
|
||||
AstNodeModule* m_modp;
|
||||
AstScopeName* const m_scopep;
|
||||
AstCFunc* const m_cfuncp;
|
||||
AstNodeModule* const m_modp;
|
||||
ScopeFuncData(AstScopeName* scopep, AstCFunc* funcp, AstNodeModule* modp)
|
||||
: m_scopep{scopep}
|
||||
, m_cfuncp{funcp}
|
||||
|
|
@ -61,9 +61,9 @@ class EmitCSyms final : EmitCBaseVisitor {
|
|||
struct ScopeVarData {
|
||||
string m_scopeName;
|
||||
string m_varBasePretty;
|
||||
AstVar* m_varp;
|
||||
AstNodeModule* m_modp;
|
||||
AstScope* m_scopep;
|
||||
AstVar* const m_varp;
|
||||
AstNodeModule* const m_modp;
|
||||
AstScope* const m_scopep;
|
||||
ScopeVarData(const string& scopeName, const string& varBasePretty, AstVar* varp,
|
||||
AstNodeModule* modp, AstScope* scopep)
|
||||
: m_scopeName{scopeName}
|
||||
|
|
@ -193,12 +193,12 @@ class EmitCSyms final : EmitCBaseVisitor {
|
|||
// Someday. For now public isn't common.
|
||||
for (std::vector<ScopeModPair>::iterator itsc = m_scopes.begin(); itsc != m_scopes.end();
|
||||
++itsc) {
|
||||
AstScope* scopep = itsc->first;
|
||||
AstNodeModule* smodp = itsc->second;
|
||||
AstScope* const scopep = itsc->first;
|
||||
const AstNodeModule* const smodp = itsc->second;
|
||||
for (std::vector<ModVarPair>::iterator it = m_modVars.begin(); it != m_modVars.end();
|
||||
++it) {
|
||||
AstNodeModule* modp = it->first;
|
||||
AstVar* varp = it->second;
|
||||
AstNodeModule* const modp = it->first;
|
||||
AstVar* const varp = it->second;
|
||||
if (modp == smodp) {
|
||||
// Need to split the module + var name into the
|
||||
// original-ish full scope and variable name under that scope.
|
||||
|
|
@ -411,7 +411,7 @@ void EmitCSyms::emitSymHdr() {
|
|||
puts("\n// DPI TYPES for DPI Export callbacks (Internal use)\n");
|
||||
std::map<const string, int> types; // Remove duplicates and sort
|
||||
for (const auto& itr : m_scopeFuncs) {
|
||||
AstCFunc* funcp = itr.second.m_cfuncp;
|
||||
const AstCFunc* const funcp = itr.second.m_cfuncp;
|
||||
if (funcp->dpiExportImpl()) {
|
||||
const string cbtype
|
||||
= protect(v3Global.opt.prefix() + "__Vcb_" + funcp->cname() + "_t");
|
||||
|
|
@ -461,8 +461,8 @@ void EmitCSyms::emitSymHdr() {
|
|||
|
||||
puts("\n// MODULE INSTANCE STATE\n");
|
||||
for (const auto& i : m_scopes) {
|
||||
AstScope* scopep = i.first;
|
||||
AstNodeModule* modp = i.second;
|
||||
const AstScope* const scopep = i.first;
|
||||
const AstNodeModule* const modp = i.second;
|
||||
if (VN_IS(modp, Class)) continue;
|
||||
const string name = prefixNameProtect(modp);
|
||||
ofp()->printf("%-30s ", name.c_str());
|
||||
|
|
@ -484,7 +484,8 @@ void EmitCSyms::emitSymHdr() {
|
|||
for (const V3GraphVertex* vxp
|
||||
= v3Global.rootp()->execGraphp()->depGraphp()->verticesBeginp();
|
||||
vxp; vxp = vxp->verticesNextp()) {
|
||||
ExecMTask* mtp = dynamic_cast<ExecMTask*>(const_cast<V3GraphVertex*>(vxp));
|
||||
const ExecMTask* const mtp
|
||||
= dynamic_cast<ExecMTask*>(const_cast<V3GraphVertex*>(vxp));
|
||||
if (maxProfilerId < mtp->profilerId()) maxProfilerId = mtp->profilerId();
|
||||
}
|
||||
}
|
||||
|
|
@ -553,7 +554,7 @@ void EmitCSyms::checkSplit(bool usesVfinal) {
|
|||
m_numStmts = 0;
|
||||
string filename
|
||||
= v3Global.opt.makeDir() + "/" + symClassName() + "__" + cvtToStr(++m_funcNum) + ".cpp";
|
||||
AstCFile* cfilep = newCFile(filename, true /*slow*/, true /*source*/);
|
||||
AstCFile* const cfilep = newCFile(filename, true /*slow*/, true /*source*/);
|
||||
cfilep->support(true);
|
||||
m_usesVfinal[m_funcNum] = usesVfinal;
|
||||
closeSplit();
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ public:
|
|||
} else {
|
||||
for (AstNodeFile* nodep = v3Global.rootp()->filesp(); nodep;
|
||||
nodep = VN_AS(nodep->nextp(), NodeFile)) {
|
||||
AstCFile* cfilep = VN_CAST(nodep, CFile);
|
||||
const AstCFile* const cfilep = VN_CAST(nodep, CFile);
|
||||
if (cfilep && cfilep->source() && cfilep->slow() == (slow != 0)
|
||||
&& cfilep->support() == (support != 0)) {
|
||||
putMakeClassEntry(of, cfilep->name());
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
}
|
||||
virtual void visit(AstNodeCase* nodep) override {
|
||||
putfs(nodep, "");
|
||||
if (const AstCase* casep = VN_CAST(nodep, Case)) {
|
||||
if (const AstCase* const casep = VN_CAST(nodep, Case)) {
|
||||
if (casep->priorityPragma()) puts("priority ");
|
||||
if (casep->uniquePragma()) puts("unique ");
|
||||
if (casep->unique0Pragma()) puts("unique0 ");
|
||||
|
|
@ -179,7 +179,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
puts(" (");
|
||||
iterateAndNextNull(nodep->exprp());
|
||||
puts(")\n");
|
||||
if (const AstCase* casep = VN_CAST(nodep, Case)) {
|
||||
if (const AstCase* const casep = VN_CAST(nodep, Case)) {
|
||||
if (casep->fullPragma() || casep->parallelPragma()) {
|
||||
puts(" // synopsys");
|
||||
if (casep->fullPragma()) puts(" full_case");
|
||||
|
|
@ -342,7 +342,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
}
|
||||
virtual void visit(AstNodeIf* nodep) override {
|
||||
putfs(nodep, "");
|
||||
if (const AstIf* ifp = VN_CAST(nodep, If)) {
|
||||
if (const AstIf* const ifp = VN_CAST(nodep, If)) {
|
||||
if (ifp->priorityPragma()) puts("priority ");
|
||||
if (ifp->uniquePragma()) puts("unique ");
|
||||
if (ifp->unique0Pragma()) puts("unique0 ");
|
||||
|
|
@ -416,7 +416,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
|
||||
// Operators
|
||||
virtual void emitVerilogFormat(AstNode* nodep, const string& format, AstNode* lhsp = nullptr,
|
||||
AstNode* rhsp = nullptr, AstNode* thsp = nullptr,
|
||||
AstNode* const rhsp = nullptr, AstNode* thsp = nullptr,
|
||||
AstNode* fhsp = nullptr) {
|
||||
// Look at emitVerilog() format for term/uni/dual/triops,
|
||||
// and write out appropriate text.
|
||||
|
|
@ -503,7 +503,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
if (comma++) putbs(", ");
|
||||
puts(cvtToStr(itr.first));
|
||||
puts(":");
|
||||
AstNode* valuep = itr.second->valuep();
|
||||
AstNode* const valuep = itr.second->valuep();
|
||||
iterate(valuep);
|
||||
}
|
||||
puts("}");
|
||||
|
|
@ -650,7 +650,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
std::vector<const AstUnpackArrayDType*> unpackps;
|
||||
for (AstNodeDType* dtypep = nodep->dtypep(); dtypep;) {
|
||||
dtypep = dtypep->skipRefp();
|
||||
if (AstUnpackArrayDType* unpackp = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||
if (AstUnpackArrayDType* const unpackp = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||
unpackps.push_back(unpackp);
|
||||
dtypep = unpackp->subDTypep();
|
||||
} else {
|
||||
|
|
@ -838,7 +838,7 @@ void V3EmitV::emitvFiles() {
|
|||
UINFO(2, __FUNCTION__ << ": " << endl);
|
||||
for (AstNodeFile* filep = v3Global.rootp()->filesp(); filep;
|
||||
filep = VN_AS(filep->nextp(), NodeFile)) {
|
||||
AstVFile* vfilep = VN_CAST(filep, VFile);
|
||||
AstVFile* const vfilep = VN_CAST(filep, VFile);
|
||||
if (vfilep && vfilep->tblockp()) {
|
||||
V3OutVFile of(vfilep->name());
|
||||
of.puts("// DESCR"
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ class EmitXmlFileVisitor final : public AstNVisitor {
|
|||
puts(" tag=");
|
||||
putsQuoted(nodep->tag());
|
||||
}
|
||||
if (AstNodeDType* dtp = VN_CAST(nodep, NodeDType)) {
|
||||
if (const AstNodeDType* const dtp = VN_CAST(nodep, NodeDType)) {
|
||||
if (dtp->subDTypep()) {
|
||||
puts(" sub_dtype_id=");
|
||||
outputId(dtp->subDTypep()->skipRefp());
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ void V3Error::init() {
|
|||
|
||||
string V3Error::lineStr(const char* filename, int lineno) {
|
||||
std::ostringstream out;
|
||||
const char* fnslashp = std::strrchr(filename, '/');
|
||||
const char* const fnslashp = std::strrchr(filename, '/');
|
||||
if (fnslashp) filename = fnslashp + 1;
|
||||
out << filename << ":" << std::dec << lineno << ":";
|
||||
const char* const spaces = " ";
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ inline void V3FileDependImp::writeTimes(const string& filename, const string& cm
|
|||
iter != m_filenameList.end(); ++iter) {
|
||||
// Read stats of files we create after we're done making them
|
||||
// (except for this file, of course)
|
||||
DependFile* dfp = const_cast<DependFile*>(&(*iter));
|
||||
DependFile* const dfp = const_cast<DependFile*>(&(*iter));
|
||||
V3Options::fileNfsFlush(dfp->filename());
|
||||
dfp->loadStats();
|
||||
off_t showSize = iter->size();
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ void FileLine::lineDirective(const char* textp, int& enterExitRef) {
|
|||
|
||||
// Grab linenumber
|
||||
bool fail = false;
|
||||
const char* ln = textp;
|
||||
const char* const ln = textp;
|
||||
while (*textp && !isspace(*textp)) textp++;
|
||||
if (isdigit(*ln)) {
|
||||
lineno(atoi(ln));
|
||||
|
|
@ -193,7 +193,7 @@ void FileLine::lineDirective(const char* textp, int& enterExitRef) {
|
|||
while (*textp && (isspace(*textp) || *textp == '"')) textp++;
|
||||
|
||||
// Grab filename
|
||||
const char* fn = textp;
|
||||
const char* const fn = textp;
|
||||
while (*textp && !(isspace(*textp) || *textp == '"')) textp++;
|
||||
if (textp != fn) {
|
||||
string strfn = fn;
|
||||
|
|
@ -244,7 +244,7 @@ FileLine* FileLine::copyOrSameFileLine() {
|
|||
if (lastNewp && *lastNewp == *this) { // Compares lineno, filename, etc
|
||||
return lastNewp;
|
||||
}
|
||||
FileLine* newp = new FileLine(this);
|
||||
FileLine* const newp = new FileLine(this);
|
||||
lastNewp = newp;
|
||||
return newp;
|
||||
}
|
||||
|
|
@ -430,14 +430,14 @@ string FileLine::warnContext(bool secondary) const {
|
|||
std::unordered_set<FileLine*> fileLineLeakChecks;
|
||||
|
||||
void* FileLine::operator new(size_t size) {
|
||||
FileLine* objp = static_cast<FileLine*>(::operator new(size));
|
||||
FileLine* const objp = static_cast<FileLine*>(::operator new(size));
|
||||
fileLineLeakChecks.insert(objp);
|
||||
return objp;
|
||||
}
|
||||
|
||||
void FileLine::operator delete(void* objp, size_t size) {
|
||||
if (!objp) return;
|
||||
FileLine* flp = static_cast<FileLine*>(objp);
|
||||
FileLine* const flp = static_cast<FileLine*>(objp);
|
||||
const auto it = fileLineLeakChecks.find(flp);
|
||||
if (it != fileLineLeakChecks.end()) {
|
||||
fileLineLeakChecks.erase(it);
|
||||
|
|
|
|||
183
src/V3Gate.cpp
183
src/V3Gate.cpp
|
|
@ -67,7 +67,7 @@ public:
|
|||
// Support classes
|
||||
|
||||
class GateEitherVertex VL_NOT_FINAL : public V3GraphVertex {
|
||||
AstScope* m_scopep; // Scope vertex refers to
|
||||
AstScope* const m_scopep; // Scope vertex refers to
|
||||
bool m_reducible = true; // True if this node should be able to be eliminated
|
||||
bool m_dedupable = true; // True if this node should be able to be deduped
|
||||
bool m_consumed = false; // Output goes to something meaningful
|
||||
|
|
@ -124,7 +124,7 @@ public:
|
|||
};
|
||||
|
||||
class GateVarVertex final : public GateEitherVertex {
|
||||
AstVarScope* m_varScp;
|
||||
AstVarScope* const m_varScp;
|
||||
bool m_isTop = false;
|
||||
bool m_isClock = false;
|
||||
AstNode* m_rstSyncNodep = nullptr; // Used as reset and not in SenItem, in clocked always
|
||||
|
|
@ -164,8 +164,8 @@ public:
|
|||
};
|
||||
|
||||
class GateLogicVertex final : public GateEitherVertex {
|
||||
AstNode* m_nodep;
|
||||
AstActive* m_activep; // Under what active; nullptr is ok (under cfunc or such)
|
||||
AstNode* const m_nodep;
|
||||
AstActive* const m_activep; // Under what active; nullptr is ok (under cfunc or such)
|
||||
bool m_slow; // In slow block
|
||||
public:
|
||||
GateLogicVertex(V3Graph* graphp, AstScope* scopep, AstNode* nodep, AstActive* activep,
|
||||
|
|
@ -227,7 +227,7 @@ private:
|
|||
m_lhsVarRef = nodep;
|
||||
} else {
|
||||
if (m_rhsVarRefs.size() > 1) {
|
||||
AstNodeVarRef* lastRefp = m_rhsVarRefs.back();
|
||||
const AstNodeVarRef* const lastRefp = m_rhsVarRefs.back();
|
||||
if (m_buffersOnly) clearSimple(">1 rhs varRefs");
|
||||
if (!nodep->varScopep()->varp()->gateMultiInputOptimizable()
|
||||
// We didn't check multiInput on the first varref, so check it here
|
||||
|
|
@ -440,9 +440,9 @@ private:
|
|||
virtual void visit(AstNodeVarRef* nodep) override {
|
||||
if (m_scopep) {
|
||||
UASSERT_OBJ(m_logicVertexp, nodep, "Var ref not under a logic block");
|
||||
AstVarScope* varscp = nodep->varScopep();
|
||||
AstVarScope* const varscp = nodep->varScopep();
|
||||
UASSERT_OBJ(varscp, nodep, "Var didn't get varscoped in V3Scope.cpp");
|
||||
GateVarVertex* vvertexp = makeVarVertex(varscp);
|
||||
GateVarVertex* const vvertexp = makeVarVertex(varscp);
|
||||
UINFO(5, " VARREF to " << varscp << endl);
|
||||
if (m_inSenItem) {
|
||||
vvertexp->setIsClock();
|
||||
|
|
@ -536,7 +536,7 @@ public:
|
|||
|
||||
void GateVisitor::optimizeSignals(bool allowMultiIn) {
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (GateVarVertex* vvertexp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
if (GateVarVertex* const vvertexp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
if (vvertexp->inEmpty()) {
|
||||
vvertexp->clearReducibleAndDedupable("inEmpty"); // Can't deal with no sources
|
||||
if (!vvertexp->isTop() // Ok if top inputs are driverless
|
||||
|
|
@ -562,7 +562,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
|
|||
UINFO(8, "SigNotRed " << vvertexp->name() << endl);
|
||||
} else {
|
||||
UINFO(8, "Sig " << vvertexp->name() << endl);
|
||||
GateLogicVertex* logicVertexp
|
||||
GateLogicVertex* const logicVertexp
|
||||
= dynamic_cast<GateLogicVertex*>(vvertexp->inBeginp()->fromp());
|
||||
UINFO(8, " From " << logicVertexp->name() << endl);
|
||||
AstNode* logicp = logicVertexp->nodep();
|
||||
|
|
@ -578,7 +578,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
|
|||
int n = 0;
|
||||
for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep;
|
||||
edgep = edgep->outNextp()) {
|
||||
GateLogicVertex* consumeVertexp
|
||||
const GateLogicVertex* const consumeVertexp
|
||||
= dynamic_cast<GateLogicVertex*>(edgep->top());
|
||||
if (!consumeVertexp->slow()) { // Not tracing or other slow path junk
|
||||
if (edgep->top()->outBeginp()) { // Destination is itself used
|
||||
|
|
@ -602,29 +602,29 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
|
|||
<< " " << vvertexp->name() << endl);
|
||||
for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep;
|
||||
edgep = edgep->outNextp()) {
|
||||
GateLogicVertex* consumeVertexp
|
||||
const GateLogicVertex* const consumeVertexp
|
||||
= dynamic_cast<GateLogicVertex*>(edgep->top());
|
||||
UINFO(9, " edge " << edgep << " to: " << consumeVertexp->nodep()
|
||||
<< endl);
|
||||
}
|
||||
for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep;
|
||||
edgep = edgep->inNextp()) {
|
||||
GateLogicVertex* consumeVertexp
|
||||
const GateLogicVertex* const consumeVertexp
|
||||
= dynamic_cast<GateLogicVertex*>(edgep->fromp());
|
||||
UINFO(9, " edge " << edgep << " from: "
|
||||
<< consumeVertexp->nodep() << endl);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
AstNode* substp = okVisitor.substTree();
|
||||
AstNode* const substp = okVisitor.substTree();
|
||||
if (debug() >= 5) logicp->dumpTree(cout, " elimVar: ");
|
||||
if (debug() >= 5) substp->dumpTree(cout, " subst: ");
|
||||
++m_statSigs;
|
||||
bool removedAllUsages = true;
|
||||
for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep;) {
|
||||
GateLogicVertex* consumeVertexp
|
||||
GateLogicVertex* const consumeVertexp
|
||||
= dynamic_cast<GateLogicVertex*>(edgep->top());
|
||||
AstNode* consumerp = consumeVertexp->nodep();
|
||||
AstNode* const consumerp = consumeVertexp->nodep();
|
||||
if (!elimLogicOkOutputs(consumeVertexp, okVisitor /*ref*/)) {
|
||||
// Cannot optimize this replacement
|
||||
removedAllUsages = false;
|
||||
|
|
@ -636,9 +636,9 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
|
|||
const GateVarRefList& rhsVarRefs = okVisitor.rhsVarRefs();
|
||||
for (GateVarRefList::const_iterator it = rhsVarRefs.begin();
|
||||
it != rhsVarRefs.end(); ++it) {
|
||||
AstVarScope* newvarscp = (*it)->varScopep();
|
||||
AstVarScope* const newvarscp = (*it)->varScopep();
|
||||
UINFO(9, " Point-to-new vertex " << newvarscp << endl);
|
||||
GateVarVertex* varvertexp = makeVarVertex(newvarscp);
|
||||
GateVarVertex* const varvertexp = makeVarVertex(newvarscp);
|
||||
new V3GraphEdge(&m_graph, varvertexp, consumeVertexp, 1);
|
||||
// Propagate clock attribute onto generating node
|
||||
varvertexp->propagateAttrClocksFrom(vvertexp);
|
||||
|
|
@ -685,12 +685,12 @@ bool GateVisitor::elimLogicOkOutputs(GateLogicVertex* consumeVertexp,
|
|||
// Replacement logic usually has shorter input list, so faster to build list based on it
|
||||
const GateVarRefList& rhsVarRefs = okVisitor.rhsVarRefs();
|
||||
for (GateVarRefList::const_iterator it = rhsVarRefs.begin(); it != rhsVarRefs.end(); ++it) {
|
||||
AstVarScope* vscp = (*it)->varScopep();
|
||||
AstVarScope* const vscp = (*it)->varScopep();
|
||||
varscopes.insert(vscp);
|
||||
}
|
||||
for (V3GraphEdge* edgep = consumeVertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||
GateVarVertex* consVVertexp = dynamic_cast<GateVarVertex*>(edgep->top());
|
||||
AstVarScope* vscp = consVVertexp->varScp();
|
||||
const GateVarVertex* const consVVertexp = dynamic_cast<GateVarVertex*>(edgep->top());
|
||||
AstVarScope* const vscp = consVVertexp->varScp();
|
||||
if (varscopes.find(vscp) != varscopes.end()) {
|
||||
UINFO(9, " Block-unopt, insertion generates input vscp " << vscp << endl);
|
||||
return false;
|
||||
|
|
@ -701,29 +701,29 @@ bool GateVisitor::elimLogicOkOutputs(GateLogicVertex* consumeVertexp,
|
|||
|
||||
void GateVisitor::replaceAssigns() {
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (GateVarVertex* vvertexp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
if (const GateVarVertex* const vvertexp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
// Take the Comments/assigns that were moved to the VarScope and change them to a
|
||||
// simple value assignment
|
||||
AstVarScope* vscp = vvertexp->varScp();
|
||||
const AstVarScope* const vscp = vvertexp->varScp();
|
||||
if (vscp->valuep() && !VN_IS(vscp->valuep(), NodeMath)) {
|
||||
// if (debug() > 9) vscp->dumpTree(cout, "-vscPre: ");
|
||||
while (AstNode* delp = VN_CAST(vscp->valuep(), Comment)) {
|
||||
VL_DO_DANGLING(delp->unlinkFrBack()->deleteTree(), delp);
|
||||
}
|
||||
if (AstInitial* delp = VN_CAST(vscp->valuep(), Initial)) {
|
||||
AstNode* bodyp = delp->bodysp();
|
||||
if (AstInitial* const delp = VN_CAST(vscp->valuep(), Initial)) {
|
||||
AstNode* const bodyp = delp->bodysp();
|
||||
bodyp->unlinkFrBackWithNext();
|
||||
delp->replaceWith(bodyp);
|
||||
VL_DO_DANGLING(delp->deleteTree(), delp);
|
||||
}
|
||||
if (AstAlways* delp = VN_CAST(vscp->valuep(), Always)) {
|
||||
AstNode* bodyp = delp->bodysp();
|
||||
if (AstAlways* const delp = VN_CAST(vscp->valuep(), Always)) {
|
||||
AstNode* const bodyp = delp->bodysp();
|
||||
bodyp->unlinkFrBackWithNext();
|
||||
delp->replaceWith(bodyp);
|
||||
VL_DO_DANGLING(delp->deleteTree(), delp);
|
||||
}
|
||||
if (AstNodeAssign* delp = VN_CAST(vscp->valuep(), NodeAssign)) {
|
||||
AstNode* rhsp = delp->rhsp();
|
||||
if (AstNodeAssign* const delp = VN_CAST(vscp->valuep(), NodeAssign)) {
|
||||
AstNode* const rhsp = delp->rhsp();
|
||||
rhsp->unlinkFrBack();
|
||||
delp->replaceWith(rhsp);
|
||||
VL_DO_DANGLING(delp->deleteTree(), delp);
|
||||
|
|
@ -745,7 +745,7 @@ void GateVisitor::consumedMark() {
|
|||
m_graph.userClearVertices();
|
||||
for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp;
|
||||
vertexp = vertexp->verticesNextp()) {
|
||||
GateEitherVertex* evertexp = static_cast<GateEitherVertex*>(vertexp);
|
||||
GateEitherVertex* const evertexp = static_cast<GateEitherVertex*>(vertexp);
|
||||
if (!evertexp->user() && evertexp->consumed()) consumedMarkRecurse(evertexp);
|
||||
}
|
||||
}
|
||||
|
|
@ -756,7 +756,7 @@ void GateVisitor::consumedMarkRecurse(GateEitherVertex* vertexp) {
|
|||
if (!vertexp->consumed()) vertexp->setConsumed("propagated");
|
||||
// Walk sources and mark them too
|
||||
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
GateEitherVertex* eFromVertexp = static_cast<GateEitherVertex*>(edgep->fromp());
|
||||
GateEitherVertex* const eFromVertexp = static_cast<GateEitherVertex*>(edgep->fromp());
|
||||
consumedMarkRecurse(eFromVertexp);
|
||||
}
|
||||
}
|
||||
|
|
@ -766,14 +766,14 @@ void GateVisitor::consumedMove() {
|
|||
// We need the "usually" block logic to do a better job at this
|
||||
for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp;
|
||||
vertexp = vertexp->verticesNextp()) {
|
||||
if (GateVarVertex* vvertexp = dynamic_cast<GateVarVertex*>(vertexp)) {
|
||||
if (const GateVarVertex* const vvertexp = dynamic_cast<GateVarVertex*>(vertexp)) {
|
||||
if (!vvertexp->consumed() && !vvertexp->user()) {
|
||||
UINFO(8, "Unconsumed " << vvertexp->varScp() << endl);
|
||||
}
|
||||
}
|
||||
if (GateLogicVertex* lvertexp = dynamic_cast<GateLogicVertex*>(vertexp)) {
|
||||
AstNode* nodep = lvertexp->nodep();
|
||||
AstActive* oldactp = lvertexp->activep(); // nullptr under cfunc
|
||||
if (const GateLogicVertex* const lvertexp = dynamic_cast<GateLogicVertex*>(vertexp)) {
|
||||
AstNode* const nodep = lvertexp->nodep();
|
||||
const AstActive* const oldactp = lvertexp->activep(); // nullptr under cfunc
|
||||
if (!lvertexp->consumed() && oldactp) {
|
||||
// Eventually: Move the statement to a new active block
|
||||
// with "tracing-on" sensitivity
|
||||
|
|
@ -790,10 +790,10 @@ void GateVisitor::consumedMove() {
|
|||
void GateVisitor::warnSignals() {
|
||||
AstNode::user2ClearTree();
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (GateVarVertex* vvertexp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
AstVarScope* vscp = vvertexp->varScp();
|
||||
AstNode* sp = vvertexp->rstSyncNodep();
|
||||
AstNode* ap = vvertexp->rstAsyncNodep();
|
||||
if (const GateVarVertex* const vvertexp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
const AstVarScope* const vscp = vvertexp->varScp();
|
||||
const AstNode* const sp = vvertexp->rstSyncNodep();
|
||||
const AstNode* const ap = vvertexp->rstAsyncNodep();
|
||||
if (ap && sp && !vscp->varp()->user2()) {
|
||||
// This is somewhat wrong, as marking one flop as ok for sync
|
||||
// may mean a different flop now fails. However it's a pain to
|
||||
|
|
@ -842,7 +842,7 @@ private:
|
|||
m_didReplace = true;
|
||||
UASSERT_OBJ(nodep->access().isReadOnly(), nodep,
|
||||
"Can't replace lvalue assignments with const var");
|
||||
AstNode* substp = m_replaceTreep->cloneTree(false);
|
||||
AstNode* const substp = m_replaceTreep->cloneTree(false);
|
||||
UASSERT_OBJ(!(VN_IS(substp, NodeVarRef) && nodep->same(substp)),
|
||||
// Prevent an infinite loop...
|
||||
substp, "Replacing node with itself; perhaps circular logic?");
|
||||
|
|
@ -853,7 +853,7 @@ private:
|
|||
// to throw warnings that point to a PIN rather than where the pin us used.
|
||||
if (VN_IS(substp, VarRef)) substp->fileline(nodep->fileline());
|
||||
// Make the substp an rvalue like nodep. This facilitates the hashing in dedupe.
|
||||
if (AstNodeVarRef* varrefp = VN_CAST(substp, NodeVarRef))
|
||||
if (AstNodeVarRef* const varrefp = VN_CAST(substp, NodeVarRef))
|
||||
varrefp->access(VAccess::READ);
|
||||
hashReplace(nodep, substp);
|
||||
nodep->replaceWith(substp);
|
||||
|
|
@ -961,8 +961,8 @@ public:
|
|||
bool isReplaced(AstNode* nodep) {
|
||||
// Assignment may have been hashReplaced, if so consider non-match (effectively removed)
|
||||
UASSERT_OBJ(!VN_IS(nodep, NodeAssign), nodep, "Dedup attempt on non-assign");
|
||||
AstNode* extra1p = nodep->user3p();
|
||||
AstNode* extra2p = nodep->user5p();
|
||||
AstNode* const extra1p = nodep->user3p();
|
||||
AstNode* const extra2p = nodep->user5p();
|
||||
return ((extra1p && m_nodeDeleteds.find(extra1p) != m_nodeDeleteds.end())
|
||||
|| (extra2p && m_nodeDeleteds.find(extra2p) != m_nodeDeleteds.end()));
|
||||
}
|
||||
|
|
@ -981,7 +981,7 @@ public:
|
|||
AstNodeAssign* hashAndFindDupe(AstNodeAssign* assignp, AstNode* extra1p, AstNode* extra2p) {
|
||||
// Legal for extra1p/2p to be nullptr, we'll compare with other assigns with extras also
|
||||
// nullptr
|
||||
AstNode* rhsp = assignp->rhsp();
|
||||
AstNode* const rhsp = assignp->rhsp();
|
||||
rhsp->user2p(assignp);
|
||||
rhsp->user3p(extra1p);
|
||||
rhsp->user5p(extra2p);
|
||||
|
|
@ -1001,9 +1001,9 @@ public:
|
|||
|
||||
void check() {
|
||||
for (const auto& itr : m_dupFinder) {
|
||||
AstNode* nodep = itr.second;
|
||||
AstNode* activep = nodep->user3p();
|
||||
AstNode* condVarp = nodep->user5p();
|
||||
AstNode* const nodep = itr.second;
|
||||
const AstNode* const activep = nodep->user3p();
|
||||
const AstNode* const condVarp = nodep->user5p();
|
||||
if (!isReplaced(nodep)) {
|
||||
// This class won't break if activep isn't an active, or
|
||||
// ifVar isn't a var, but this is checking the caller's construction.
|
||||
|
|
@ -1094,12 +1094,13 @@ public:
|
|||
m_dedupable = true;
|
||||
iterate(nodep);
|
||||
if (m_dedupable && m_assignp) {
|
||||
AstNode* lhsp = m_assignp->lhsp();
|
||||
AstNode* const lhsp = m_assignp->lhsp();
|
||||
// Possible todo, handle more complex lhs expressions
|
||||
if (AstNodeVarRef* lhsVarRefp = VN_CAST(lhsp, NodeVarRef)) {
|
||||
if (const AstNodeVarRef* const lhsVarRefp = VN_CAST(lhsp, NodeVarRef)) {
|
||||
UASSERT_OBJ(lhsVarRefp->varScopep() == consumerVarScopep, consumerVarScopep,
|
||||
"Consumer doesn't match lhs of assign");
|
||||
if (AstNodeAssign* dup = m_ghash.hashAndFindDupe(m_assignp, activep, m_ifCondp)) {
|
||||
if (const AstNodeAssign* const dup
|
||||
= m_ghash.hashAndFindDupe(m_assignp, activep, m_ifCondp)) {
|
||||
return static_cast<AstNodeVarRef*>(dup->lhsp());
|
||||
}
|
||||
}
|
||||
|
|
@ -1137,26 +1138,26 @@ private:
|
|||
|
||||
m_depth++;
|
||||
if (vvertexp->inSize1()) {
|
||||
AstNodeVarRef* dupVarRefp = static_cast<AstNodeVarRef*>(
|
||||
AstNodeVarRef* const dupVarRefp = static_cast<AstNodeVarRef*>(
|
||||
vvertexp->iterateInEdges(*this, VNUser(vvertexp)).toNodep());
|
||||
if (dupVarRefp) { // visit(GateLogicVertex*...) returned match
|
||||
V3GraphEdge* edgep = vvertexp->inBeginp();
|
||||
GateLogicVertex* lvertexp = static_cast<GateLogicVertex*>(edgep->fromp());
|
||||
GateLogicVertex* const lvertexp = static_cast<GateLogicVertex*>(edgep->fromp());
|
||||
UASSERT_OBJ(vvertexp->dedupable(), vvertexp->varScp(),
|
||||
"GateLogicVertex* visit should have returned nullptr "
|
||||
"if consumer var vertex is not dedupable.");
|
||||
GateOkVisitor okVisitor{lvertexp->nodep(), false, true};
|
||||
if (okVisitor.isSimple()) {
|
||||
AstVarScope* dupVarScopep = dupVarRefp->varScopep();
|
||||
GateVarVertex* dupVvertexp
|
||||
const AstVarScope* const dupVarScopep = dupVarRefp->varScopep();
|
||||
GateVarVertex* const dupVvertexp
|
||||
= reinterpret_cast<GateVarVertex*>(dupVarScopep->user1p());
|
||||
UINFO(4, "replacing " << vvertexp << " with " << dupVvertexp << endl);
|
||||
++m_numDeduped;
|
||||
// Replace all of this varvertex's consumers with dupVarRefp
|
||||
for (V3GraphEdge* outedgep = vvertexp->outBeginp(); outedgep;) {
|
||||
GateLogicVertex* consumeVertexp
|
||||
const GateLogicVertex* const consumeVertexp
|
||||
= dynamic_cast<GateLogicVertex*>(outedgep->top());
|
||||
AstNode* consumerp = consumeVertexp->nodep();
|
||||
AstNode* const consumerp = consumeVertexp->nodep();
|
||||
// if (debug() >= 9) m_graphp->dumpDotFilePrefixed("gate_preelim");
|
||||
UINFO(9,
|
||||
"elim src vtx" << lvertexp << " node " << lvertexp->nodep() << endl);
|
||||
|
|
@ -1198,15 +1199,16 @@ private:
|
|||
virtual VNUser visit(GateLogicVertex* lvertexp, VNUser vu) override {
|
||||
lvertexp->iterateInEdges(*this);
|
||||
|
||||
GateVarVertex* consumerVvertexpp = static_cast<GateVarVertex*>(vu.toGraphVertex());
|
||||
const GateVarVertex* const consumerVvertexpp
|
||||
= static_cast<GateVarVertex*>(vu.toGraphVertex());
|
||||
if (lvertexp->dedupable() && consumerVvertexpp->dedupable()) {
|
||||
AstNode* nodep = lvertexp->nodep();
|
||||
AstVarScope* consumerVarScopep = consumerVvertexpp->varScp();
|
||||
AstNode* const nodep = lvertexp->nodep();
|
||||
AstVarScope* const consumerVarScopep = consumerVvertexpp->varScp();
|
||||
// TODO: Doing a simple pointer comparison of activep won't work
|
||||
// optimally for statements under generated clocks. Statements under
|
||||
// different generated clocks will never compare as equal, even if the
|
||||
// generated clocks are deduped into one clock.
|
||||
AstActive* activep = lvertexp->activep();
|
||||
AstActive* const activep = lvertexp->activep();
|
||||
return VNUser(m_varVisitor.findDupe(nodep, consumerVarScopep, activep));
|
||||
}
|
||||
return VNUser(0);
|
||||
|
|
@ -1227,14 +1229,14 @@ void GateVisitor::dedupe() {
|
|||
// Traverse starting from each of the clocks
|
||||
UINFO(9, "Gate dedupe() clocks:\n");
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (GateVarVertex* vvertexp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
if (GateVarVertex* const vvertexp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
if (vvertexp->isClock()) deduper.dedupeTree(vvertexp);
|
||||
}
|
||||
}
|
||||
// Traverse starting from each of the outputs
|
||||
UINFO(9, "Gate dedupe() outputs:\n");
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (GateVarVertex* vvertexp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
if (GateVarVertex* const vvertexp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
if (vvertexp->isTop() && vvertexp->varScp()->varp()->isWritable()) {
|
||||
deduper.dedupeTree(vvertexp);
|
||||
}
|
||||
|
|
@ -1256,15 +1258,15 @@ private:
|
|||
|
||||
// assemble two Sel into one if possible
|
||||
AstSel* merge(AstSel* pre, AstSel* cur) {
|
||||
AstVarRef* preVarRefp = VN_CAST(pre->fromp(), VarRef);
|
||||
AstVarRef* curVarRefp = VN_CAST(cur->fromp(), VarRef);
|
||||
const AstVarRef* const preVarRefp = VN_CAST(pre->fromp(), VarRef);
|
||||
AstVarRef* const curVarRefp = VN_CAST(cur->fromp(), VarRef);
|
||||
if (!preVarRefp || !curVarRefp || !curVarRefp->same(preVarRefp)) {
|
||||
return nullptr; // not the same var
|
||||
}
|
||||
const AstConst* pstart = VN_CAST(pre->lsbp(), Const);
|
||||
const AstConst* pwidth = VN_CAST(pre->widthp(), Const);
|
||||
const AstConst* cstart = VN_CAST(cur->lsbp(), Const);
|
||||
const AstConst* cwidth = VN_CAST(cur->widthp(), Const);
|
||||
const AstConst* const pstart = VN_CAST(pre->lsbp(), Const);
|
||||
const AstConst* const pwidth = VN_CAST(pre->widthp(), Const);
|
||||
const AstConst* const cstart = VN_CAST(cur->lsbp(), Const);
|
||||
const AstConst* const cwidth = VN_CAST(cur->widthp(), Const);
|
||||
if (!pstart || !pwidth || !cstart || !cwidth) return nullptr; // too complicated
|
||||
if (cur->lsbConst() + cur->widthConst() == pre->lsbConst()) {
|
||||
return new AstSel(curVarRefp->fileline(), curVarRefp->cloneTree(false),
|
||||
|
|
@ -1278,8 +1280,9 @@ private:
|
|||
for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep;) {
|
||||
V3GraphEdge* oldedgep = edgep;
|
||||
edgep = edgep->inNextp(); // for recursive since the edge could be deleted
|
||||
if (GateLogicVertex* lvertexp = dynamic_cast<GateLogicVertex*>(oldedgep->fromp())) {
|
||||
if (AstNodeAssign* assignp = VN_CAST(lvertexp->nodep(), NodeAssign)) {
|
||||
if (GateLogicVertex* const lvertexp
|
||||
= dynamic_cast<GateLogicVertex*>(oldedgep->fromp())) {
|
||||
if (AstNodeAssign* const assignp = VN_CAST(lvertexp->nodep(), NodeAssign)) {
|
||||
// if (lvertexp->outSize1() && VN_IS(assignp->lhsp(), Sel)) {
|
||||
if (VN_IS(assignp->lhsp(), Sel) && lvertexp->outSize1()) {
|
||||
UINFO(9, "assing to the nodep[" << VN_AS(assignp->lhsp(), Sel)->lsbConst()
|
||||
|
|
@ -1297,20 +1300,20 @@ private:
|
|||
continue;
|
||||
}
|
||||
|
||||
AstSel* preselp = VN_CAST(m_assignp->lhsp(), Sel);
|
||||
AstSel* curselp = VN_CAST(assignp->lhsp(), Sel);
|
||||
AstSel* const preselp = VN_CAST(m_assignp->lhsp(), Sel);
|
||||
AstSel* const curselp = VN_CAST(assignp->lhsp(), Sel);
|
||||
if (!preselp || !curselp) continue;
|
||||
|
||||
if (AstSel* newselp = merge(preselp, curselp)) {
|
||||
if (AstSel* const newselp = merge(preselp, curselp)) {
|
||||
UINFO(5, "assemble to new sel: " << newselp << endl);
|
||||
// replace preSel with newSel
|
||||
preselp->replaceWith(newselp);
|
||||
VL_DO_DANGLING(preselp->deleteTree(), preselp);
|
||||
// create new rhs for pre assignment
|
||||
AstNode* newrhsp = new AstConcat(m_assignp->rhsp()->fileline(),
|
||||
m_assignp->rhsp()->cloneTree(false),
|
||||
assignp->rhsp()->cloneTree(false));
|
||||
AstNode* oldrhsp = m_assignp->rhsp();
|
||||
AstNode* const newrhsp = new AstConcat(
|
||||
m_assignp->rhsp()->fileline(), m_assignp->rhsp()->cloneTree(false),
|
||||
assignp->rhsp()->cloneTree(false));
|
||||
AstNode* const oldrhsp = m_assignp->rhsp();
|
||||
oldrhsp->replaceWith(newrhsp);
|
||||
VL_DO_DANGLING(oldrhsp->deleteTree(), oldrhsp);
|
||||
m_assignp->dtypeChgWidthSigned(m_assignp->width() + assignp->width(),
|
||||
|
|
@ -1327,7 +1330,7 @@ private:
|
|||
for (V3GraphEdge* ledgep = lvertexp->inBeginp(); ledgep;) {
|
||||
V3GraphEdge* oedgep = ledgep;
|
||||
ledgep = ledgep->inNextp();
|
||||
GateEitherVertex* fromvp
|
||||
GateEitherVertex* const fromvp
|
||||
= dynamic_cast<GateEitherVertex*>(oedgep->fromp());
|
||||
new V3GraphEdge(m_graphp, fromvp, m_logicvp, 1);
|
||||
VL_DO_DANGLING(oedgep->unlinkDelete(), oedgep);
|
||||
|
|
@ -1366,7 +1369,7 @@ void GateVisitor::mergeAssigns() {
|
|||
UINFO(6, "mergeAssigns\n");
|
||||
GateMergeAssignsGraphVisitor merger{&m_graph};
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (GateVarVertex* vvertexp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
if (GateVarVertex* const vvertexp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
merger.mergeAssignsTree(vvertexp);
|
||||
}
|
||||
}
|
||||
|
|
@ -1430,7 +1433,7 @@ public:
|
|||
class GateClkDecompState final {
|
||||
public:
|
||||
int m_offset;
|
||||
AstVarScope* m_last_vsp;
|
||||
AstVarScope* const m_last_vsp;
|
||||
GateClkDecompState(int offset, AstVarScope* vsp)
|
||||
: m_offset{offset}
|
||||
, m_last_vsp{vsp} {}
|
||||
|
|
@ -1450,14 +1453,14 @@ private:
|
|||
|
||||
virtual VNUser visit(GateVarVertex* vvertexp, VNUser vu) override {
|
||||
// Check that we haven't been here before
|
||||
AstVarScope* vsp = vvertexp->varScp();
|
||||
AstVarScope* const vsp = vvertexp->varScp();
|
||||
if (vsp->user2SetOnce()) return VNUser(0);
|
||||
UINFO(9, "CLK DECOMP Var - " << vvertexp << " : " << vsp << endl);
|
||||
if (vsp->varp()->width() > 1) {
|
||||
m_seen_clk_vectors++;
|
||||
m_total_seen_clk_vectors++;
|
||||
}
|
||||
GateClkDecompState* currState = reinterpret_cast<GateClkDecompState*>(vu.c());
|
||||
GateClkDecompState* const currState = reinterpret_cast<GateClkDecompState*>(vu.c());
|
||||
GateClkDecompState nextState(currState->m_offset, vsp);
|
||||
vvertexp->iterateCurrentOutEdges(*this, VNUser(&nextState));
|
||||
if (vsp->varp()->width() > 1) --m_seen_clk_vectors;
|
||||
|
|
@ -1466,13 +1469,13 @@ private:
|
|||
}
|
||||
|
||||
virtual VNUser visit(GateLogicVertex* lvertexp, VNUser vu) override {
|
||||
GateClkDecompState* currState = reinterpret_cast<GateClkDecompState*>(vu.c());
|
||||
GateClkDecompState* const currState = reinterpret_cast<GateClkDecompState*>(vu.c());
|
||||
int clk_offset = currState->m_offset;
|
||||
if (const AstAssignW* assignp = VN_CAST(lvertexp->nodep(), AssignW)) {
|
||||
if (const AstAssignW* const assignp = VN_CAST(lvertexp->nodep(), AssignW)) {
|
||||
UINFO(9, "CLK DECOMP Logic (off = " << clk_offset << ") - " << lvertexp << " : "
|
||||
<< m_clk_vsp << endl);
|
||||
// RHS
|
||||
if (AstSel* rselp = VN_CAST(assignp->rhsp(), Sel)) {
|
||||
if (AstSel* const rselp = VN_CAST(assignp->rhsp(), Sel)) {
|
||||
if (VN_IS(rselp->lsbp(), Const) && VN_IS(rselp->widthp(), Const)) {
|
||||
if (clk_offset < rselp->lsbConst() || clk_offset > rselp->msbConst()) {
|
||||
UINFO(9, "CLK DECOMP Sel [ " << rselp->msbConst() << " : "
|
||||
|
|
@ -1498,7 +1501,7 @@ private:
|
|||
return VNUser(0);
|
||||
}
|
||||
// LHS
|
||||
if (const AstSel* lselp = VN_CAST(assignp->lhsp(), Sel)) {
|
||||
if (const AstSel* const lselp = VN_CAST(assignp->lhsp(), Sel)) {
|
||||
if (VN_IS(lselp->lsbp(), Const) && VN_IS(lselp->widthp(), Const)) {
|
||||
clk_offset += lselp->lsbConst();
|
||||
} else {
|
||||
|
|
@ -1512,7 +1515,7 @@ private:
|
|||
}
|
||||
UINFO(9, "CLK DECOMP Connecting - " << assignp->lhsp() << endl);
|
||||
UINFO(9, " to - " << m_clk_vsp << endl);
|
||||
AstNode* rhsp = assignp->rhsp();
|
||||
AstNode* const rhsp = assignp->rhsp();
|
||||
rhsp->replaceWith(new AstVarRef(rhsp->fileline(), m_clk_vsp, VAccess::READ));
|
||||
while (V3GraphEdge* edgep = lvertexp->inBeginp()) {
|
||||
VL_DO_DANGLING(edgep->unlinkDelete(), edgep);
|
||||
|
|
@ -1552,8 +1555,8 @@ void GateVisitor::decomposeClkVectors() {
|
|||
AstNode::user2ClearTree();
|
||||
GateClkDecompGraphVisitor decomposer{&m_graph};
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (GateVarVertex* vertp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
AstVarScope* vsp = vertp->varScp();
|
||||
if (GateVarVertex* const vertp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
AstVarScope* const vsp = vertp->varScp();
|
||||
if (vsp->varp()->attrClocker() == VVarAttrClocker::CLOCKER_YES) {
|
||||
if (vsp->varp()->width() > 1) {
|
||||
UINFO(9, "Clocker > 1 bit, not decomposing: " << vsp << endl);
|
||||
|
|
@ -1573,9 +1576,9 @@ class GateDeassignVisitor final : public GateBaseVisitor {
|
|||
private:
|
||||
// VISITORS
|
||||
virtual void visit(AstVarScope* nodep) override {
|
||||
if (AstNodeAssign* assp = VN_CAST(nodep->valuep(), NodeAssign)) {
|
||||
if (AstNodeAssign* const assp = VN_CAST(nodep->valuep(), NodeAssign)) {
|
||||
UINFO(5, " Removeassign " << assp << endl);
|
||||
AstNode* valuep = assp->rhsp();
|
||||
AstNode* const valuep = assp->rhsp();
|
||||
valuep->unlinkFrBack();
|
||||
assp->replaceWith(valuep);
|
||||
VL_DO_DANGLING(assp->deleteTree(), assp);
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ private:
|
|||
|
||||
// STATE
|
||||
AstActive* m_activep = nullptr; // Inside activate statement
|
||||
AstNodeModule* m_topModp; // Top module
|
||||
AstNodeModule* const m_topModp; // Top module
|
||||
AstScope* const m_scopetopp = v3Global.rootp()->topScopep()->scopep(); // The top AstScope
|
||||
|
||||
// METHODS
|
||||
|
|
@ -69,18 +69,18 @@ private:
|
|||
// that might have dependents scheduled earlier.
|
||||
UASSERT_OBJ(vscp != v3Global.rootp()->dpiExportTriggerp(), vscp,
|
||||
"DPI export trigger should not need __VinpClk");
|
||||
AstVar* varp = vscp->varp();
|
||||
AstVar* const varp = vscp->varp();
|
||||
string newvarname
|
||||
= "__VinpClk__" + vscp->scopep()->nameDotless() + "__" + varp->name();
|
||||
// Create: VARREF(inpclk)
|
||||
// ...
|
||||
// ASSIGN(VARREF(inpclk), VARREF(var))
|
||||
AstVar* newvarp
|
||||
AstVar* const newvarp
|
||||
= new AstVar(varp->fileline(), AstVarType::MODULETEMP, newvarname, varp);
|
||||
m_topModp->addStmtp(newvarp);
|
||||
AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopetopp, newvarp);
|
||||
AstVarScope* const newvscp = new AstVarScope(vscp->fileline(), m_scopetopp, newvarp);
|
||||
m_scopetopp->addVarp(newvscp);
|
||||
AstAssign* asninitp = new AstAssign(
|
||||
AstAssign* const asninitp = new AstAssign(
|
||||
vscp->fileline(), new AstVarRef(vscp->fileline(), newvscp, VAccess::WRITE),
|
||||
new AstVarRef(vscp->fileline(), vscp, VAccess::READ));
|
||||
m_scopetopp->addFinalClkp(asninitp);
|
||||
|
|
@ -98,15 +98,16 @@ private:
|
|||
//----
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
// Consumption/generation of a variable,
|
||||
AstVarScope* vscp = nodep->varScopep();
|
||||
AstVarScope* const vscp = nodep->varScopep();
|
||||
UASSERT_OBJ(vscp, nodep, "Scope not assigned");
|
||||
if (m_activep && !nodep->user3()) {
|
||||
nodep->user3(true);
|
||||
if (vscp->isCircular()) {
|
||||
UINFO(8, " VarActReplace " << nodep << endl);
|
||||
// Replace with the new variable
|
||||
AstVarScope* newvscp = genInpClk(vscp);
|
||||
AstVarRef* newrefp = new AstVarRef(nodep->fileline(), newvscp, nodep->access());
|
||||
AstVarScope* const newvscp = genInpClk(vscp);
|
||||
AstVarRef* const newrefp
|
||||
= new AstVarRef(nodep->fileline(), newvscp, nodep->access());
|
||||
nodep->replaceWith(newrefp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
|
|
@ -187,7 +188,7 @@ private:
|
|||
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
// Consumption/generation of a variable,
|
||||
AstVarScope* vscp = nodep->varScopep();
|
||||
AstVarScope* const vscp = nodep->varScopep();
|
||||
UASSERT_OBJ(vscp, nodep, "Scope not assigned");
|
||||
if (m_activep) {
|
||||
UINFO(8, " VarAct " << nodep << endl);
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class GraphAcycEdge final : public V3GraphEdge {
|
|||
private:
|
||||
using OrigEdgeList = std::list<V3GraphEdge*>; // List of orig edges, see also GraphAcyc's decl
|
||||
V3GraphEdge* origEdgep() const {
|
||||
OrigEdgeList* oEListp = static_cast<OrigEdgeList*>(userp());
|
||||
const OrigEdgeList* const oEListp = static_cast<OrigEdgeList*>(userp());
|
||||
if (!oEListp) v3fatalSrc("No original edge associated with acyc edge " << this);
|
||||
return (oEListp->front());
|
||||
}
|
||||
|
|
@ -127,8 +127,8 @@ private:
|
|||
}
|
||||
V3GraphEdge* edgeFromEdge(V3GraphEdge* oldedgep, V3GraphVertex* fromp, V3GraphVertex* top) {
|
||||
// Make new breakGraph edge, with old edge as a template
|
||||
GraphAcycEdge* newEdgep = new GraphAcycEdge(&m_breakGraph, fromp, top, oldedgep->weight(),
|
||||
oldedgep->cutable());
|
||||
GraphAcycEdge* const newEdgep = new GraphAcycEdge(&m_breakGraph, fromp, top,
|
||||
oldedgep->weight(), oldedgep->cutable());
|
||||
newEdgep->userp(oldedgep->userp()); // Keep pointer to OrigEdgeList
|
||||
return newEdgep;
|
||||
}
|
||||
|
|
@ -137,12 +137,12 @@ private:
|
|||
// Note addEdge may already have a bunch of similar linked edge representations. Yuk.
|
||||
UASSERT(addEdgep, "Adding nullptr");
|
||||
if (!toEdgep->userp()) {
|
||||
OrigEdgeList* oep = new OrigEdgeList;
|
||||
OrigEdgeList* const oep = new OrigEdgeList;
|
||||
m_origEdgeDelp.push_back(oep);
|
||||
toEdgep->userp(oep);
|
||||
}
|
||||
OrigEdgeList* oEListp = static_cast<OrigEdgeList*>(toEdgep->userp());
|
||||
if (OrigEdgeList* addListp = static_cast<OrigEdgeList*>(addEdgep->userp())) {
|
||||
OrigEdgeList* const oEListp = static_cast<OrigEdgeList*>(toEdgep->userp());
|
||||
if (OrigEdgeList* const addListp = static_cast<OrigEdgeList*>(addEdgep->userp())) {
|
||||
for (const auto& itr : *addListp) oEListp->push_back(itr);
|
||||
addListp->clear(); // Done with it
|
||||
} else {
|
||||
|
|
@ -153,7 +153,7 @@ private:
|
|||
// From the break edge, cut edges in original graph it represents
|
||||
UINFO(8, why << " CUT " << breakEdgep->fromp() << endl);
|
||||
breakEdgep->cut();
|
||||
OrigEdgeList* oEListp = static_cast<OrigEdgeList*>(breakEdgep->userp());
|
||||
const OrigEdgeList* const oEListp = static_cast<OrigEdgeList*>(breakEdgep->userp());
|
||||
if (!oEListp) {
|
||||
v3fatalSrc("No original edge associated with cutting edge " << breakEdgep);
|
||||
}
|
||||
|
|
@ -166,7 +166,7 @@ private:
|
|||
}
|
||||
// Work Queue
|
||||
void workPush(V3GraphVertex* vertexp) {
|
||||
GraphAcycVertex* avertexp = static_cast<GraphAcycVertex*>(vertexp);
|
||||
GraphAcycVertex* const avertexp = static_cast<GraphAcycVertex*>(vertexp);
|
||||
// Add vertex to list of nodes needing further optimization trials
|
||||
if (!avertexp->m_onWorkList) {
|
||||
avertexp->m_onWorkList = true;
|
||||
|
|
@ -175,7 +175,7 @@ private:
|
|||
}
|
||||
GraphAcycVertex* workBeginp() { return m_work.begin(); }
|
||||
void workPop() {
|
||||
GraphAcycVertex* avertexp = workBeginp();
|
||||
GraphAcycVertex* const avertexp = workBeginp();
|
||||
avertexp->m_onWorkList = false;
|
||||
avertexp->m_work.unlink(m_work, avertexp);
|
||||
}
|
||||
|
|
@ -204,7 +204,7 @@ void GraphAcyc::buildGraph(V3Graph* origGraphp) {
|
|||
for (V3GraphVertex* overtexp = origGraphp->verticesBeginp(); overtexp;
|
||||
overtexp = overtexp->verticesNextp()) {
|
||||
if (overtexp->color()) {
|
||||
GraphAcycVertex* avertexp = new GraphAcycVertex(&m_breakGraph, overtexp);
|
||||
GraphAcycVertex* const avertexp = new GraphAcycVertex(&m_breakGraph, overtexp);
|
||||
overtexp->userp(avertexp); // Stash so can look up later
|
||||
}
|
||||
}
|
||||
|
|
@ -213,7 +213,7 @@ void GraphAcyc::buildGraph(V3Graph* origGraphp) {
|
|||
for (V3GraphVertex* overtexp = origGraphp->verticesBeginp(); overtexp;
|
||||
overtexp = overtexp->verticesNextp()) {
|
||||
if (overtexp->color()) {
|
||||
GraphAcycVertex* avertexp = static_cast<GraphAcycVertex*>(overtexp->userp());
|
||||
GraphAcycVertex* const avertexp = static_cast<GraphAcycVertex*>(overtexp->userp());
|
||||
buildGraphIterate(overtexp, avertexp);
|
||||
}
|
||||
}
|
||||
|
|
@ -225,7 +225,8 @@ void GraphAcyc::buildGraphIterate(V3GraphVertex* overtexp, GraphAcycVertex* aver
|
|||
if (origFollowEdge(edgep)) { // not cut
|
||||
V3GraphVertex* toVertexp = edgep->top();
|
||||
if (toVertexp->color()) {
|
||||
GraphAcycVertex* toAVertexp = static_cast<GraphAcycVertex*>(toVertexp->userp());
|
||||
GraphAcycVertex* const toAVertexp
|
||||
= static_cast<GraphAcycVertex*>(toVertexp->userp());
|
||||
// Replicate the old edge into the new graph
|
||||
// There may be multiple edges between same pairs of vertices
|
||||
V3GraphEdge* breakEdgep = new GraphAcycEdge(&m_breakGraph, avertexp, toAVertexp,
|
||||
|
|
@ -266,7 +267,7 @@ void GraphAcyc::deleteMarked() {
|
|||
for (V3GraphVertex *nextp, *vertexp = m_breakGraph.verticesBeginp(); vertexp;
|
||||
vertexp = nextp) {
|
||||
nextp = vertexp->verticesNextp();
|
||||
GraphAcycVertex* avertexp = static_cast<GraphAcycVertex*>(vertexp);
|
||||
GraphAcycVertex* const avertexp = static_cast<GraphAcycVertex*>(vertexp);
|
||||
if (avertexp->isDelete()) {
|
||||
VL_DO_DANGLING(avertexp->unlinkDelete(&m_breakGraph), avertexp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ DfaVertex* DfaGraph::findStart() {
|
|||
DfaVertex* startp = nullptr;
|
||||
for (V3GraphVertex* vertexp = this->verticesBeginp(); vertexp;
|
||||
vertexp = vertexp->verticesNextp()) {
|
||||
if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
|
||||
if (DfaVertex* const vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
|
||||
if (vvertexp->start()) {
|
||||
UASSERT_OBJ(!startp, vertexp, "Multiple start points in NFA graph");
|
||||
startp = vvertexp;
|
||||
|
|
@ -84,7 +84,7 @@ private:
|
|||
}
|
||||
|
||||
DfaVertex* newDfaVertex(DfaVertex* nfaTemplatep = nullptr) {
|
||||
DfaVertex* vertexp = new DfaVertex(graphp());
|
||||
DfaVertex* const vertexp = new DfaVertex(graphp());
|
||||
vertexp->color(1); // Mark as dfa
|
||||
if (nfaTemplatep && nfaTemplatep->start()) vertexp->start(true);
|
||||
if (nfaTemplatep && nfaTemplatep->accepting()) vertexp->accepting(true);
|
||||
|
|
@ -95,7 +95,7 @@ private:
|
|||
// Hashing
|
||||
static uint32_t hashVertex(V3GraphVertex* vertexp) {
|
||||
union {
|
||||
void* up;
|
||||
const void* up;
|
||||
struct {
|
||||
uint32_t upper;
|
||||
uint32_t lower;
|
||||
|
|
@ -118,7 +118,7 @@ private:
|
|||
for (V3GraphEdge* dfaEdgep = dfaStatep->outBeginp(); dfaEdgep;
|
||||
dfaEdgep = dfaEdgep->outNextp()) {
|
||||
if (nfaState(dfaEdgep->top())) {
|
||||
DfaVertex* nfaStatep = static_cast<DfaVertex*>(dfaEdgep->top());
|
||||
DfaVertex* const nfaStatep = static_cast<DfaVertex*>(dfaEdgep->top());
|
||||
hash ^= hashVertex(nfaStatep);
|
||||
if (debug()) {
|
||||
UASSERT_OBJ(nfaStatep->user() != m_step, nfaStatep,
|
||||
|
|
@ -178,7 +178,7 @@ private:
|
|||
|
||||
const auto eqrange = m_hashMap.equal_range(hash);
|
||||
for (auto it = eqrange.first; it != eqrange.second; ++it) {
|
||||
DfaVertex* testp = it->second;
|
||||
DfaVertex* const testp = it->second;
|
||||
if (compareDfaOrigins(nfasWithInput, testp)) {
|
||||
UINFO(9, " DFA match for set: " << testp << endl);
|
||||
return testp; // Identical
|
||||
|
|
@ -197,13 +197,13 @@ private:
|
|||
for (V3GraphEdge* dfaEdgep = dfaStatep->outBeginp(); dfaEdgep;
|
||||
dfaEdgep = dfaEdgep->outNextp()) {
|
||||
if (nfaState(dfaEdgep->top())) {
|
||||
DfaVertex* nfaStatep = static_cast<DfaVertex*>(dfaEdgep->top());
|
||||
const DfaVertex* const nfaStatep = static_cast<DfaVertex*>(dfaEdgep->top());
|
||||
// Foreach input transition (on this nfaStatep)
|
||||
for (V3GraphEdge* nfaEdgep = nfaStatep->outBeginp(); nfaEdgep;
|
||||
nfaEdgep = nfaEdgep->outNextp()) {
|
||||
DfaEdge* cNfaEdgep = static_cast<DfaEdge*>(nfaEdgep);
|
||||
const DfaEdge* const cNfaEdgep = static_cast<DfaEdge*>(nfaEdgep);
|
||||
if (cNfaEdgep->input().toNodep() == input.toNodep()) {
|
||||
DfaVertex* nextStatep = static_cast<DfaVertex*>(cNfaEdgep->top());
|
||||
DfaVertex* const nextStatep = static_cast<DfaVertex*>(cNfaEdgep->top());
|
||||
if (unseenNfaThisStep(nextStatep)) { // Not processed?
|
||||
nfasWithInput.push_back(nextStatep);
|
||||
nextStatep->user(m_step);
|
||||
|
|
@ -220,15 +220,15 @@ private:
|
|||
DfaStates nfasTodo = nfasWithInput;
|
||||
nfasWithInput.clear(); // Now the completed list
|
||||
while (!nfasTodo.empty()) {
|
||||
DfaVertex* nfaStatep = nfasTodo.front();
|
||||
DfaVertex* const nfaStatep = nfasTodo.front();
|
||||
nfasTodo.pop_front();
|
||||
nfasWithInput.push_back(nfaStatep);
|
||||
// Foreach epsilon-reachable (on this nfaStatep)
|
||||
for (V3GraphEdge* nfaEdgep = nfaStatep->outBeginp(); nfaEdgep;
|
||||
nfaEdgep = nfaEdgep->outNextp()) {
|
||||
DfaEdge* cNfaEdgep = static_cast<DfaEdge*>(nfaEdgep);
|
||||
const DfaEdge* const cNfaEdgep = static_cast<DfaEdge*>(nfaEdgep);
|
||||
if (cNfaEdgep->epsilon()) {
|
||||
DfaVertex* nextStatep = static_cast<DfaVertex*>(cNfaEdgep->top());
|
||||
DfaVertex* const nextStatep = static_cast<DfaVertex*>(cNfaEdgep->top());
|
||||
if (unseenNfaThisStep(nextStatep)) { // Not processed?
|
||||
nfasTodo.push_back(nextStatep);
|
||||
nextStatep->user(m_step);
|
||||
|
|
@ -250,10 +250,10 @@ private:
|
|||
if (debug() >= 6) m_graphp->dumpDotFilePrefixed("dfa_nfa");
|
||||
|
||||
// Find NFA start
|
||||
DfaVertex* nfaStartp = graphp()->findStart();
|
||||
DfaVertex* const nfaStartp = graphp()->findStart();
|
||||
|
||||
// Create new DFA State (start state) from the NFA states
|
||||
DfaVertex* dfaStartp = newDfaVertex(nfaStartp);
|
||||
DfaVertex* const dfaStartp = newDfaVertex(nfaStartp);
|
||||
|
||||
DfaStates dfaUnprocps; // Unprocessed DFA nodes
|
||||
dfaUnprocps.push_back(dfaStartp);
|
||||
|
|
@ -265,7 +265,7 @@ private:
|
|||
workps.push_back(nfaStartp);
|
||||
|
||||
while (!workps.empty()) { // While work
|
||||
DfaVertex* nfaStatep = workps.back();
|
||||
DfaVertex* const nfaStatep = workps.back();
|
||||
workps.pop_back();
|
||||
// UINFO(9," Processing "<<nfaStatep<<endl);
|
||||
nfaStatep->user(m_step); // Mark as processed
|
||||
|
|
@ -275,8 +275,8 @@ private:
|
|||
// Find epsilon closure of this nfa node, and destinations to work list
|
||||
for (V3GraphEdge* nfaEdgep = nfaStatep->outBeginp(); nfaEdgep;
|
||||
nfaEdgep = nfaEdgep->outNextp()) {
|
||||
DfaEdge* cNfaEdgep = static_cast<DfaEdge*>(nfaEdgep);
|
||||
DfaVertex* ecNfaStatep = static_cast<DfaVertex*>(nfaEdgep->top());
|
||||
const DfaEdge* const cNfaEdgep = static_cast<DfaEdge*>(nfaEdgep);
|
||||
DfaVertex* const ecNfaStatep = static_cast<DfaVertex*>(nfaEdgep->top());
|
||||
// UINFO(9," Consider "<<nfaEdgep->top()<<" EP "<<cNfaEdgep->epsilon()<<endl);
|
||||
if (cNfaEdgep->epsilon() && unseenNfaThisStep(ecNfaStatep)) { // Not processed?
|
||||
workps.push_back(ecNfaStatep);
|
||||
|
|
@ -289,7 +289,7 @@ private:
|
|||
int i = 0;
|
||||
UINFO(5, "Main state conversion...\n");
|
||||
while (!dfaUnprocps.empty()) {
|
||||
DfaVertex* dfaStatep = dfaUnprocps.back();
|
||||
DfaVertex* const dfaStatep = dfaUnprocps.back();
|
||||
dfaUnprocps.pop_back();
|
||||
UINFO(9, " On dfaState " << dfaStatep << endl);
|
||||
|
||||
|
|
@ -299,11 +299,11 @@ private:
|
|||
for (V3GraphEdge* dfaEdgep = dfaStatep->outBeginp(); dfaEdgep;
|
||||
dfaEdgep = dfaEdgep->outNextp()) {
|
||||
if (nfaState(dfaEdgep->top())) {
|
||||
DfaVertex* nfaStatep = static_cast<DfaVertex*>(dfaEdgep->top());
|
||||
const DfaVertex* const nfaStatep = static_cast<DfaVertex*>(dfaEdgep->top());
|
||||
// Foreach input on this nfaStatep
|
||||
for (V3GraphEdge* nfaEdgep = nfaStatep->outBeginp(); nfaEdgep;
|
||||
nfaEdgep = nfaEdgep->outNextp()) {
|
||||
DfaEdge* cNfaEdgep = static_cast<DfaEdge*>(nfaEdgep);
|
||||
const DfaEdge* const cNfaEdgep = static_cast<DfaEdge*>(nfaEdgep);
|
||||
if (!cNfaEdgep->epsilon()) {
|
||||
if (inputs.find(cNfaEdgep->input().toInt()) == inputs.end()) {
|
||||
inputs.insert(cNfaEdgep->input().toInt());
|
||||
|
|
@ -403,7 +403,7 @@ private:
|
|||
// (As once we've accepted, we no longer care about anything else.)
|
||||
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp;
|
||||
vertexp = vertexp->verticesNextp()) {
|
||||
if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
|
||||
if (const DfaVertex* const vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
|
||||
if (vvertexp->accepting()) {
|
||||
for (V3GraphEdge *nextp, *edgep = vertexp->outBeginp(); edgep; edgep = nextp) {
|
||||
nextp = edgep->outNextp();
|
||||
|
|
@ -422,7 +422,7 @@ private:
|
|||
// (Otherwise we might have nodes on the list twice, and reference after deleting them.)
|
||||
m_graphp->userClearVertices();
|
||||
|
||||
DfaVertex* startp = graphp()->findStart();
|
||||
DfaVertex* const startp = graphp()->findStart();
|
||||
std::stack<V3GraphVertex*> workps;
|
||||
workps.push(startp);
|
||||
|
||||
|
|
@ -462,7 +462,7 @@ private:
|
|||
std::stack<DfaVertex*> workps;
|
||||
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp;
|
||||
vertexp = vertexp->verticesNextp()) {
|
||||
if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
|
||||
if (DfaVertex* const vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
|
||||
workps.push(vvertexp);
|
||||
vertexp->user(1);
|
||||
} else {
|
||||
|
|
@ -473,13 +473,13 @@ private:
|
|||
|
||||
// While deadness... Delete and find new dead nodes.
|
||||
while (!workps.empty()) {
|
||||
DfaVertex* vertexp = workps.top();
|
||||
DfaVertex* const vertexp = workps.top();
|
||||
workps.pop();
|
||||
vertexp->user(0);
|
||||
if (isDead(vertexp)) {
|
||||
// Add nodes that go here to the work list
|
||||
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
DfaVertex* fromvertexp = static_cast<DfaVertex*>(edgep->fromp());
|
||||
DfaVertex* const fromvertexp = static_cast<DfaVertex*>(edgep->fromp());
|
||||
if (fromvertexp != vertexp && !fromvertexp->user()) {
|
||||
workps.push(fromvertexp);
|
||||
fromvertexp->user(1);
|
||||
|
|
@ -541,7 +541,7 @@ private:
|
|||
DfaVertex* acceptp = nullptr;
|
||||
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp;
|
||||
vertexp = vertexp->verticesNextp()) {
|
||||
if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
|
||||
if (DfaVertex* const vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
|
||||
if (vvertexp->accepting()) {
|
||||
acceptp = vvertexp;
|
||||
break;
|
||||
|
|
@ -553,15 +553,16 @@ private:
|
|||
// Remap edges
|
||||
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp;
|
||||
vertexp = vertexp->verticesNextp()) {
|
||||
if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
|
||||
if (DfaVertex* const vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
|
||||
// UINFO(9, " on vertex "<<vvertexp->name()<<endl);
|
||||
if (!vvertexp->accepting() && vvertexp != m_tempNewerReject) {
|
||||
for (V3GraphEdge *nextp, *edgep = vertexp->outBeginp(); edgep; edgep = nextp) {
|
||||
nextp = edgep->outNextp();
|
||||
if (!edgep->user()) { // Not processed
|
||||
// Old edges to accept now go to new reject
|
||||
DfaEdge* vedgep = static_cast<DfaEdge*>(edgep);
|
||||
DfaVertex* tovertexp = static_cast<DfaVertex*>(edgep->top());
|
||||
const DfaEdge* const vedgep = static_cast<DfaEdge*>(edgep);
|
||||
const DfaVertex* const tovertexp
|
||||
= static_cast<DfaVertex*>(edgep->top());
|
||||
if (tovertexp->accepting()) {
|
||||
new DfaEdge(graphp(), vvertexp, m_tempNewerReject, vedgep);
|
||||
VL_DO_DANGLING(edgep->unlinkDelete(), edgep);
|
||||
|
|
@ -572,7 +573,8 @@ private:
|
|||
// edge(complemented,a) edge(complemented,b) means !(a | b)
|
||||
if (!tovertexp->accepting()) {
|
||||
// Note we must include edges moved above to reject
|
||||
DfaEdge* newp = new DfaEdge(graphp(), vvertexp, acceptp, vedgep);
|
||||
DfaEdge* const newp
|
||||
= new DfaEdge(graphp(), vvertexp, acceptp, vedgep);
|
||||
newp->complement(!newp->complement());
|
||||
newp->user(1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ GraphPathChecker::GraphPathChecker(const V3Graph* graphp, V3EdgeFuncP edgeFuncp)
|
|||
GraphPathChecker::~GraphPathChecker() {
|
||||
// Free every GraphPCNode
|
||||
for (V3GraphVertex* vxp = m_graphp->verticesBeginp(); vxp; vxp = vxp->verticesNextp()) {
|
||||
GraphPCNode* nodep = static_cast<GraphPCNode*>(vxp->userp());
|
||||
const GraphPCNode* const nodep = static_cast<GraphPCNode*>(vxp->userp());
|
||||
VL_DO_DANGLING(delete nodep, nodep);
|
||||
vxp->userp(nullptr);
|
||||
}
|
||||
|
|
@ -80,11 +80,11 @@ void GraphPathChecker::initHalfCriticalPaths(GraphWay way, bool checkOnly) {
|
|||
if (!m_edgeFuncp(edgep)) continue;
|
||||
|
||||
V3GraphVertex* wrelativep = edgep->furtherp(rev);
|
||||
GraphPCNode* wrelUserp = static_cast<GraphPCNode*>(wrelativep->userp());
|
||||
const GraphPCNode* const wrelUserp = static_cast<GraphPCNode*>(wrelativep->userp());
|
||||
critPathCost = std::max(critPathCost, wrelUserp->m_cp[way] + 1);
|
||||
}
|
||||
|
||||
GraphPCNode* ourUserp = static_cast<GraphPCNode*>(vertexp->userp());
|
||||
GraphPCNode* const ourUserp = static_cast<GraphPCNode*>(vertexp->userp());
|
||||
if (checkOnly) {
|
||||
UASSERT_OBJ(ourUserp->m_cp[way] == critPathCost, vertexp,
|
||||
"Validation of critical paths failed");
|
||||
|
|
@ -96,8 +96,8 @@ void GraphPathChecker::initHalfCriticalPaths(GraphWay way, bool checkOnly) {
|
|||
|
||||
bool GraphPathChecker::pathExistsInternal(const V3GraphVertex* ap, const V3GraphVertex* bp,
|
||||
unsigned* costp) {
|
||||
GraphPCNode* auserp = static_cast<GraphPCNode*>(ap->userp());
|
||||
GraphPCNode* buserp = static_cast<GraphPCNode*>(bp->userp());
|
||||
GraphPCNode* const auserp = static_cast<GraphPCNode*>(ap->userp());
|
||||
const GraphPCNode* const buserp = static_cast<GraphPCNode*>(bp->userp());
|
||||
|
||||
// If have already searched this node on the current search, don't
|
||||
// recurse through it again. Since we're still searching, we must not
|
||||
|
|
|
|||
|
|
@ -277,17 +277,17 @@ class V3GraphTestDfa final : public V3GraphTest {
|
|||
public:
|
||||
virtual string name() override { return "dfa"; }
|
||||
virtual void runTest() override {
|
||||
DfaGraph* gp = &m_graph;
|
||||
DfaGraph* const gp = &m_graph;
|
||||
|
||||
// NFA Pattern for ( (LR) | (L*R)) Z
|
||||
DfaTestVertex* st = new DfaTestVertex(gp, "*START*");
|
||||
DfaTestVertex* const st = new DfaTestVertex(gp, "*START*");
|
||||
st->start(true);
|
||||
DfaTestVertex* sl = new DfaTestVertex(gp, "sL");
|
||||
DfaTestVertex* srs = new DfaTestVertex(gp, "sR*");
|
||||
DfaTestVertex* sls = new DfaTestVertex(gp, "sL*");
|
||||
DfaTestVertex* sr = new DfaTestVertex(gp, "sR");
|
||||
DfaTestVertex* sz = new DfaTestVertex(gp, "sZ");
|
||||
DfaTestVertex* sac = new DfaTestVertex(gp, "*ACCEPT*");
|
||||
DfaTestVertex* const sl = new DfaTestVertex(gp, "sL");
|
||||
DfaTestVertex* const srs = new DfaTestVertex(gp, "sR*");
|
||||
DfaTestVertex* const sls = new DfaTestVertex(gp, "sL*");
|
||||
DfaTestVertex* const sr = new DfaTestVertex(gp, "sR");
|
||||
DfaTestVertex* const sz = new DfaTestVertex(gp, "sZ");
|
||||
DfaTestVertex* const sac = new DfaTestVertex(gp, "*ACCEPT*");
|
||||
sac->accepting(true);
|
||||
|
||||
VNUser L = VNUser::fromInt(0xaa);
|
||||
|
|
@ -332,7 +332,7 @@ class V3GraphTestImport final : public V3GraphTest {
|
|||
public:
|
||||
virtual string name() override { return "import"; }
|
||||
virtual void runTest() override {
|
||||
DfaGraph* gp = &m_graph;
|
||||
DfaGraph* const gp = &m_graph;
|
||||
if (V3GraphTest::debug()) DfaGraph::debug(9);
|
||||
dotImport();
|
||||
dump();
|
||||
|
|
|
|||
|
|
@ -353,7 +353,7 @@ private:
|
|||
virtual void visit(AstInitArray* nodep) override {
|
||||
// Hash unpacked array initializers by value, as the order of initializer nodes does not
|
||||
// matter, and we want semantically equivalent initializers to map to the same hash.
|
||||
AstUnpackArrayDType* const dtypep = VN_CAST(nodep->dtypep(), UnpackArrayDType);
|
||||
const AstUnpackArrayDType* const dtypep = VN_CAST(nodep->dtypep(), UnpackArrayDType);
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, /* hashChildren: */ !dtypep, [=]() {
|
||||
if (dtypep) {
|
||||
const uint32_t size = dtypep->elementsConst();
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ static void V3HierWriteCommonInputs(const V3HierBlock* hblockp, std::ostream* of
|
|||
V3HierBlock::StrGParams V3HierBlock::stringifyParams(const GParams& gparams, bool forGOption) {
|
||||
StrGParams strParams;
|
||||
for (const auto& gparam : gparams) {
|
||||
if (const AstConst* constp = VN_CAST(gparam->valuep(), Const)) {
|
||||
if (const AstConst* const constp = VN_CAST(gparam->valuep(), Const)) {
|
||||
string s;
|
||||
// Only constant parameter needs to be set to -G because already checked in
|
||||
// V3Param.cpp. See also ParamVisitor::checkSupportedParam() in the file.
|
||||
|
|
|
|||
|
|
@ -177,14 +177,14 @@ private:
|
|||
// Iterate through all modules in bottom-up order.
|
||||
// Make a final inlining decision for each.
|
||||
for (auto it = m_allMods.rbegin(); it != m_allMods.rend(); ++it) {
|
||||
AstNodeModule* modp = *it;
|
||||
AstNodeModule* const modp = *it;
|
||||
|
||||
// If we're going to inline some modules into this one,
|
||||
// update user4 (statement count) to reflect that:
|
||||
int statements = modp->user4();
|
||||
LocalInstanceMap& localsr = m_instances[modp];
|
||||
for (LocalInstanceMap::iterator iti = localsr.begin(); iti != localsr.end(); ++iti) {
|
||||
AstNodeModule* childp = iti->first;
|
||||
const AstNodeModule* const childp = iti->first;
|
||||
if (childp->user1()) { // inlining child
|
||||
statements += (childp->user4() * iti->second);
|
||||
}
|
||||
|
|
@ -270,8 +270,8 @@ private:
|
|||
|
||||
// STATE
|
||||
std::unordered_set<std::string> m_renamedInterfaces; // Name of renamed interface variables
|
||||
AstNodeModule* m_modp; // Current module
|
||||
AstCell* m_cellp; // Cell being cloned
|
||||
AstNodeModule* const m_modp; // Current module
|
||||
AstCell* const m_cellp; // Cell being cloned
|
||||
|
||||
// METHODS
|
||||
VL_DEBUG_FUNC; // Declare debug()
|
||||
|
|
@ -307,8 +307,8 @@ private:
|
|||
if (nodep->user2p()) {
|
||||
// Make an assignment, so we'll trace it properly
|
||||
// user2p is either a const or a var.
|
||||
AstConst* exprconstp = VN_CAST(nodep->user2p(), Const);
|
||||
AstVarRef* exprvarrefp = VN_CAST(nodep->user2p(), VarRef);
|
||||
AstConst* const exprconstp = VN_CAST(nodep->user2p(), Const);
|
||||
const AstVarRef* const exprvarrefp = VN_CAST(nodep->user2p(), VarRef);
|
||||
UINFO(8, "connectto: " << nodep->user2p() << endl);
|
||||
UASSERT_OBJ(exprconstp || exprvarrefp, nodep,
|
||||
"Unknown interconnect type; pinReconnectSimple should have cleared up");
|
||||
|
|
@ -339,7 +339,7 @@ private:
|
|||
m_modp->addStmtp(new AstAssignVarScope(
|
||||
nodep->fileline(), new AstVarRef(nodep->fileline(), nodep, VAccess::WRITE),
|
||||
new AstVarRef(nodep->fileline(), exprvarrefp->varp(), VAccess::READ)));
|
||||
AstNode* nodebp = exprvarrefp->varp();
|
||||
const AstNode* const nodebp = exprvarrefp->varp();
|
||||
nodep->fileline()->modifyStateInherit(nodebp->fileline());
|
||||
nodebp->fileline()->modifyStateInherit(nodep->fileline());
|
||||
} else {
|
||||
|
|
@ -348,23 +348,23 @@ private:
|
|||
m_modp->addStmtp(new AstAssignAlias(
|
||||
nodep->fileline(), new AstVarRef(nodep->fileline(), nodep, VAccess::WRITE),
|
||||
new AstVarRef(nodep->fileline(), exprvarrefp->varp(), VAccess::READ)));
|
||||
AstNode* nodebp = exprvarrefp->varp();
|
||||
const AstNode* const nodebp = exprvarrefp->varp();
|
||||
nodep->fileline()->modifyStateInherit(nodebp->fileline());
|
||||
nodebp->fileline()->modifyStateInherit(nodep->fileline());
|
||||
}
|
||||
}
|
||||
// Iterate won't hit AstIfaceRefDType directly as it is no longer underneath the module
|
||||
if (AstIfaceRefDType* ifacerefp = VN_CAST(nodep->dtypep(), IfaceRefDType)) {
|
||||
if (AstIfaceRefDType* const ifacerefp = VN_CAST(nodep->dtypep(), IfaceRefDType)) {
|
||||
m_renamedInterfaces.insert(nodep->name());
|
||||
// Each inlined cell that contain an interface variable need to
|
||||
// copy the IfaceRefDType and point it to the newly cloned
|
||||
// interface cell.
|
||||
AstIfaceRefDType* newdp = ifacerefp->cloneTree(false);
|
||||
AstIfaceRefDType* const newdp = ifacerefp->cloneTree(false);
|
||||
nodep->dtypep(newdp);
|
||||
ifacerefp->addNextHere(newdp);
|
||||
// Relink to point to newly cloned cell
|
||||
if (newdp->cellp()) {
|
||||
if (AstCell* newcellp = VN_CAST(newdp->cellp()->user4p(), Cell)) {
|
||||
if (AstCell* const newcellp = VN_CAST(newdp->cellp()->user4p(), Cell)) {
|
||||
newdp->cellp(newcellp);
|
||||
newdp->cellName(newcellp->name());
|
||||
// Tag the old ifacerefp to ensure it leaves no stale
|
||||
|
|
@ -398,8 +398,8 @@ private:
|
|||
&& !nodep->varp()->user3()
|
||||
// Don't constant propagate aliases (we just made)
|
||||
&& !VN_IS(nodep->backp(), AssignAlias)) {
|
||||
AstConst* exprconstp = VN_CAST(nodep->varp()->user2p(), Const);
|
||||
AstVarRef* exprvarrefp = VN_CAST(nodep->varp()->user2p(), VarRef);
|
||||
AstConst* const exprconstp = VN_CAST(nodep->varp()->user2p(), Const);
|
||||
const AstVarRef* const exprvarrefp = VN_CAST(nodep->varp()->user2p(), VarRef);
|
||||
if (exprconstp) {
|
||||
nodep->replaceWith(exprconstp->cloneTree(true));
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
|
|
@ -543,14 +543,14 @@ private:
|
|||
// Clone original module
|
||||
if (debug() >= 9) nodep->dumpTree(cout, "inlcell:");
|
||||
// if (debug() >= 9) nodep->modp()->dumpTree(cout, "oldmod:");
|
||||
AstNodeModule* newmodp = nodep->modp()->cloneTree(false);
|
||||
AstNodeModule* const newmodp = nodep->modp()->cloneTree(false);
|
||||
if (debug() >= 9) newmodp->dumpTree(cout, "newmod:");
|
||||
// Clear var markings and find cell cross references
|
||||
AstNode::user2ClearTree();
|
||||
AstNode::user4ClearTree();
|
||||
{ InlineCollectVisitor{nodep->modp()}; } // {} to destroy visitor immediately
|
||||
// Create data for dotted variable resolution
|
||||
AstCellInline* inlinep
|
||||
AstCellInline* const inlinep
|
||||
= new AstCellInline(nodep->fileline(), nodep->name(), nodep->modp()->origName(),
|
||||
nodep->modp()->timeunit());
|
||||
m_modp->addInlinesp(inlinep); // Must be parsed before any AstCells
|
||||
|
|
@ -561,11 +561,11 @@ private:
|
|||
// Make new signal; even though we'll optimize the interconnect, we
|
||||
// need an alias to trace correctly. If tracing is disabled, we'll
|
||||
// delete it in later optimizations.
|
||||
AstVar* pinOldVarp = pinp->modVarp();
|
||||
AstVar* pinNewVarp = pinOldVarp->clonep();
|
||||
AstVar* const pinOldVarp = pinp->modVarp();
|
||||
AstVar* const pinNewVarp = pinOldVarp->clonep();
|
||||
UASSERT_OBJ(pinNewVarp, pinOldVarp, "Cloning failed");
|
||||
|
||||
AstNode* connectRefp = pinp->exprp();
|
||||
AstNode* const connectRefp = pinp->exprp();
|
||||
UASSERT_OBJ(
|
||||
VN_IS(connectRefp, Const) || VN_IS(connectRefp, VarRef), pinp,
|
||||
"Unknown interconnect type; pinReconnectSimple should have cleared up");
|
||||
|
|
@ -594,7 +594,7 @@ private:
|
|||
{ InlineRelinkVisitor{newmodp, m_modp, nodep}; }
|
||||
// Move statements to top module
|
||||
if (debug() >= 9) newmodp->dumpTree(cout, "fixmod:");
|
||||
AstNode* stmtsp = newmodp->stmtsp();
|
||||
AstNode* const stmtsp = newmodp->stmtsp();
|
||||
if (stmtsp) stmtsp->unlinkFrBackWithNext();
|
||||
if (stmtsp) m_modp->addStmtp(stmtsp);
|
||||
// Remove the cell
|
||||
|
|
@ -646,14 +646,14 @@ private:
|
|||
m_scope += "__DOT__" + nodep->name();
|
||||
}
|
||||
|
||||
if (AstModule* modp = VN_CAST(nodep->modp(), Module)) {
|
||||
if (AstModule* const modp = VN_CAST(nodep->modp(), Module)) {
|
||||
// Pass Cell pointers down to the next module
|
||||
for (AstPin* pinp = nodep->pinsp(); pinp; pinp = VN_AS(pinp->nextp(), Pin)) {
|
||||
AstVar* varp = pinp->modVarp();
|
||||
AstVarRef* varrefp = VN_CAST(pinp->exprp(), VarRef);
|
||||
AstVar* const varp = pinp->modVarp();
|
||||
const AstVarRef* const varrefp = VN_CAST(pinp->exprp(), VarRef);
|
||||
if (!varrefp) continue;
|
||||
AstVar* fromVarp = varrefp->varp();
|
||||
AstIfaceRefDType* irdtp = VN_CAST(fromVarp->dtypep(), IfaceRefDType);
|
||||
const AstVar* const fromVarp = varrefp->varp();
|
||||
const AstIfaceRefDType* const irdtp = VN_CAST(fromVarp->dtypep(), IfaceRefDType);
|
||||
if (!irdtp) continue;
|
||||
|
||||
AstCell* cellp;
|
||||
|
|
@ -672,18 +672,18 @@ private:
|
|||
}
|
||||
virtual void visit(AstAssignVarScope* nodep) override {
|
||||
// Reference
|
||||
AstVarRef* reflp = VN_CAST(nodep->lhsp(), VarRef);
|
||||
const AstVarRef* const reflp = VN_CAST(nodep->lhsp(), VarRef);
|
||||
// What the reference refers to
|
||||
AstVarRef* refrp = VN_CAST(nodep->rhsp(), VarRef);
|
||||
const AstVarRef* const refrp = VN_CAST(nodep->rhsp(), VarRef);
|
||||
if (!(reflp && refrp)) return;
|
||||
|
||||
AstVar* varlp = reflp->varp();
|
||||
AstVar* varrp = refrp->varp();
|
||||
const AstVar* const varlp = reflp->varp();
|
||||
const AstVar* const varrp = refrp->varp();
|
||||
if (!(varlp && varrp)) return;
|
||||
|
||||
AstCell* cellp = VN_CAST(varrp->user1p(), Cell);
|
||||
if (!cellp) {
|
||||
AstIfaceRefDType* irdtp = VN_CAST(varrp->dtypep(), IfaceRefDType);
|
||||
const AstIfaceRefDType* const irdtp = VN_CAST(varrp->dtypep(), IfaceRefDType);
|
||||
if (!irdtp) return;
|
||||
|
||||
cellp = irdtp->cellp();
|
||||
|
|
|
|||
|
|
@ -70,23 +70,24 @@ private:
|
|||
// Use user1p on the PIN to indicate we created an assign for this pin
|
||||
if (!nodep->user1SetOnce()) {
|
||||
// Make an ASSIGNW (expr, pin)
|
||||
AstNode* exprp = nodep->exprp()->cloneTree(false);
|
||||
AstNode* const exprp = nodep->exprp()->cloneTree(false);
|
||||
UASSERT_OBJ(exprp->width() == nodep->modVarp()->width(), nodep,
|
||||
"Width mismatch, should have been handled in pinReconnectSimple");
|
||||
if (nodep->modVarp()->isInoutish()) {
|
||||
nodep->v3fatalSrc("Unsupported: Verilator is a 2-state simulator");
|
||||
} else if (nodep->modVarp()->isWritable()) {
|
||||
AstNode* rhsp = new AstVarXRef(exprp->fileline(), nodep->modVarp(),
|
||||
m_cellp->name(), VAccess::READ);
|
||||
AstAssignW* assp = new AstAssignW(exprp->fileline(), exprp, rhsp);
|
||||
AstNode* const rhsp = new AstVarXRef(exprp->fileline(), nodep->modVarp(),
|
||||
m_cellp->name(), VAccess::READ);
|
||||
AstAssignW* const assp = new AstAssignW(exprp->fileline(), exprp, rhsp);
|
||||
m_cellp->addNextHere(assp);
|
||||
} else if (nodep->modVarp()->isNonOutput()) {
|
||||
// Don't bother moving constants now,
|
||||
// we'll be pushing the const down to the cell soon enough.
|
||||
AstNode* assp = new AstAssignW(exprp->fileline(),
|
||||
new AstVarXRef(exprp->fileline(), nodep->modVarp(),
|
||||
m_cellp->name(), VAccess::WRITE),
|
||||
exprp);
|
||||
AstNode* const assp
|
||||
= new AstAssignW(exprp->fileline(),
|
||||
new AstVarXRef(exprp->fileline(), nodep->modVarp(),
|
||||
m_cellp->name(), VAccess::WRITE),
|
||||
exprp);
|
||||
m_cellp->addNextHere(assp);
|
||||
if (debug() >= 9) assp->dumpTree(cout, " _new: ");
|
||||
} else if (nodep->modVarp()->isIfaceRef()
|
||||
|
|
@ -96,13 +97,14 @@ private:
|
|||
IfaceRefDType))) {
|
||||
// Create an AstAssignVarScope for Vars to Cells so we can
|
||||
// link with their scope later
|
||||
AstNode* lhsp = new AstVarXRef(exprp->fileline(), nodep->modVarp(),
|
||||
m_cellp->name(), VAccess::READ);
|
||||
const AstVarRef* refp = VN_CAST(exprp, VarRef);
|
||||
const AstVarXRef* xrefp = VN_CAST(exprp, VarXRef);
|
||||
AstNode* const lhsp = new AstVarXRef(exprp->fileline(), nodep->modVarp(),
|
||||
m_cellp->name(), VAccess::READ);
|
||||
const AstVarRef* const refp = VN_CAST(exprp, VarRef);
|
||||
const AstVarXRef* const xrefp = VN_CAST(exprp, VarXRef);
|
||||
UASSERT_OBJ(refp || xrefp, exprp,
|
||||
"Interfaces: Pin is not connected to a VarRef or VarXRef");
|
||||
AstAssignVarScope* assp = new AstAssignVarScope(exprp->fileline(), lhsp, exprp);
|
||||
AstAssignVarScope* const assp
|
||||
= new AstAssignVarScope(exprp->fileline(), lhsp, exprp);
|
||||
m_cellp->addNextHere(assp);
|
||||
} else {
|
||||
nodep->v3error("Assigned pin is neither input nor output");
|
||||
|
|
@ -204,18 +206,18 @@ private:
|
|||
if (VN_IS(nodep->dtypep(), UnpackArrayDType)
|
||||
&& VN_IS(VN_AS(nodep->dtypep(), UnpackArrayDType)->subDTypep(), IfaceRefDType)) {
|
||||
UINFO(8, " dv-vec-VAR " << nodep << endl);
|
||||
AstUnpackArrayDType* arrdtype = VN_AS(nodep->dtypep(), UnpackArrayDType);
|
||||
AstUnpackArrayDType* const arrdtype = VN_AS(nodep->dtypep(), UnpackArrayDType);
|
||||
AstNode* prevp = nullptr;
|
||||
for (int i = arrdtype->lo(); i <= arrdtype->hi(); ++i) {
|
||||
const string varNewName = nodep->name() + "__BRA__" + cvtToStr(i) + "__KET__";
|
||||
UINFO(8, "VAR name insert " << varNewName << " " << nodep << endl);
|
||||
if (!m_deModVars.find(varNewName)) {
|
||||
AstIfaceRefDType* ifaceRefp
|
||||
AstIfaceRefDType* const ifaceRefp
|
||||
= VN_AS(arrdtype->subDTypep(), IfaceRefDType)->cloneTree(false);
|
||||
arrdtype->addNextHere(ifaceRefp);
|
||||
ifaceRefp->cellp(nullptr);
|
||||
|
||||
AstVar* varNewp = nodep->cloneTree(false);
|
||||
AstVar* const varNewp = nodep->cloneTree(false);
|
||||
varNewp->name(varNewName);
|
||||
varNewp->origName(varNewp->origName() + "__BRA__" + cvtToStr(i) + "__KET__");
|
||||
varNewp->dtypep(ifaceRefp);
|
||||
|
|
@ -245,7 +247,7 @@ private:
|
|||
if (nodep->rangep()) {
|
||||
m_cellRangep = nodep->rangep();
|
||||
|
||||
AstVar* ifaceVarp = VN_CAST(nodep->nextp(), Var);
|
||||
AstVar* const ifaceVarp = VN_CAST(nodep->nextp(), Var);
|
||||
const bool isIface
|
||||
= ifaceVarp && VN_IS(ifaceVarp->dtypep(), UnpackArrayDType)
|
||||
&& VN_IS(VN_AS(ifaceVarp->dtypep(), UnpackArrayDType)->subDTypep(),
|
||||
|
|
@ -257,7 +259,7 @@ private:
|
|||
= m_cellRangep->littleEndian() ? (m_cellRangep->elementsConst() - 1 - i) : i;
|
||||
const int instNum = m_cellRangep->loConst() + i;
|
||||
|
||||
AstCell* newp = nodep->cloneTree(false);
|
||||
AstCell* const newp = nodep->cloneTree(false);
|
||||
nodep->addNextHere(newp);
|
||||
// Remove ranging and fix name
|
||||
newp->rangep()->unlinkFrBack()->deleteTree();
|
||||
|
|
@ -271,11 +273,13 @@ private:
|
|||
// If this AstCell is actually an interface instantiation, also clone the IfaceRef
|
||||
// within the same parent module as the cell
|
||||
if (isIface) {
|
||||
AstUnpackArrayDType* arrdtype = VN_AS(ifaceVarp->dtypep(), UnpackArrayDType);
|
||||
AstIfaceRefDType* origIfaceRefp = VN_AS(arrdtype->subDTypep(), IfaceRefDType);
|
||||
AstUnpackArrayDType* const arrdtype
|
||||
= VN_AS(ifaceVarp->dtypep(), UnpackArrayDType);
|
||||
AstIfaceRefDType* const origIfaceRefp
|
||||
= VN_AS(arrdtype->subDTypep(), IfaceRefDType);
|
||||
origIfaceRefp->cellp(nullptr);
|
||||
AstVar* varNewp = ifaceVarp->cloneTree(false);
|
||||
AstIfaceRefDType* ifaceRefp = origIfaceRefp->cloneTree(false);
|
||||
AstVar* const varNewp = ifaceVarp->cloneTree(false);
|
||||
AstIfaceRefDType* const ifaceRefp = origIfaceRefp->cloneTree(false);
|
||||
arrdtype->addNextHere(ifaceRefp);
|
||||
ifaceRefp->cellp(newp);
|
||||
ifaceRefp->cellName(newp->name());
|
||||
|
|
@ -327,7 +331,8 @@ private:
|
|||
<< pinDim.second << endl);
|
||||
if (expDim.first == pinDim.first && expDim.second == pinDim.second + 1) {
|
||||
// Connection to array, where array dimensions match the instant dimension
|
||||
AstRange* rangep = VN_AS(nodep->exprp()->dtypep(), UnpackArrayDType)->rangep();
|
||||
AstRange* const rangep
|
||||
= VN_AS(nodep->exprp()->dtypep(), UnpackArrayDType)->rangep();
|
||||
const int arraySelNum = rangep->littleEndian()
|
||||
? (rangep->elementsConst() - 1 - m_instSelNum)
|
||||
: m_instSelNum;
|
||||
|
|
@ -362,11 +367,12 @@ private:
|
|||
}
|
||||
} // end expanding ranged cell
|
||||
else if (AstArraySel* arrselp = VN_CAST(nodep->exprp(), ArraySel)) {
|
||||
if (AstUnpackArrayDType* arrp = VN_CAST(arrselp->lhsp()->dtypep(), UnpackArrayDType)) {
|
||||
if (AstUnpackArrayDType* const arrp
|
||||
= VN_CAST(arrselp->lhsp()->dtypep(), UnpackArrayDType)) {
|
||||
if (!VN_IS(arrp->subDTypep(), IfaceRefDType)) return;
|
||||
// Interface pin attaches to one element of arrayed interface
|
||||
V3Const::constifyParamsEdit(arrselp->rhsp());
|
||||
const AstConst* constp = VN_CAST(arrselp->rhsp(), Const);
|
||||
const AstConst* const constp = VN_CAST(arrselp->rhsp(), Const);
|
||||
if (!constp) {
|
||||
nodep->v3warn(
|
||||
E_UNSUPPORTED,
|
||||
|
|
@ -376,19 +382,19 @@ private:
|
|||
const string index = AstNode::encodeNumber(constp->toSInt());
|
||||
if (VN_IS(arrselp->lhsp(), SliceSel))
|
||||
arrselp->lhsp()->v3error("Unsupported: interface slices");
|
||||
AstVarRef* varrefp = VN_CAST(arrselp->lhsp(), VarRef);
|
||||
AstVarRef* const varrefp = VN_CAST(arrselp->lhsp(), VarRef);
|
||||
UASSERT_OBJ(varrefp, arrselp, "No interface varref under array");
|
||||
AstVarXRef* newp = new AstVarXRef(nodep->fileline(),
|
||||
varrefp->name() + "__BRA__" + index + "__KET__",
|
||||
"", VAccess::WRITE);
|
||||
AstVarXRef* const newp = new AstVarXRef(
|
||||
nodep->fileline(), varrefp->name() + "__BRA__" + index + "__KET__", "",
|
||||
VAccess::WRITE);
|
||||
newp->dtypep(nodep->modVarp()->dtypep());
|
||||
newp->classOrPackagep(varrefp->classOrPackagep());
|
||||
arrselp->addNextHere(newp);
|
||||
VL_DO_DANGLING(arrselp->unlinkFrBack()->deleteTree(), arrselp);
|
||||
}
|
||||
} else {
|
||||
AstVar* pinVarp = nodep->modVarp();
|
||||
AstUnpackArrayDType* pinArrp = VN_CAST(pinVarp->dtypep(), UnpackArrayDType);
|
||||
AstVar* const pinVarp = nodep->modVarp();
|
||||
AstUnpackArrayDType* const pinArrp = VN_CAST(pinVarp->dtypep(), UnpackArrayDType);
|
||||
if (!pinArrp || !VN_IS(pinArrp->subDTypep(), IfaceRefDType)) return;
|
||||
// Arrayed pin/var attaches to arrayed submodule lower port/var, expand it
|
||||
AstNode* prevp = nullptr;
|
||||
|
|
@ -404,7 +410,7 @@ private:
|
|||
if (!pinVarp->backp()) {
|
||||
varNewp = m_deModVars.find(varNewName);
|
||||
} else {
|
||||
AstIfaceRefDType* ifaceRefp = VN_AS(pinArrp->subDTypep(), IfaceRefDType);
|
||||
AstIfaceRefDType* const ifaceRefp = VN_AS(pinArrp->subDTypep(), IfaceRefDType);
|
||||
ifaceRefp->cellp(nullptr);
|
||||
varNewp = pinVarp->cloneTree(false);
|
||||
varNewp->name(varNewName);
|
||||
|
|
@ -425,18 +431,18 @@ private:
|
|||
|
||||
// But clone the pin for each module instance
|
||||
// Now also clone the pin itself and update its varref
|
||||
AstPin* newp = nodep->cloneTree(false);
|
||||
AstPin* const newp = nodep->cloneTree(false);
|
||||
newp->modVarp(varNewp);
|
||||
newp->name(newp->name() + "__BRA__" + cvtToStr(i) + "__KET__");
|
||||
// And replace exprp with a new varxref
|
||||
const AstVarRef* varrefp = VN_CAST(newp->exprp(), VarRef); // Maybe null
|
||||
int expr_i = i;
|
||||
if (AstSliceSel* slicep = VN_CAST(newp->exprp(), SliceSel)) {
|
||||
if (AstSliceSel* const slicep = VN_CAST(newp->exprp(), SliceSel)) {
|
||||
varrefp = VN_AS(slicep->fromp(), VarRef);
|
||||
UASSERT(VN_IS(slicep->rhsp(), Const), "Slices should be constant");
|
||||
int slice_index
|
||||
= slicep->declRange().left() + in * slicep->declRange().leftToRightInc();
|
||||
auto* exprArrp = VN_AS(varrefp->dtypep(), UnpackArrayDType);
|
||||
auto* const exprArrp = VN_AS(varrefp->dtypep(), UnpackArrayDType);
|
||||
UASSERT_OBJ(exprArrp, slicep, "Slice of non-array");
|
||||
expr_i = slice_index + exprArrp->lo();
|
||||
} else if (!varrefp) {
|
||||
|
|
@ -446,7 +452,7 @@ private:
|
|||
}
|
||||
|
||||
const string newname = varrefp->name() + "__BRA__" + cvtToStr(expr_i) + "__KET__";
|
||||
AstVarXRef* newVarXRefp
|
||||
AstVarXRef* const newVarXRefp
|
||||
= new AstVarXRef(nodep->fileline(), newname, "", VAccess::WRITE);
|
||||
newVarXRefp->varp(newp->modVarp());
|
||||
newp->exprp()->unlinkFrBack()->deleteTree();
|
||||
|
|
@ -506,7 +512,7 @@ public:
|
|||
// Else create a intermediate wire to perform the interconnect
|
||||
// Return the new assignment, if one was made
|
||||
// Note this module calles cloneTree() via new AstVar
|
||||
AstVar* pinVarp = pinp->modVarp();
|
||||
AstVar* const pinVarp = pinp->modVarp();
|
||||
if (!pinp->exprp()) {
|
||||
// No-connect, perhaps promote based on `unconnected_drive,
|
||||
// otherwise done
|
||||
|
|
@ -520,9 +526,9 @@ public:
|
|||
return nullptr;
|
||||
}
|
||||
}
|
||||
AstVarRef* connectRefp = VN_CAST(pinp->exprp(), VarRef);
|
||||
AstVarXRef* connectXRefp = VN_CAST(pinp->exprp(), VarXRef);
|
||||
AstBasicDType* pinBasicp = VN_CAST(pinVarp->dtypep(), BasicDType); // Maybe nullptr
|
||||
AstVarRef* const connectRefp = VN_CAST(pinp->exprp(), VarRef);
|
||||
AstVarXRef* const connectXRefp = VN_CAST(pinp->exprp(), VarXRef);
|
||||
AstBasicDType* const pinBasicp = VN_CAST(pinVarp->dtypep(), BasicDType); // Maybe nullptr
|
||||
AstBasicDType* connBasicp = nullptr;
|
||||
AstAssignW* assignp = nullptr;
|
||||
if (connectRefp) connBasicp = VN_CAST(connectRefp->varp()->dtypep(), BasicDType);
|
||||
|
|
@ -547,12 +553,12 @@ public:
|
|||
// Make a new temp wire
|
||||
// if (1 || debug() >= 9) pinp->dumpTree(cout, "-in_pin:");
|
||||
V3Inst::checkOutputShort(pinp);
|
||||
AstNode* pinexprp = pinp->exprp()->unlinkFrBack();
|
||||
AstNode* const pinexprp = pinp->exprp()->unlinkFrBack();
|
||||
string newvarname
|
||||
= (string(pinVarp->isWritable() ? "__Vcellout" : "__Vcellinp")
|
||||
// Prevent name conflict if both tri & non-tri add signals
|
||||
+ (forTristate ? "t" : "") + "__" + cellp->name() + "__" + pinp->name());
|
||||
AstVar* newvarp
|
||||
AstVar* const newvarp
|
||||
= new AstVar(pinVarp->fileline(), AstVarType::MODULETEMP, newvarname, pinVarp);
|
||||
// Important to add statement next to cell, in case there is a
|
||||
// generate with same named cell
|
||||
|
|
@ -567,7 +573,7 @@ public:
|
|||
<< pinexprp->width() << endl);
|
||||
rhsp = extendOrSel(pinp->fileline(), rhsp, pinVarp);
|
||||
pinp->exprp(new AstVarRef(newvarp->fileline(), newvarp, VAccess::WRITE));
|
||||
AstNode* rhsSelp = extendOrSel(pinp->fileline(), rhsp, pinexprp);
|
||||
AstNode* const rhsSelp = extendOrSel(pinp->fileline(), rhsp, pinexprp);
|
||||
assignp = new AstAssignW(pinp->fileline(), pinexprp, rhsSelp);
|
||||
} else {
|
||||
// V3 width should have range/extended to make the widths correct
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ private:
|
|||
|
||||
// MEMBERS
|
||||
uint32_t m_instrCount = 0; // Running count of instructions
|
||||
const AstNode* m_startNodep; // Start node of count
|
||||
const AstNode* const m_startNodep; // Start node of count
|
||||
bool m_tracingCall = false; // Iterating into a CCall to a CFunc
|
||||
bool m_inCFunc = false; // Inside AstCFunc
|
||||
bool m_assertNoDups; // Check for duplicates
|
||||
|
|
@ -50,8 +50,8 @@ private:
|
|||
private:
|
||||
// MEMBERS
|
||||
uint32_t m_savedCount;
|
||||
AstNode* m_nodep;
|
||||
InstrCountVisitor* m_visitor;
|
||||
AstNode* const m_nodep;
|
||||
InstrCountVisitor* const m_visitor;
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
|
|||
|
|
@ -138,13 +138,13 @@ public:
|
|||
~LifeBlock() = default;
|
||||
// METHODS
|
||||
void checkRemoveAssign(const LifeMap::iterator& it) {
|
||||
AstVar* varp = it->first->varp();
|
||||
LifeVarEntry* entp = &(it->second);
|
||||
const AstVar* const varp = it->first->varp();
|
||||
LifeVarEntry* const entp = &(it->second);
|
||||
if (!varp->isSigPublic()) {
|
||||
// Rather than track what sigs AstUCFunc/AstUCStmt may change,
|
||||
// we just don't optimize any public sigs
|
||||
// Check the var entry, and remove if appropriate
|
||||
if (AstNode* oldassp = entp->assignp()) {
|
||||
if (AstNode* const oldassp = entp->assignp()) {
|
||||
UINFO(7, " PREV: " << oldassp << endl);
|
||||
// Redundant assignment, in same level block
|
||||
// Don't delete it now as it will confuse iteration since it maybe WAY
|
||||
|
|
@ -182,7 +182,7 @@ public:
|
|||
// Variable rvalue. If it references a constant, we can simply replace it
|
||||
const auto it = m_map.find(nodep);
|
||||
if (it != m_map.end()) {
|
||||
if (AstConst* constp = it->second.constNodep()) {
|
||||
if (AstConst* const constp = it->second.constNodep()) {
|
||||
if (!varrefp->varp()->isSigPublic()) {
|
||||
// Aha, variable is constant; substitute in.
|
||||
// We'll later constant propagate
|
||||
|
|
@ -220,7 +220,7 @@ public:
|
|||
// Any varrefs under a if/else branch affect statements outside and after the if/else
|
||||
if (!m_aboveLifep) v3fatalSrc("Pushing life when already at the top level");
|
||||
for (LifeMap::iterator it = m_map.begin(); it != m_map.end(); ++it) {
|
||||
AstVarScope* nodep = it->first;
|
||||
AstVarScope* const nodep = it->first;
|
||||
m_aboveLifep->complexAssignFind(nodep);
|
||||
if (it->second.everSet()) {
|
||||
// Record there may be an assignment, so we don't constant propagate across the if.
|
||||
|
|
@ -242,7 +242,7 @@ public:
|
|||
}
|
||||
for (LifeMap::iterator it = life2p->m_map.begin(); it != life2p->m_map.end(); ++it) {
|
||||
// When the else branch sets a var before it's used
|
||||
AstVarScope* nodep = it->first;
|
||||
AstVarScope* const nodep = it->first;
|
||||
if (it->second.setBeforeUse() && nodep->user1()) {
|
||||
// Both branches set the var, we can remove the assignment before the IF.
|
||||
UINFO(4, "DUALBRANCH " << nodep << endl);
|
||||
|
|
@ -291,7 +291,7 @@ private:
|
|||
// it's used so can't elim assignment before this use.
|
||||
UASSERT_OBJ(nodep->varScopep(), nodep, "nullptr");
|
||||
//
|
||||
AstVarScope* vscp = nodep->varScopep();
|
||||
AstVarScope* const vscp = nodep->varScopep();
|
||||
UASSERT_OBJ(vscp, nodep, "Scope not assigned");
|
||||
if (nodep->access().isWriteOrRW()) {
|
||||
m_sideEffect = true; // $sscanf etc may have RHS vars that are lvalues
|
||||
|
|
@ -313,7 +313,7 @@ private:
|
|||
}
|
||||
// Has to be direct assignment without any EXTRACTing.
|
||||
if (VN_IS(nodep->lhsp(), VarRef) && !m_sideEffect && !m_noopt) {
|
||||
AstVarScope* vscp = VN_AS(nodep->lhsp(), VarRef)->varScopep();
|
||||
AstVarScope* const vscp = VN_AS(nodep->lhsp(), VarRef)->varScopep();
|
||||
UASSERT_OBJ(vscp, nodep, "Scope lost on variable");
|
||||
m_lifep->simpleAssign(vscp, nodep);
|
||||
} else {
|
||||
|
|
@ -330,9 +330,9 @@ private:
|
|||
UINFO(4, " IF " << nodep << endl);
|
||||
// Condition is part of PREVIOUS block
|
||||
iterateAndNextNull(nodep->condp());
|
||||
LifeBlock* prevLifep = m_lifep;
|
||||
LifeBlock* ifLifep = new LifeBlock(prevLifep, m_statep);
|
||||
LifeBlock* elseLifep = new LifeBlock(prevLifep, m_statep);
|
||||
LifeBlock* const prevLifep = m_lifep;
|
||||
LifeBlock* const ifLifep = new LifeBlock(prevLifep, m_statep);
|
||||
LifeBlock* const elseLifep = new LifeBlock(prevLifep, m_statep);
|
||||
{
|
||||
m_lifep = ifLifep;
|
||||
iterateAndNextNull(nodep->ifsp());
|
||||
|
|
@ -360,9 +360,9 @@ private:
|
|||
// would because it only appears used after-the-fact. So, we model
|
||||
// it as a IF statement, and just don't allow elimination of
|
||||
// variables across the body.
|
||||
LifeBlock* prevLifep = m_lifep;
|
||||
LifeBlock* condLifep = new LifeBlock(prevLifep, m_statep);
|
||||
LifeBlock* bodyLifep = new LifeBlock(prevLifep, m_statep);
|
||||
LifeBlock* const prevLifep = m_lifep;
|
||||
LifeBlock* const condLifep = new LifeBlock(prevLifep, m_statep);
|
||||
LifeBlock* const bodyLifep = new LifeBlock(prevLifep, m_statep);
|
||||
{
|
||||
m_lifep = condLifep;
|
||||
iterateAndNextNull(nodep->precondsp());
|
||||
|
|
@ -385,8 +385,8 @@ private:
|
|||
// As with While's we can't predict if a JumpGo will kill us or not
|
||||
// It's worse though as an IF(..., JUMPGO) may change the control flow.
|
||||
// Just don't optimize blocks with labels; they're rare - so far.
|
||||
LifeBlock* prevLifep = m_lifep;
|
||||
LifeBlock* bodyLifep = new LifeBlock(prevLifep, m_statep);
|
||||
LifeBlock* const prevLifep = m_lifep;
|
||||
LifeBlock* const bodyLifep = new LifeBlock(prevLifep, m_statep);
|
||||
const bool prev_noopt = m_noopt;
|
||||
{
|
||||
m_lifep = bodyLifep;
|
||||
|
|
@ -455,7 +455,7 @@ class LifeTopVisitor final : public AstNVisitor {
|
|||
// finding code within.
|
||||
private:
|
||||
// STATE
|
||||
LifeState* m_statep; // Current state
|
||||
LifeState* const m_statep; // Current state
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
|
|
|
|||
|
|
@ -54,11 +54,11 @@ private:
|
|||
|
||||
// VISITORS
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
AstVarScope* vscp = nodep->varScopep();
|
||||
const AstVarScope* const vscp = nodep->varScopep();
|
||||
UASSERT_OBJ(vscp, nodep, "Scope not assigned");
|
||||
if (AstVarScope* newvscp = reinterpret_cast<AstVarScope*>(vscp->user4p())) {
|
||||
if (AstVarScope* const newvscp = reinterpret_cast<AstVarScope*>(vscp->user4p())) {
|
||||
UINFO(9, " Replace " << nodep << " to " << newvscp << endl);
|
||||
AstVarRef* newrefp = new AstVarRef(nodep->fileline(), newvscp, nodep->access());
|
||||
AstVarRef* const newrefp = new AstVarRef(nodep->fileline(), newvscp, nodep->access());
|
||||
nodep->replaceWith(newrefp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
|
|
@ -186,11 +186,11 @@ private:
|
|||
}
|
||||
void squashAssignposts() {
|
||||
for (auto& itr : m_assignposts) {
|
||||
LifePostLocation* app = &itr.second;
|
||||
AstVarRef* lhsp = VN_AS(app->nodep->lhsp(), VarRef); // original var
|
||||
AstVarRef* rhsp = VN_AS(app->nodep->rhsp(), VarRef); // dly var
|
||||
AstVarScope* dlyVarp = rhsp->varScopep();
|
||||
AstVarScope* origVarp = lhsp->varScopep();
|
||||
LifePostLocation* const app = &itr.second;
|
||||
AstVarRef* const lhsp = VN_AS(app->nodep->lhsp(), VarRef); // original var
|
||||
AstVarRef* const rhsp = VN_AS(app->nodep->rhsp(), VarRef); // dly var
|
||||
AstVarScope* const dlyVarp = rhsp->varScopep();
|
||||
AstVarScope* const origVarp = lhsp->varScopep();
|
||||
|
||||
// Scrunch these:
|
||||
// X1: __Vdly__q = __PVT__clk_clocks;
|
||||
|
|
@ -275,7 +275,7 @@ private:
|
|||
}
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
// Consumption/generation of a variable,
|
||||
AstVarScope* vscp = nodep->varScopep();
|
||||
AstVarScope* const vscp = nodep->varScopep();
|
||||
UASSERT_OBJ(vscp, nodep, "Scope not assigned");
|
||||
|
||||
LifeLocation loc(m_execMTaskp, ++m_sequence);
|
||||
|
|
@ -292,9 +292,9 @@ private:
|
|||
virtual void visit(AstAssignPost* nodep) override {
|
||||
// Don't record ASSIGNPOST in the read/write maps, record them in a
|
||||
// separate map
|
||||
if (AstVarRef* rhsp = VN_CAST(nodep->rhsp(), VarRef)) {
|
||||
if (AstVarRef* const rhsp = VN_CAST(nodep->rhsp(), VarRef)) {
|
||||
// rhsp is the dly var
|
||||
AstVarScope* dlyVarp = rhsp->varScopep();
|
||||
AstVarScope* const dlyVarp = rhsp->varScopep();
|
||||
UASSERT_OBJ(m_assignposts.find(dlyVarp) == m_assignposts.end(), nodep,
|
||||
"LifePostLocation attempted duplicate dlyvar map addition");
|
||||
LifeLocation loc(m_execMTaskp, ++m_sequence);
|
||||
|
|
@ -318,7 +318,7 @@ private:
|
|||
m_mtasksGraphp = nodep->depGraphp();
|
||||
for (V3GraphVertex* mtaskVxp = m_mtasksGraphp->verticesBeginp(); mtaskVxp;
|
||||
mtaskVxp = mtaskVxp->verticesNextp()) {
|
||||
ExecMTask* mtaskp = dynamic_cast<ExecMTask*>(mtaskVxp);
|
||||
ExecMTask* const mtaskp = dynamic_cast<ExecMTask*>(mtaskVxp);
|
||||
m_execMTaskp = mtaskp;
|
||||
m_sequence = 0;
|
||||
iterate(mtaskp->bodyp());
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ public:
|
|||
};
|
||||
|
||||
class LinkCellsVertex final : public V3GraphVertex {
|
||||
AstNodeModule* m_modp;
|
||||
AstNodeModule* const m_modp;
|
||||
|
||||
public:
|
||||
LinkCellsVertex(V3Graph* graphp, AstNodeModule* modp)
|
||||
|
|
@ -74,7 +74,7 @@ public:
|
|||
};
|
||||
|
||||
void LinkCellsGraph::loopsMessageCb(V3GraphVertex* vertexp) {
|
||||
if (LinkCellsVertex* vvertexp = dynamic_cast<LinkCellsVertex*>(vertexp)) {
|
||||
if (const LinkCellsVertex* const vvertexp = dynamic_cast<LinkCellsVertex*>(vertexp)) {
|
||||
vvertexp->modp()->v3warn(E_UNSUPPORTED,
|
||||
"Unsupported: Recursive multiple modules (module instantiates "
|
||||
"something leading back to itself): "
|
||||
|
|
@ -127,7 +127,7 @@ private:
|
|||
}
|
||||
|
||||
AstNodeModule* findModuleSym(const string& modName) {
|
||||
VSymEnt* foundp = m_mods.rootp()->findIdFallback(modName);
|
||||
const VSymEnt* const foundp = m_mods.rootp()->findIdFallback(modName);
|
||||
if (!foundp) {
|
||||
return nullptr;
|
||||
} else {
|
||||
|
|
@ -169,9 +169,9 @@ private:
|
|||
m_graph.dumpDotFilePrefixed("linkcells");
|
||||
m_graph.rank();
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (LinkCellsVertex* vvertexp = dynamic_cast<LinkCellsVertex*>(itp)) {
|
||||
if (const LinkCellsVertex* const vvertexp = dynamic_cast<LinkCellsVertex*>(itp)) {
|
||||
// +1 so we leave level 1 for the new wrapper we'll make in a moment
|
||||
AstNodeModule* modp = vvertexp->modp();
|
||||
AstNodeModule* const modp = vvertexp->modp();
|
||||
modp->level(vvertexp->rank() + 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -228,7 +228,7 @@ private:
|
|||
UINFO(4, "Link IfaceRef: " << nodep << endl);
|
||||
// Use findIdUpward instead of findIdFlat; it doesn't matter for now
|
||||
// but we might support modules-under-modules someday.
|
||||
AstNodeModule* modp = resolveModule(nodep, nodep->ifaceName());
|
||||
AstNodeModule* const modp = resolveModule(nodep, nodep->ifaceName());
|
||||
if (modp) {
|
||||
if (VN_IS(modp, Iface)) {
|
||||
// Track module depths, so can sort list from parent down to children
|
||||
|
|
@ -256,9 +256,9 @@ private:
|
|||
// this move to post param, which would mean we do not auto-read modules
|
||||
// and means we cannot compute module levels until later.
|
||||
UINFO(4, "Link Bind: " << nodep << endl);
|
||||
AstNodeModule* modp = resolveModule(nodep, nodep->name());
|
||||
AstNodeModule* const modp = resolveModule(nodep, nodep->name());
|
||||
if (modp) {
|
||||
AstNode* cellsp = nodep->cellsp()->unlinkFrBackWithNext();
|
||||
AstNode* const cellsp = nodep->cellsp()->unlinkFrBackWithNext();
|
||||
// Module may have already linked, so need to pick up these new cells
|
||||
VL_RESTORER(m_modp);
|
||||
{
|
||||
|
|
@ -388,13 +388,13 @@ private:
|
|||
// and it's easier to do it now than in V3LinkDot when we'd need to repeat steps.
|
||||
for (AstNode* portnodep = nodep->modp()->stmtsp(); portnodep;
|
||||
portnodep = portnodep->nextp()) {
|
||||
if (const AstPort* portp = VN_CAST(portnodep, Port)) {
|
||||
if (const AstPort* const portp = VN_CAST(portnodep, Port)) {
|
||||
if (ports.find(portp->name()) == ports.end()
|
||||
&& ports.find("__pinNumber" + cvtToStr(portp->pinNum())) == ports.end()) {
|
||||
if (pinStar) {
|
||||
UINFO(9, " need .* PORT " << portp << endl);
|
||||
// Create any not already connected
|
||||
AstPin* newp = new AstPin(
|
||||
AstPin* const newp = new AstPin(
|
||||
nodep->fileline(), 0, portp->name(),
|
||||
new AstParseRef(nodep->fileline(), VParseRefExp::PX_TEXT,
|
||||
portp->name(), nullptr, nullptr));
|
||||
|
|
@ -403,7 +403,7 @@ private:
|
|||
} else { // warn on the CELL that needs it, not the port
|
||||
nodep->v3warn(PINMISSING,
|
||||
"Cell has missing pin: " << portp->prettyNameQ());
|
||||
AstPin* newp
|
||||
AstPin* const newp
|
||||
= new AstPin(nodep->fileline(), 0, portp->name(), nullptr);
|
||||
nodep->addPinsp(newp);
|
||||
}
|
||||
|
|
@ -421,14 +421,14 @@ private:
|
|||
if (!nodep->hasIfaceVar()) {
|
||||
const string varName
|
||||
= nodep->name() + "__Viftop"; // V3LinkDot looks for this naming
|
||||
AstIfaceRefDType* idtypep = new AstIfaceRefDType(nodep->fileline(), nodep->name(),
|
||||
nodep->modp()->name());
|
||||
AstIfaceRefDType* const idtypep = new AstIfaceRefDType(
|
||||
nodep->fileline(), nodep->name(), nodep->modp()->name());
|
||||
idtypep->ifacep(nullptr); // cellp overrides
|
||||
// In the case of arrayed interfaces, we replace cellp when de-arraying in V3Inst
|
||||
idtypep->cellp(nodep); // Only set when real parent cell known.
|
||||
AstVar* varp;
|
||||
if (nodep->rangep()) {
|
||||
AstNodeArrayDType* arrp
|
||||
AstNodeArrayDType* const arrp
|
||||
= new AstUnpackArrayDType(nodep->fileline(), VFlagChildDType(), idtypep,
|
||||
nodep->rangep()->cloneTree(true));
|
||||
varp = new AstVar(nodep->fileline(), AstVarType::IFACEREF, varName,
|
||||
|
|
@ -474,7 +474,7 @@ private:
|
|||
nodep->name(hierIt->first); // Change name of this module to be mangled name
|
||||
// considering parameter
|
||||
}
|
||||
AstNodeModule* foundp = findModuleSym(nodep->name());
|
||||
AstNodeModule* const foundp = findModuleSym(nodep->name());
|
||||
if (foundp && foundp != nodep) {
|
||||
if (!(foundp->fileline()->warnIsOff(V3ErrorCode::MODDUP)
|
||||
|| nodep->fileline()->warnIsOff(V3ErrorCode::MODDUP)
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ public:
|
|||
class LinkNodeMatcherVarIO final : public VNodeMatcher {
|
||||
public:
|
||||
virtual bool nodeMatch(const AstNode* nodep) const override {
|
||||
const AstVar* varp = VN_CAST(nodep, Var);
|
||||
const AstVar* const varp = VN_CAST(nodep, Var);
|
||||
if (!varp) return false;
|
||||
return varp->isIO();
|
||||
}
|
||||
|
|
@ -107,7 +107,7 @@ public:
|
|||
class LinkNodeMatcherVarParam final : public VNodeMatcher {
|
||||
public:
|
||||
virtual bool nodeMatch(const AstNode* nodep) const override {
|
||||
const AstVar* varp = VN_CAST(nodep, Var);
|
||||
const AstVar* const varp = VN_CAST(nodep, Var);
|
||||
if (!varp) return false;
|
||||
return varp->isParam();
|
||||
}
|
||||
|
|
@ -249,8 +249,8 @@ public:
|
|||
//
|
||||
// Note we only check for conflicts at the same level; it's ok if one block hides another
|
||||
// We also wouldn't want to not insert it even though it's lower down
|
||||
VSymEnt* foundp = lookupSymp->findIdFlat(name);
|
||||
AstNode* fnodep = foundp ? foundp->nodep() : nullptr;
|
||||
VSymEnt* const foundp = lookupSymp->findIdFlat(name);
|
||||
AstNode* const fnodep = foundp ? foundp->nodep() : nullptr;
|
||||
if (!fnodep) {
|
||||
// Not found, will add in a moment.
|
||||
} else if (nodep == fnodep) { // Already inserted.
|
||||
|
|
@ -284,7 +284,7 @@ public:
|
|||
}
|
||||
void insertDUnit(AstNetlist* nodep) {
|
||||
// $unit on top scope
|
||||
VSymEnt* symp = new VSymEnt(&m_syms, nodep);
|
||||
VSymEnt* const symp = new VSymEnt(&m_syms, nodep);
|
||||
UINFO(9, " INSERTdunit se" << cvtToHex(symp) << endl);
|
||||
symp->parentp(rootEntp()); // Needed so backward search can find name of top module
|
||||
symp->fallbackp(nullptr);
|
||||
|
|
@ -295,7 +295,7 @@ public:
|
|||
}
|
||||
VSymEnt* insertTopCell(AstNodeModule* nodep, const string& scopename) {
|
||||
// Only called on the module at the very top of the hierarchy
|
||||
VSymEnt* symp = new VSymEnt(&m_syms, nodep);
|
||||
VSymEnt* const symp = new VSymEnt(&m_syms, nodep);
|
||||
UINFO(9,
|
||||
" INSERTtop se" << cvtToHex(symp) << " " << scopename << " " << nodep << endl);
|
||||
symp->parentp(rootEntp()); // Needed so backward search can find name of top module
|
||||
|
|
@ -309,7 +309,7 @@ public:
|
|||
VSymEnt* insertCell(VSymEnt* abovep, VSymEnt* modSymp, AstCell* nodep,
|
||||
const string& scopename) {
|
||||
UASSERT_OBJ(abovep, nodep, "Null symbol table inserting node");
|
||||
VSymEnt* symp = new VSymEnt(&m_syms, nodep);
|
||||
VSymEnt* const symp = new VSymEnt(&m_syms, nodep);
|
||||
UINFO(9, " INSERTcel se" << cvtToHex(symp) << " " << scopename << " above=se"
|
||||
<< cvtToHex(abovep) << " mods=se" << cvtToHex(modSymp)
|
||||
<< " node=" << nodep << endl);
|
||||
|
|
@ -337,7 +337,7 @@ public:
|
|||
// A fake point in the hierarchy, corresponding to an inlined module
|
||||
// This references to another Sym, and eventually resolves to a module with a prefix
|
||||
UASSERT_OBJ(abovep, nodep, "Null symbol table inserting node");
|
||||
VSymEnt* symp = new VSymEnt(&m_syms, nodep);
|
||||
VSymEnt* const symp = new VSymEnt(&m_syms, nodep);
|
||||
UINFO(9, " INSERTinl se" << cvtToHex(symp) << " " << basename << " above=se"
|
||||
<< cvtToHex(abovep) << " mods=se" << cvtToHex(modSymp)
|
||||
<< " node=" << nodep << endl);
|
||||
|
|
@ -360,7 +360,7 @@ public:
|
|||
// Note we fallback to the symbol table of the parent, as we want to find variables there
|
||||
// However, cells walk the graph, so cells will appear under the begin/ftask itself
|
||||
UASSERT_OBJ(abovep, nodep, "Null symbol table inserting node");
|
||||
VSymEnt* symp = new VSymEnt(&m_syms, nodep);
|
||||
VSymEnt* const symp = new VSymEnt(&m_syms, nodep);
|
||||
UINFO(9, " INSERTblk se" << cvtToHex(symp) << " above=se" << cvtToHex(abovep)
|
||||
<< " pkg=" << cvtToHex(classOrPackagep) << " node=" << nodep
|
||||
<< endl);
|
||||
|
|
@ -376,7 +376,7 @@ public:
|
|||
VSymEnt* insertSym(VSymEnt* abovep, const string& name, AstNode* nodep,
|
||||
AstNodeModule* classOrPackagep) {
|
||||
UASSERT_OBJ(abovep, nodep, "Null symbol table inserting node");
|
||||
VSymEnt* symp = new VSymEnt(&m_syms, nodep);
|
||||
VSymEnt* const symp = new VSymEnt(&m_syms, nodep);
|
||||
UINFO(9, " INSERTsym se" << cvtToHex(symp) << " name='" << name << "' above=se"
|
||||
<< cvtToHex(abovep) << " pkg=" << cvtToHex(classOrPackagep)
|
||||
<< " node=" << nodep << endl);
|
||||
|
|
@ -394,7 +394,7 @@ public:
|
|||
static VSymEnt* getNodeSym(AstNode* nodep) {
|
||||
// Don't use this in ResolveVisitor, as we need to pick up the proper
|
||||
// reference under each SCOPE
|
||||
VSymEnt* symp = nodep->user1u().toSymEnt();
|
||||
VSymEnt* const symp = nodep->user1u().toSymEnt();
|
||||
UASSERT_OBJ(symp, nodep, "Module/etc never assigned a symbol entry?");
|
||||
return symp;
|
||||
}
|
||||
|
|
@ -431,7 +431,7 @@ public:
|
|||
static AstIfaceRefDType* ifaceRefFromArray(AstNodeDType* nodep) {
|
||||
AstIfaceRefDType* ifacerefp = VN_CAST(nodep, IfaceRefDType);
|
||||
if (!ifacerefp) {
|
||||
if (AstBracketArrayDType* arrp = VN_CAST(nodep, BracketArrayDType)) {
|
||||
if (AstBracketArrayDType* const arrp = VN_CAST(nodep, BracketArrayDType)) {
|
||||
ifacerefp = VN_CAST(arrp->subDTypep(), IfaceRefDType);
|
||||
} else if (AstUnpackArrayDType* arrp = VN_CAST(nodep, UnpackArrayDType)) {
|
||||
ifacerefp = VN_CAST(arrp->subDTypep(), IfaceRefDType);
|
||||
|
|
@ -441,9 +441,9 @@ public:
|
|||
}
|
||||
void computeIfaceVarSyms() {
|
||||
for (VSymEnt* varSymp : m_ifaceVarSyms) {
|
||||
AstVar* varp = varSymp ? VN_AS(varSymp->nodep(), Var) : nullptr;
|
||||
AstVar* const varp = varSymp ? VN_AS(varSymp->nodep(), Var) : nullptr;
|
||||
UINFO(9, " insAllIface se" << cvtToHex(varSymp) << " " << varp << endl);
|
||||
AstIfaceRefDType* ifacerefp = ifaceRefFromArray(varp->subDTypep());
|
||||
AstIfaceRefDType* const ifacerefp = ifaceRefFromArray(varp->subDTypep());
|
||||
UASSERT_OBJ(ifacerefp, varp, "Non-ifacerefs on list!");
|
||||
if (!ifacerefp->ifaceViaCellp()) {
|
||||
if (!ifacerefp->cellp()) { // Probably a NotFoundModule, or a normal module if
|
||||
|
|
@ -461,14 +461,14 @@ public:
|
|||
<< AstNode::prettyNameQ(ifacerefp->ifaceName()));
|
||||
continue;
|
||||
}
|
||||
VSymEnt* ifaceSymp = getNodeSym(ifacerefp->ifaceViaCellp());
|
||||
VSymEnt* const ifaceSymp = getNodeSym(ifacerefp->ifaceViaCellp());
|
||||
VSymEnt* ifOrPortSymp = ifaceSymp;
|
||||
// Link Modport names to the Modport Node under the Interface
|
||||
if (ifacerefp->isModport()) {
|
||||
VSymEnt* foundp = ifaceSymp->findIdFallback(ifacerefp->modportName());
|
||||
VSymEnt* const foundp = ifaceSymp->findIdFallback(ifacerefp->modportName());
|
||||
bool ok = false;
|
||||
if (foundp) {
|
||||
if (AstModport* modportp = VN_CAST(foundp->nodep(), Modport)) {
|
||||
if (AstModport* const modportp = VN_CAST(foundp->nodep(), Modport)) {
|
||||
UINFO(4, "Link Modport: " << modportp << endl);
|
||||
ifacerefp->modportp(modportp);
|
||||
ifOrPortSymp = foundp;
|
||||
|
|
@ -506,7 +506,7 @@ public:
|
|||
for (int samn = 0; samn < SAMN__MAX; ++samn) {
|
||||
for (ScopeAliasMap::iterator it = m_scopeAliasMap[samn].begin();
|
||||
it != m_scopeAliasMap[samn].end(); ++it) {
|
||||
VSymEnt* lhsp = it->first;
|
||||
VSymEnt* const lhsp = it->first;
|
||||
VSymEnt* srcp = lhsp;
|
||||
while (true) { // Follow chain of aliases up to highest level non-alias
|
||||
const auto it2 = m_scopeAliasMap[samn].find(srcp);
|
||||
|
|
@ -582,7 +582,7 @@ public:
|
|||
: nullptr; // Replicated below
|
||||
AstCellInline* inlinep = lookupSymp ? VN_CAST(lookupSymp->nodep(), CellInline)
|
||||
: nullptr; // Replicated below
|
||||
if (VSymEnt* findSymp = findWithAltFallback(lookupSymp, ident, altIdent)) {
|
||||
if (VSymEnt* const findSymp = findWithAltFallback(lookupSymp, ident, altIdent)) {
|
||||
lookupSymp = findSymp;
|
||||
}
|
||||
// Check this module - cur modname
|
||||
|
|
@ -629,15 +629,15 @@ public:
|
|||
if (!lookupSymp) return nullptr; // Not found
|
||||
}
|
||||
} else { // Searching for middle submodule, must be a cell name
|
||||
if (VSymEnt* findSymp = findWithAltFallback(lookupSymp, ident, altIdent)) {
|
||||
if (VSymEnt* const findSymp = findWithAltFallback(lookupSymp, ident, altIdent)) {
|
||||
lookupSymp = findSymp;
|
||||
} else {
|
||||
return nullptr; // Not found
|
||||
}
|
||||
}
|
||||
if (lookupSymp) {
|
||||
if (AstCell* cellp = VN_CAST(lookupSymp->nodep(), Cell)) {
|
||||
if (AstNodeModule* modp = cellp->modp()) {
|
||||
if (AstCell* const cellp = VN_CAST(lookupSymp->nodep(), Cell)) {
|
||||
if (AstNodeModule* const modp = cellp->modp()) {
|
||||
if (modp->hierBlock()) {
|
||||
refLocationp->v3error("Cannot access inside hierarchical block");
|
||||
} else if (VN_IS(modp, NotFoundModule)) {
|
||||
|
|
@ -708,7 +708,7 @@ LinkDotState* LinkDotState::s_errorThisp = nullptr;
|
|||
|
||||
class LinkDotFindVisitor final : public AstNVisitor {
|
||||
// STATE
|
||||
LinkDotState* m_statep; // State to pass between visitors, including symbol table
|
||||
LinkDotState* const m_statep; // State to pass between visitors, including symbol table
|
||||
AstNodeModule* m_classOrPackagep = nullptr; // Current package
|
||||
VSymEnt* m_modSymp = nullptr; // Symbol Entry for current module
|
||||
VSymEnt* m_curSymp = nullptr; // Symbol Entry for current table, where to lookup/insert
|
||||
|
|
@ -725,7 +725,7 @@ class LinkDotFindVisitor final : public AstNVisitor {
|
|||
static int debug() { return LinkDotState::debug(); }
|
||||
|
||||
void makeImplicitNew(AstClass* nodep) {
|
||||
AstFunc* newp = new AstFunc(nodep->fileline(), "new", nullptr, nullptr);
|
||||
AstFunc* const newp = new AstFunc(nodep->fileline(), "new", nullptr, nullptr);
|
||||
newp->isConstructor(true);
|
||||
nodep->addMembersp(newp);
|
||||
UINFO(8, "Made implicit new for " << nodep->name() << ": " << nodep << endl);
|
||||
|
|
@ -793,8 +793,8 @@ class LinkDotFindVisitor final : public AstNVisitor {
|
|||
} else if (doit) {
|
||||
UINFO(4, " Link Module: " << nodep << endl);
|
||||
UASSERT_OBJ(!nodep->dead(), nodep, "Module in instance tree mislabeled as dead?");
|
||||
VSymEnt* upperSymp = m_curSymp ? m_curSymp : m_statep->rootEntp();
|
||||
AstPackage* pkgp = VN_CAST(nodep, Package);
|
||||
VSymEnt* const upperSymp = m_curSymp ? m_curSymp : m_statep->rootEntp();
|
||||
AstPackage* const pkgp = VN_CAST(nodep, Package);
|
||||
m_classOrPackagep = pkgp;
|
||||
if (standalonePkg) {
|
||||
if (pkgp->isDollarUnit()) {
|
||||
|
|
@ -818,13 +818,13 @@ class LinkDotFindVisitor final : public AstNVisitor {
|
|||
nodep->user2(false);
|
||||
nodep->user4(true);
|
||||
// Interfaces need another pass when signals are resolved
|
||||
if (AstIface* ifacep = VN_CAST(nodep, Iface)) {
|
||||
if (AstIface* const ifacep = VN_CAST(nodep, Iface)) {
|
||||
m_statep->insertIfaceModSym(ifacep, m_curSymp);
|
||||
}
|
||||
} else if (isHierBlockWrapper(nodep->name())) {
|
||||
UINFO(5, "Module is hierarchical block, must not be dead: " << nodep << endl);
|
||||
m_scope = nodep->name();
|
||||
VSymEnt* upperSymp = m_curSymp ? m_curSymp : m_statep->rootEntp();
|
||||
VSymEnt* const upperSymp = m_curSymp ? m_curSymp : m_statep->rootEntp();
|
||||
m_curSymp = m_modSymp
|
||||
= m_statep->insertBlock(upperSymp, nodep->name() + "::", nodep, m_classOrPackagep);
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -847,7 +847,7 @@ class LinkDotFindVisitor final : public AstNVisitor {
|
|||
VL_RESTORER(m_modWithNum);
|
||||
{
|
||||
UINFO(4, " Link Class: " << nodep << endl);
|
||||
VSymEnt* upperSymp = m_curSymp;
|
||||
VSymEnt* const upperSymp = m_curSymp;
|
||||
m_scope = m_scope + "." + nodep->name();
|
||||
m_classOrPackagep = nodep;
|
||||
m_curSymp = m_modSymp
|
||||
|
|
@ -1180,8 +1180,8 @@ class LinkDotFindVisitor final : public AstNVisitor {
|
|||
m_statep->insertSym(m_curSymp, nodep->name(), nodep, m_classOrPackagep);
|
||||
if (m_statep->forPrimary() && nodep->isGParam()) {
|
||||
++m_paramNum;
|
||||
VSymEnt* symp = m_statep->insertSym(m_curSymp, "__paramNumber" + cvtToStr(m_paramNum),
|
||||
nodep, m_classOrPackagep);
|
||||
VSymEnt* const symp = m_statep->insertSym(
|
||||
m_curSymp, "__paramNumber" + cvtToStr(m_paramNum), nodep, m_classOrPackagep);
|
||||
symp->exported(false);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ private:
|
|||
} else if (m_insMode == IM_AFTER) {
|
||||
m_insStmtp->addNextHere(newp);
|
||||
} else if (m_insMode == IM_WHILE_PRECOND) {
|
||||
AstWhile* whilep = VN_AS(m_insStmtp, While);
|
||||
AstWhile* const whilep = VN_AS(m_insStmtp, While);
|
||||
UASSERT_OBJ(whilep, nodep, "Insert should be under WHILE");
|
||||
whilep->addPrecondsp(newp);
|
||||
} else {
|
||||
|
|
@ -151,12 +151,12 @@ private:
|
|||
void prepost_non_stmt_visit(AstNodeTriop* nodep) {
|
||||
iterateChildren(nodep);
|
||||
|
||||
AstConst* constp = VN_AS(nodep->lhsp(), Const);
|
||||
AstConst* const constp = VN_AS(nodep->lhsp(), Const);
|
||||
UASSERT_OBJ(nodep, constp, "Expecting CONST");
|
||||
AstConst* newconstp = constp->cloneTree(true);
|
||||
AstConst* const newconstp = constp->cloneTree(true);
|
||||
|
||||
AstNode* storetop = nodep->thsp();
|
||||
AstNode* valuep = nodep->rhsp();
|
||||
AstNode* const storetop = nodep->thsp();
|
||||
AstNode* const valuep = nodep->rhsp();
|
||||
|
||||
storetop->unlinkFrBack();
|
||||
valuep->unlinkFrBack();
|
||||
|
|
@ -175,22 +175,22 @@ private:
|
|||
void prepost_stmt_visit(AstNodeTriop* nodep) {
|
||||
iterateChildren(nodep);
|
||||
|
||||
AstNodeVarRef* varrefp = nullptr;
|
||||
const AstNodeVarRef* varrefp = nullptr;
|
||||
if (m_unsupportedHere || !(varrefp = VN_CAST(nodep->rhsp(), VarRef))) {
|
||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: Incrementation in this context.");
|
||||
return;
|
||||
}
|
||||
|
||||
AstConst* constp = VN_AS(nodep->lhsp(), Const);
|
||||
AstConst* const constp = VN_AS(nodep->lhsp(), Const);
|
||||
UASSERT_OBJ(nodep, constp, "Expecting CONST");
|
||||
AstNode* backp = nodep->backp();
|
||||
AstConst* newconstp = constp->cloneTree(true);
|
||||
const AstNode* const backp = nodep->backp();
|
||||
AstConst* const newconstp = constp->cloneTree(true);
|
||||
|
||||
// Prepare a temporary variable
|
||||
FileLine* fl = backp->fileline();
|
||||
FileLine* const fl = backp->fileline();
|
||||
const string name = string("__Vincrement") + cvtToStr(++m_modIncrementsNum);
|
||||
AstVar* varp = new AstVar(fl, AstVarType::BLOCKTEMP, name, VFlagChildDType(),
|
||||
varrefp->varp()->subDTypep()->cloneTree(true));
|
||||
AstVar* const varp = new AstVar(fl, AstVarType::BLOCKTEMP, name, VFlagChildDType(),
|
||||
varrefp->varp()->subDTypep()->cloneTree(true));
|
||||
|
||||
// Declare the variable
|
||||
insertBeforeStmt(nodep, varp);
|
||||
|
|
|
|||
|
|
@ -89,8 +89,8 @@ private:
|
|||
if (VN_IS(underp, JumpLabel)) {
|
||||
return VN_AS(underp, JumpLabel);
|
||||
} else { // Move underp stuff to be under a new label
|
||||
AstJumpBlock* blockp = new AstJumpBlock(nodep->fileline(), nullptr);
|
||||
AstJumpLabel* labelp = new AstJumpLabel(nodep->fileline(), blockp);
|
||||
AstJumpBlock* const blockp = new AstJumpBlock(nodep->fileline(), nullptr);
|
||||
AstJumpLabel* const labelp = new AstJumpLabel(nodep->fileline(), blockp);
|
||||
blockp->labelp(labelp);
|
||||
|
||||
AstNRelinker repHandle;
|
||||
|
|
@ -143,23 +143,23 @@ private:
|
|||
// So later optimizations don't need to deal with them,
|
||||
// REPEAT(count,body) -> loop=count,WHILE(loop>0) { body, loop-- }
|
||||
// Note var can be signed or unsigned based on original number.
|
||||
AstNode* countp = nodep->countp()->unlinkFrBackWithNext();
|
||||
AstNode* const countp = nodep->countp()->unlinkFrBackWithNext();
|
||||
const string name = string("__Vrepeat") + cvtToStr(m_modRepeatNum++);
|
||||
// Spec says value is integral, if negative is ignored
|
||||
AstVar* varp = new AstVar(nodep->fileline(), AstVarType::BLOCKTEMP, name,
|
||||
nodep->findSigned32DType());
|
||||
AstVar* const varp = new AstVar(nodep->fileline(), AstVarType::BLOCKTEMP, name,
|
||||
nodep->findSigned32DType());
|
||||
varp->usedLoopIdx(true);
|
||||
m_modp->addStmtp(varp);
|
||||
AstNode* initsp = new AstAssign(
|
||||
nodep->fileline(), new AstVarRef(nodep->fileline(), varp, VAccess::WRITE), countp);
|
||||
AstNode* decp = new AstAssign(
|
||||
AstNode* const decp = new AstAssign(
|
||||
nodep->fileline(), new AstVarRef(nodep->fileline(), varp, VAccess::WRITE),
|
||||
new AstSub(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, VAccess::READ),
|
||||
new AstConst(nodep->fileline(), 1)));
|
||||
AstNode* zerosp = new AstConst(nodep->fileline(), AstConst::Signed32(), 0);
|
||||
AstNode* condp = new AstGtS(nodep->fileline(),
|
||||
new AstVarRef(nodep->fileline(), varp, VAccess::READ), zerosp);
|
||||
AstNode* bodysp = nodep->bodysp();
|
||||
AstNode* const zerosp = new AstConst(nodep->fileline(), AstConst::Signed32(), 0);
|
||||
AstNode* const condp = new AstGtS(
|
||||
nodep->fileline(), new AstVarRef(nodep->fileline(), varp, VAccess::READ), zerosp);
|
||||
AstNode* const bodysp = nodep->bodysp();
|
||||
if (bodysp) bodysp->unlinkFrBackWithNext();
|
||||
AstNode* newp = new AstWhile(nodep->fileline(), condp, bodysp, decp);
|
||||
initsp = initsp->addNext(newp);
|
||||
|
|
@ -170,7 +170,7 @@ private:
|
|||
virtual void visit(AstWait* nodep) override {
|
||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: wait statements");
|
||||
// Statements we'll just execute immediately; equivalent to if they followed this
|
||||
if (AstNode* bodysp = nodep->bodysp()) {
|
||||
if (AstNode* const bodysp = nodep->bodysp()) {
|
||||
bodysp->unlinkFrBackWithNext();
|
||||
nodep->replaceWith(bodysp);
|
||||
} else {
|
||||
|
|
@ -194,7 +194,7 @@ private:
|
|||
}
|
||||
virtual void visit(AstReturn* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
AstFunc* funcp = VN_CAST(m_ftaskp, Func);
|
||||
const AstFunc* const funcp = VN_CAST(m_ftaskp, Func);
|
||||
if (m_inFork) {
|
||||
nodep->v3error("Return isn't legal under fork (IEEE 1800-2017 9.2.3)");
|
||||
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
|
||||
|
|
@ -214,7 +214,7 @@ private:
|
|||
nodep->lhsp()->unlinkFrBackWithNext()));
|
||||
}
|
||||
// Jump to the end of the function call
|
||||
AstJumpLabel* labelp = findAddLabel(m_ftaskp, false);
|
||||
AstJumpLabel* const labelp = findAddLabel(m_ftaskp, false);
|
||||
nodep->addPrev(new AstJumpGo(nodep->fileline(), labelp));
|
||||
}
|
||||
nodep->unlinkFrBack();
|
||||
|
|
@ -226,7 +226,7 @@ private:
|
|||
nodep->v3error("break isn't underneath a loop");
|
||||
} else {
|
||||
// Jump to the end of the loop
|
||||
AstJumpLabel* labelp = findAddLabel(m_loopp, false);
|
||||
AstJumpLabel* const labelp = findAddLabel(m_loopp, false);
|
||||
nodep->addNextHere(new AstJumpGo(nodep->fileline(), labelp));
|
||||
}
|
||||
nodep->unlinkFrBack();
|
||||
|
|
@ -239,7 +239,7 @@ private:
|
|||
} else {
|
||||
// Jump to the end of this iteration
|
||||
// If a "for" loop then need to still do the post-loop increment
|
||||
AstJumpLabel* labelp = findAddLabel(m_loopp, true);
|
||||
AstJumpLabel* const labelp = findAddLabel(m_loopp, true);
|
||||
nodep->addNextHere(new AstJumpGo(nodep->fileline(), labelp));
|
||||
}
|
||||
nodep->unlinkFrBack();
|
||||
|
|
@ -261,7 +261,7 @@ private:
|
|||
nodep->v3error("disable isn't underneath a begin with name: " << nodep->prettyNameQ());
|
||||
} else if (AstBegin* beginp = VN_CAST(blockp, Begin)) {
|
||||
// Jump to the end of the named block
|
||||
AstJumpLabel* labelp = findAddLabel(beginp, false);
|
||||
AstJumpLabel* const labelp = findAddLabel(beginp, false);
|
||||
nodep->addNextHere(new AstJumpGo(nodep->fileline(), labelp));
|
||||
} else {
|
||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: disable fork");
|
||||
|
|
|
|||
|
|
@ -262,11 +262,11 @@ private:
|
|||
}
|
||||
virtual void visit(AstNodeFTaskRef* nodep) override {
|
||||
AstNode* pinp = nodep->pinsp();
|
||||
AstNodeFTask* taskp = nodep->taskp();
|
||||
const AstNodeFTask* const taskp = nodep->taskp();
|
||||
// We'll deal with mismatching pins later
|
||||
if (!taskp) return;
|
||||
for (AstNode* stmtp = taskp->stmtsp(); stmtp && pinp; stmtp = stmtp->nextp()) {
|
||||
if (const AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (const AstVar* const portp = VN_CAST(stmtp, Var)) {
|
||||
if (portp->isIO()) {
|
||||
if (portp->isWritable()) {
|
||||
m_setRefLvalue = VAccess::WRITE;
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ void V3LinkLevel::modSortByLevel() {
|
|||
mods.push_back(nodep);
|
||||
}
|
||||
if (tops.size() >= 2) {
|
||||
AstNode* secp = tops[1]; // Complain about second one, as first often intended
|
||||
const AstNode* const secp = tops[1]; // Complain about second one, as first often intended
|
||||
if (!secp->fileline()->warnIsOff(V3ErrorCode::MULTITOP)) {
|
||||
secp->v3warn(MULTITOP, "Multiple top level modules\n"
|
||||
<< secp->warnMore()
|
||||
|
|
@ -86,7 +86,7 @@ void V3LinkLevel::modSortByLevel() {
|
|||
|
||||
void V3LinkLevel::timescaling(const ModVec& mods) {
|
||||
// Timescale determination
|
||||
AstNodeModule* modTimedp = nullptr;
|
||||
const AstNodeModule* modTimedp = nullptr;
|
||||
VTimescale unit(VTimescale::NONE);
|
||||
// Use highest level module as default unit - already sorted in proper order
|
||||
for (const auto& modp : mods) {
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ private:
|
|||
|
||||
string nameFromTypedef(AstNode* nodep) {
|
||||
// Try to find a name for a typedef'ed enum/struct
|
||||
if (AstTypedef* typedefp = VN_CAST(nodep->backp(), Typedef)) {
|
||||
if (const AstTypedef* const typedefp = VN_CAST(nodep->backp(), Typedef)) {
|
||||
// Create a name for the enum, to aid debug and tracing
|
||||
// This name is not guaranteed to be globally unique (due to later parameterization)
|
||||
string above;
|
||||
|
|
@ -112,7 +112,7 @@ private:
|
|||
// -> 1:3: BEGIN [GEN] [IMPLIED] // nodep passed to this function
|
||||
// 1:3:1: GENIF
|
||||
// 1:3:1:2: BEGIN genblk1 [GEN] [IMPLIED]
|
||||
AstNode* const backp = nodep->backp();
|
||||
const AstNode* const backp = nodep->backp();
|
||||
return (nodep->implied() // User didn't provide begin/end
|
||||
&& VN_IS(backp, GenIf) && VN_CAST(backp, GenIf)->elsesp() == nodep
|
||||
&& !nodep->nextp() // No other statements under upper genif else
|
||||
|
|
@ -554,7 +554,7 @@ private:
|
|||
virtual void visit(AstBegin* nodep) override {
|
||||
V3Config::applyCoverageBlock(m_modp, nodep);
|
||||
cleanFileline(nodep);
|
||||
AstNode* const backp = nodep->backp();
|
||||
const AstNode* const backp = nodep->backp();
|
||||
// IEEE says directly nested item is not a new block
|
||||
// The genblk name will get attached to the if true/false LOWER begin block(s)
|
||||
const bool nestedIf = nestedIfBegin(nodep);
|
||||
|
|
|
|||
|
|
@ -152,12 +152,12 @@ private:
|
|||
// If it's not a simple variable wrap in a temporary
|
||||
// This is a bit unfortunate as we haven't done width resolution
|
||||
// and any width errors will look a bit odd, but it works.
|
||||
AstNode* sensp = nodep->sensp();
|
||||
AstNode* const sensp = nodep->sensp();
|
||||
if (sensp && !VN_IS(sensp, NodeVarRef) && !VN_IS(sensp, Const)) {
|
||||
// Make a new temp wire
|
||||
const string newvarname = "__Vsenitemexpr" + cvtToStr(++m_senitemCvtNum);
|
||||
AstVar* newvarp = new AstVar(sensp->fileline(), AstVarType::MODULETEMP, newvarname,
|
||||
VFlagLogicPacked(), 1);
|
||||
AstVar* const newvarp = new AstVar(sensp->fileline(), AstVarType::MODULETEMP,
|
||||
newvarname, VFlagLogicPacked(), 1);
|
||||
// We can't just add under the module, because we may be
|
||||
// inside a generate, begin, etc.
|
||||
// We know a SenItem should be under a SenTree/Always etc,
|
||||
|
|
@ -175,7 +175,7 @@ private:
|
|||
addwherep->addNext(newvarp);
|
||||
|
||||
sensp->replaceWith(new AstVarRef(sensp->fileline(), newvarp, VAccess::READ));
|
||||
AstAssignW* assignp = new AstAssignW(
|
||||
AstAssignW* const assignp = new AstAssignW(
|
||||
sensp->fileline(), new AstVarRef(sensp->fileline(), newvarp, VAccess::WRITE),
|
||||
sensp);
|
||||
addwherep->addNext(assignp);
|
||||
|
|
@ -184,21 +184,21 @@ private:
|
|||
bool did = true;
|
||||
while (did) {
|
||||
did = false;
|
||||
if (AstNodeSel* selp = VN_CAST(nodep->sensp(), NodeSel)) {
|
||||
AstNode* fromp = selp->fromp()->unlinkFrBack();
|
||||
if (AstNodeSel* const selp = VN_CAST(nodep->sensp(), NodeSel)) {
|
||||
AstNode* const fromp = selp->fromp()->unlinkFrBack();
|
||||
selp->replaceWith(fromp);
|
||||
VL_DO_DANGLING(selp->deleteTree(), selp);
|
||||
did = true;
|
||||
}
|
||||
// NodeSel doesn't include AstSel....
|
||||
if (AstSel* selp = VN_CAST(nodep->sensp(), Sel)) {
|
||||
AstNode* fromp = selp->fromp()->unlinkFrBack();
|
||||
if (AstSel* const selp = VN_CAST(nodep->sensp(), Sel)) {
|
||||
AstNode* const fromp = selp->fromp()->unlinkFrBack();
|
||||
selp->replaceWith(fromp);
|
||||
VL_DO_DANGLING(selp->deleteTree(), selp);
|
||||
did = true;
|
||||
}
|
||||
if (AstNodePreSel* selp = VN_CAST(nodep->sensp(), NodePreSel)) {
|
||||
AstNode* fromp = selp->fromp()->unlinkFrBack();
|
||||
if (AstNodePreSel* const selp = VN_CAST(nodep->sensp(), NodePreSel)) {
|
||||
AstNode* const fromp = selp->fromp()->unlinkFrBack();
|
||||
selp->replaceWith(fromp);
|
||||
VL_DO_DANGLING(selp->deleteTree(), selp);
|
||||
did = true;
|
||||
|
|
@ -220,8 +220,8 @@ private:
|
|||
// variable we're extracting from (to determine MSB/LSB/endianness/etc.)
|
||||
// So we replicate it in another node
|
||||
// Note that V3Param knows not to replace AstVarRef's under AstAttrOf's
|
||||
AstNode* basefromp = AstArraySel::baseFromp(nodep, false);
|
||||
if (AstNodeVarRef* varrefp
|
||||
AstNode* const basefromp = AstArraySel::baseFromp(nodep, false);
|
||||
if (AstNodeVarRef* const varrefp
|
||||
= VN_CAST(basefromp, NodeVarRef)) { // Maybe varxref - so need to clone
|
||||
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE,
|
||||
varrefp->cloneTree(false)));
|
||||
|
|
@ -254,7 +254,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
if (!nodep->user2() && nodep->isDefault() && nodep->nextp()) {
|
||||
nodep->user2(true);
|
||||
AstNode* nextp = nodep->nextp();
|
||||
AstNode* const nextp = nodep->nextp();
|
||||
nodep->unlinkFrBack();
|
||||
nextp->addNext(nodep);
|
||||
}
|
||||
|
|
@ -355,7 +355,7 @@ private:
|
|||
skipCount--;
|
||||
continue;
|
||||
}
|
||||
AstConst* constp = VN_CAST(argp, Const);
|
||||
const AstConst* const constp = VN_CAST(argp, Const);
|
||||
const bool isFromString = (constp) ? constp->num().isFromString() : false;
|
||||
if (isFromString) {
|
||||
const int numchars = argp->dtypep()->width() / 8;
|
||||
|
|
@ -389,7 +389,7 @@ private:
|
|||
}
|
||||
}
|
||||
newFormat.append(str);
|
||||
AstNode* nextp = argp->nextp();
|
||||
AstNode* const nextp = argp->nextp();
|
||||
argp->unlinkFrBack();
|
||||
VL_DO_DANGLING(pushDeletep(argp), argp);
|
||||
argp = nextp;
|
||||
|
|
@ -450,7 +450,7 @@ private:
|
|||
"Non-format $sformatf should have \"\" format");
|
||||
if (VN_IS(nodep->exprsp(), Const)
|
||||
&& VN_AS(nodep->exprsp(), Const)->num().isFromString()) {
|
||||
AstConst* fmtp = VN_AS(nodep->exprsp()->unlinkFrBack(), Const);
|
||||
AstConst* const fmtp = VN_AS(nodep->exprsp()->unlinkFrBack(), Const);
|
||||
nodep->text(fmtp->num().toString());
|
||||
VL_DO_DANGLING(pushDeletep(fmtp), fmtp);
|
||||
}
|
||||
|
|
@ -472,9 +472,9 @@ private:
|
|||
// never used won't result in any warnings.
|
||||
} else {
|
||||
// Massive hack, just tie off all outputs so our analysis can proceed
|
||||
AstVar* varoutp = nullptr;
|
||||
const AstVar* varoutp = nullptr;
|
||||
for (AstNode* stmtp = m_modp->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (AstVar* varp = VN_CAST(stmtp, Var)) {
|
||||
if (AstVar* const varp = VN_CAST(stmtp, Var)) {
|
||||
if (varp->isReadOnly()) {
|
||||
} else if (varp->isWritable()) {
|
||||
if (varoutp) {
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ private:
|
|||
if (m_nodeDepth == 0) {
|
||||
// Check if simple "VARREF = ..." assignment, i.e.: this assignment sets the whole
|
||||
// variable (and in particular, it is not assigned only in part).
|
||||
if (AstVarRef* const refp = VN_CAST(nodep->lhsp(), VarRef)) {
|
||||
if (const AstVarRef* const refp = VN_CAST(nodep->lhsp(), VarRef)) {
|
||||
// Mark this VarScope as assigned in this function
|
||||
refp->varScopep()->user2(1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ struct V3OptionParser::Impl {
|
|||
|
||||
#define V3OPTION_PARSER_DEF_ACT_CLASS(className, type, body, enType) \
|
||||
template <> class V3OptionParser::Impl::className<type> final : public ActionBase<enType> { \
|
||||
type* m_valp; /* Pointer to a option variable*/ \
|
||||
type* const m_valp; /* Pointer to a option variable*/ \
|
||||
\
|
||||
public: \
|
||||
explicit className(type* valp) \
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ void VTimescale::parseSlashed(FileLine* fl, const char* textp, VTimescale& unitr
|
|||
|
||||
const char* cp = textp;
|
||||
for (; isspace(*cp); ++cp) {}
|
||||
const char* unitp = cp;
|
||||
const char* const unitp = cp;
|
||||
for (; *cp && *cp != '/'; ++cp) {}
|
||||
string unitStr(unitp, cp - unitp);
|
||||
for (; isspace(*cp); ++cp) {}
|
||||
|
|
@ -242,7 +242,7 @@ void VTimescale::parseSlashed(FileLine* fl, const char* textp, VTimescale& unitr
|
|||
if (*cp == '/') {
|
||||
++cp;
|
||||
for (; isspace(*cp); ++cp) {}
|
||||
const char* precp = cp;
|
||||
const char* const precp = cp;
|
||||
for (; *cp && *cp != '/'; ++cp) {}
|
||||
precStr = string(precp, cp - precp);
|
||||
}
|
||||
|
|
@ -442,7 +442,7 @@ void V3Options::fileNfsFlush(const string& filename) {
|
|||
// NFS caches stat() calls so to get up-to-date information must
|
||||
// do a open or opendir on the filename.
|
||||
// Faster to just try both rather than check if a file is a dir.
|
||||
if (DIR* dirp = opendir(filename.c_str())) { // LCOV_EXCL_BR_LINE
|
||||
if (DIR* const dirp = opendir(filename.c_str())) { // LCOV_EXCL_BR_LINE
|
||||
closedir(dirp); // LCOV_EXCL_LINE
|
||||
} else if (int fd = ::open(filename.c_str(), O_RDONLY)) { // LCOV_EXCL_BR_LINE
|
||||
if (fd > 0) ::close(fd);
|
||||
|
|
@ -465,7 +465,7 @@ string V3Options::fileExists(const string& filename) {
|
|||
|
||||
std::set<string>* setp = &(diriter->second);
|
||||
|
||||
if (DIR* dirp = opendir(dir.c_str())) {
|
||||
if (DIR* const dirp = opendir(dir.c_str())) {
|
||||
while (struct dirent* direntp = readdir(dirp)) setp->insert(direntp->d_name);
|
||||
closedir(dirp);
|
||||
}
|
||||
|
|
@ -710,7 +710,7 @@ bool V3Options::systemCFound() {
|
|||
// V3 Options notification methods
|
||||
|
||||
void V3Options::notify() {
|
||||
FileLine* cmdfl = new FileLine(FileLine::commandLineFilename());
|
||||
FileLine* const cmdfl = new FileLine(FileLine::commandLineFilename());
|
||||
|
||||
// Notify that all arguments have been passed and final modification can be made.
|
||||
if (!outFormatOk() && !cdc() && !dpiHdrOnly() && !lintOnly() && !preprocOnly() && !xmlOnly()) {
|
||||
|
|
|
|||
|
|
@ -130,8 +130,8 @@ static bool domainsExclusive(const AstSenTree* fromp, const AstSenTree* top) {
|
|||
const bool fromInitial = fromp->hasInitial() || fromp->hasSettle();
|
||||
if (toInitial != fromInitial) return true;
|
||||
|
||||
const AstSenItem* fromSenListp = fromp->sensesp();
|
||||
const AstSenItem* toSenListp = top->sensesp();
|
||||
const AstSenItem* const fromSenListp = fromp->sensesp();
|
||||
const AstSenItem* const toSenListp = top->sensesp();
|
||||
|
||||
UASSERT_OBJ(fromSenListp, fromp, "sensitivity list empty");
|
||||
UASSERT_OBJ(toSenListp, top, "sensitivity list empty");
|
||||
|
|
@ -139,8 +139,8 @@ static bool domainsExclusive(const AstSenTree* fromp, const AstSenTree* top) {
|
|||
if (fromSenListp->nextp()) return false;
|
||||
if (toSenListp->nextp()) return false;
|
||||
|
||||
const AstNodeVarRef* fromVarrefp = fromSenListp->varrefp();
|
||||
const AstNodeVarRef* toVarrefp = toSenListp->varrefp();
|
||||
const AstNodeVarRef* const fromVarrefp = fromSenListp->varrefp();
|
||||
const AstNodeVarRef* const toVarrefp = toSenListp->varrefp();
|
||||
if (!fromVarrefp || !toVarrefp) return false;
|
||||
|
||||
// We know nothing about the relationship between different clocks here,
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@
|
|||
string V3Os::getenvStr(const string& envvar, const string& defaultValue) {
|
||||
#if defined(_MSC_VER)
|
||||
// Note: MinGW does not offer _dupenv_s
|
||||
char* envvalue = nullptr;
|
||||
const char* const envvalue = nullptr;
|
||||
_dupenv_s(&envvalue, nullptr, envvar.c_str());
|
||||
if (envvalue != nullptr) {
|
||||
const std::string result{envvalue};
|
||||
|
|
@ -82,7 +82,7 @@ string V3Os::getenvStr(const string& envvar, const string& defaultValue) {
|
|||
return defaultValue;
|
||||
}
|
||||
#else
|
||||
if (const char* envvalue = getenv(envvar.c_str())) {
|
||||
if (const char* const envvalue = getenv(envvar.c_str())) {
|
||||
return envvalue;
|
||||
} else {
|
||||
return defaultValue;
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ public:
|
|||
if (!pinp->exprp()) continue;
|
||||
UASSERT_OBJ(!pinp->modPTypep(), pinp,
|
||||
"module with type parameter must not be a hierarchical block");
|
||||
if (AstVar* modvarp = pinp->modVarp()) {
|
||||
if (const AstVar* modvarp = pinp->modVarp()) {
|
||||
AstConst* const constp = VN_AS(pinp->exprp(), Const);
|
||||
UASSERT_OBJ(constp, pinp,
|
||||
"parameter for a hierarchical block must have been constified");
|
||||
|
|
|
|||
|
|
@ -71,10 +71,10 @@ AstNode* V3ParseGrammar::argWrapList(AstNode* nodep) {
|
|||
// Convert list of expressions to list of arguments
|
||||
if (!nodep) return nullptr;
|
||||
AstNode* outp = nullptr;
|
||||
AstBegin* tempp = new AstBegin(nodep->fileline(), "[EditWrapper]", nodep);
|
||||
AstBegin* const tempp = new AstBegin(nodep->fileline(), "[EditWrapper]", nodep);
|
||||
while (nodep) {
|
||||
AstNode* nextp = nodep->nextp();
|
||||
AstNode* exprp = nodep->unlinkFrBack();
|
||||
AstNode* const nextp = nodep->nextp();
|
||||
AstNode* const exprp = nodep->unlinkFrBack();
|
||||
nodep = nextp;
|
||||
// addNext can handle nulls:
|
||||
outp = AstNode::addNext(outp, new AstArg(exprp->fileline(), "", exprp));
|
||||
|
|
@ -117,9 +117,9 @@ AstNodeDType* V3ParseGrammar::createArray(AstNodeDType* basep, AstNodeRange* nra
|
|||
if (nrangep) { // Maybe no range - return unmodified base type
|
||||
while (nrangep->nextp()) nrangep = VN_AS(nrangep->nextp(), NodeRange);
|
||||
while (nrangep) {
|
||||
AstNodeRange* prevp = VN_AS(nrangep->backp(), NodeRange);
|
||||
AstNodeRange* const prevp = VN_AS(nrangep->backp(), NodeRange);
|
||||
if (prevp) nrangep->unlinkFrBack();
|
||||
AstRange* rangep = VN_CAST(nrangep, Range);
|
||||
AstRange* const rangep = VN_CAST(nrangep, Range);
|
||||
if (rangep && isPacked) {
|
||||
arrayp
|
||||
= new AstPackArrayDType(rangep->fileline(), VFlagChildDType(), arrayp, rangep);
|
||||
|
|
@ -134,8 +134,8 @@ AstNodeDType* V3ParseGrammar::createArray(AstNodeDType* basep, AstNodeRange* nra
|
|||
} else if (VN_IS(nrangep, UnsizedRange)) {
|
||||
arrayp = new AstUnsizedArrayDType(nrangep->fileline(), VFlagChildDType(), arrayp);
|
||||
} else if (VN_IS(nrangep, BracketRange)) {
|
||||
AstBracketRange* arangep = VN_AS(nrangep, BracketRange);
|
||||
AstNode* keyp = arangep->elementsp()->unlinkFrBack();
|
||||
const AstBracketRange* const arangep = VN_AS(nrangep, BracketRange);
|
||||
AstNode* const keyp = arangep->elementsp()->unlinkFrBack();
|
||||
arrayp = new AstBracketArrayDType(nrangep->fileline(), VFlagChildDType(), arrayp,
|
||||
keyp);
|
||||
} else {
|
||||
|
|
@ -182,9 +182,9 @@ AstVar* V3ParseGrammar::createVariable(FileLine* fileline, const string& name,
|
|||
|
||||
// Split RANGE0-RANGE1-RANGE2 into
|
||||
// ARRAYDTYPE0(ARRAYDTYPE1(ARRAYDTYPE2(BASICTYPE3), RANGE), RANGE)
|
||||
AstNodeDType* arrayDTypep = createArray(dtypep, arrayp, false);
|
||||
AstNodeDType* const arrayDTypep = createArray(dtypep, arrayp, false);
|
||||
|
||||
AstVar* nodep = new AstVar(fileline, type, name, VFlagChildDType(), arrayDTypep);
|
||||
AstVar* const nodep = new AstVar(fileline, type, name, VFlagChildDType(), arrayDTypep);
|
||||
nodep->addAttrsp(attrsp);
|
||||
nodep->ansi(m_pinAnsi);
|
||||
nodep->declTyped(m_varDeclTyped);
|
||||
|
|
@ -203,7 +203,7 @@ AstVar* V3ParseGrammar::createVariable(FileLine* fileline, const string& name,
|
|||
}
|
||||
if (VN_IS(dtypep, ParseTypeDType)) {
|
||||
// Parser needs to know what is a type
|
||||
AstNode* newp = new AstTypedefFwd(fileline, name);
|
||||
AstNode* const newp = new AstTypedefFwd(fileline, name);
|
||||
nodep->addNext(newp);
|
||||
SYMP->reinsert(newp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ V3ParseImp::~V3ParseImp() {
|
|||
|
||||
void V3ParseImp::lexPpline(const char* textp) {
|
||||
// Handle lexer `line directive
|
||||
FileLine* prevFl = copyOrSameFileLine();
|
||||
FileLine* const prevFl = copyOrSameFileLine();
|
||||
int enterExit;
|
||||
lexFileline()->lineDirective(textp, enterExit /*ref*/);
|
||||
if (enterExit == 1) { // Enter
|
||||
|
|
@ -186,7 +186,7 @@ string V3ParseImp::lexParseTag(const char* textp) {
|
|||
|
||||
double V3ParseImp::lexParseTimenum(const char* textp) {
|
||||
const size_t length = strlen(textp);
|
||||
char* strgp = new char[length + 1];
|
||||
char* const strgp = new char[length + 1];
|
||||
char* dp = strgp;
|
||||
const char* sp = textp;
|
||||
for (; isdigit(*sp) || *sp == '_' || *sp == '.'; ++sp) {
|
||||
|
|
@ -281,7 +281,7 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i
|
|||
if (!ok) {
|
||||
if (errmsg != "") return; // Threw error already
|
||||
// Create fake node for later error reporting
|
||||
AstNodeModule* nodep = new AstNotFoundModule(fileline, modname);
|
||||
AstNodeModule* const nodep = new AstNotFoundModule(fileline, modname);
|
||||
v3Global.rootp()->addModulep(nodep);
|
||||
return;
|
||||
}
|
||||
|
|
@ -488,7 +488,7 @@ void V3ParseImp::tokenPipelineSym() {
|
|||
int token = yylval.token;
|
||||
if (token == yaID__LEX || token == yaID__CC) {
|
||||
VSymEnt* foundp;
|
||||
if (VSymEnt* look_underp = V3ParseImp::parsep()->symp()->nextId()) {
|
||||
if (VSymEnt* const look_underp = V3ParseImp::parsep()->symp()->nextId()) {
|
||||
UINFO(7, " tokenPipelineSym: next id lookup forced under " << look_underp << endl);
|
||||
// if (debug() >= 7) V3ParseImp::parsep()->symp()->dump(cout, " -symtree: ");
|
||||
foundp = look_underp->findIdFallback(*(yylval.strp));
|
||||
|
|
@ -503,7 +503,7 @@ void V3ParseImp::tokenPipelineSym() {
|
|||
foundp = V3ParseImp::parsep()->symp()->symCurrentp()->findIdFallback(*(yylval.strp));
|
||||
}
|
||||
if (foundp) {
|
||||
AstNode* scp = foundp->nodep();
|
||||
AstNode* const scp = foundp->nodep();
|
||||
yylval.scp = scp;
|
||||
UINFO(7, " tokenPipelineSym: Found " << scp << endl);
|
||||
if (token == yaID__LEX) { // i.e. not yaID__CC
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ private:
|
|||
GraphWay m_way; // CPs oriented in this direction: either FORWARD
|
||||
// // from graph-start to current node, or REVERSE
|
||||
// // from graph-end to current node.
|
||||
T_CostAccessor* m_accessp; // Access cost and CPs on V3GraphVertex's.
|
||||
T_CostAccessor* const m_accessp; // Access cost and CPs on V3GraphVertex's.
|
||||
vluint64_t m_generation = 0; // Mark each vertex with this number;
|
||||
// // confirm we only process each vertex once.
|
||||
bool m_slowAsserts; // Enable nontrivial asserts
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
class VDefine final {
|
||||
// Define class. One for each define.
|
||||
// string m_name; // Name of the define (list is keyed by this)
|
||||
FileLine* m_fileline; // Where it was declared
|
||||
FileLine* const m_fileline; // Where it was declared
|
||||
string m_value; // Value of define
|
||||
string m_params; // Parameters
|
||||
bool m_cmdline; // Set on command line, don't `undefineall
|
||||
|
|
@ -801,7 +801,7 @@ void V3PreProcImp::openFile(FileLine*, VInFilter* filterp, const string& filenam
|
|||
}
|
||||
|
||||
// Save file contents for future error reporting
|
||||
FileLine* flsp = new FileLine(filename);
|
||||
FileLine* const flsp = new FileLine(filename);
|
||||
flsp->lineno(1);
|
||||
flsp->newContent();
|
||||
for (const string& i : wholefile) flsp->contentp()->pushText(i);
|
||||
|
|
@ -818,8 +818,8 @@ void V3PreProcImp::openFile(FileLine*, VInFilter* filterp, const string& filenam
|
|||
for (StrList::iterator it = wholefile.begin(); it != wholefile.end(); ++it) {
|
||||
// We don't end-loop at \0 as we allow and strip mid-string '\0's (for now).
|
||||
bool strip = false;
|
||||
const char* sp = it->data();
|
||||
const char* ep = sp + it->length();
|
||||
const char* const sp = it->data();
|
||||
const char* const ep = sp + it->length();
|
||||
// Only process if needed, as saves extra string allocations
|
||||
for (const char* cp = sp; cp < ep; cp++) {
|
||||
if (VL_UNLIKELY(*cp == '\r' || *cp == '\0')) {
|
||||
|
|
@ -848,7 +848,7 @@ void V3PreProcImp::openFile(FileLine*, VInFilter* filterp, const string& filenam
|
|||
|
||||
// Warning check
|
||||
if (eof_newline) {
|
||||
FileLine* fl = new FileLine{flsp};
|
||||
FileLine* const fl = new FileLine{flsp};
|
||||
fl->contentLineno(eof_lineno);
|
||||
fl->column(eof_newline + 1, eof_newline + 1);
|
||||
fl->v3warn(EOFNEWLINE, "Missing newline at end of file (POSIX 3.206).\n"
|
||||
|
|
@ -1180,7 +1180,7 @@ int V3PreProcImp::getStateToken() {
|
|||
if (VL_UNCOVERABLE(m_defRefs.empty())) {
|
||||
fatalSrc("Shouldn't be in DEFPAREN w/o active defref");
|
||||
}
|
||||
VDefineRef* refp = &(m_defRefs.top());
|
||||
VDefineRef* const refp = &(m_defRefs.top());
|
||||
error(string("Expecting ( to begin argument list for define reference `")
|
||||
+ refp->name() + "\n");
|
||||
statePop();
|
||||
|
|
@ -1463,7 +1463,7 @@ int V3PreProcImp::getStateToken() {
|
|||
// Can't subst now, or
|
||||
// `define a x,y
|
||||
// foo(`a,`b) would break because a contains comma
|
||||
VDefineRef* refp = &(m_defRefs.top());
|
||||
VDefineRef* const refp = &(m_defRefs.top());
|
||||
refp->nextarg(refp->nextarg() + m_lexp->m_defValue + out);
|
||||
m_lexp->m_defValue = "";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,11 +53,11 @@ protected:
|
|||
// Create the implementation pointer
|
||||
if (env) {}
|
||||
if (!s_preprocp) {
|
||||
FileLine* cmdfl = new FileLine(FileLine::commandLineFilename());
|
||||
FileLine* const cmdfl = new FileLine(FileLine::commandLineFilename());
|
||||
s_preprocp = V3PreProc::createPreProc(cmdfl);
|
||||
s_preprocp->debug(debug());
|
||||
// Default defines
|
||||
FileLine* prefl = new FileLine(FileLine::builtInFilename());
|
||||
FileLine* const prefl = new FileLine(FileLine::builtInFilename());
|
||||
s_preprocp->defineCmdLine(prefl, "VERILATOR", "1"); // LEAK_OK
|
||||
s_preprocp->defineCmdLine(prefl, "verilator", "1"); // LEAK_OK
|
||||
s_preprocp->defineCmdLine(prefl, "verilator3", "1"); // LEAK_OK
|
||||
|
|
@ -104,7 +104,7 @@ protected:
|
|||
// from the V3LangCode to the various Lex BEGIN states. The language
|
||||
// of this source file is updated here, in case there have been any
|
||||
// intervening +<lang>ext+ options since it was first encountered.
|
||||
FileLine* modfileline = new FileLine(modfilename);
|
||||
FileLine* const modfileline = new FileLine(modfilename);
|
||||
modfileline->language(v3Global.opt.fileLanguage(modfilename));
|
||||
V3Parse::ppPushText(
|
||||
parsep, (string("`begin_keywords \"") + modfileline->language().ascii() + "\"\n"));
|
||||
|
|
@ -171,7 +171,7 @@ void V3PreShell::preprocInclude(FileLine* fl, const string& modname) {
|
|||
V3PreShellImp::s_preImp.preprocInclude(fl, modname);
|
||||
}
|
||||
void V3PreShell::defineCmdLine(const string& name, const string& value) {
|
||||
FileLine* prefl = new FileLine(FileLine::commandLineFilename());
|
||||
FileLine* const prefl = new FileLine(FileLine::commandLineFilename());
|
||||
V3PreShellImp::s_preprocp->defineCmdLine(prefl, name, value);
|
||||
}
|
||||
void V3PreShell::undef(const string& name) { V3PreShellImp::s_preprocp->undef(name); }
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ private:
|
|||
} else {
|
||||
UASSERT_OBJ(!m_foundTop, nodep, "Multiple root modules");
|
||||
}
|
||||
FileLine* fl = nodep->fileline();
|
||||
FileLine* const fl = nodep->fileline();
|
||||
// Need to know the existence of clk before createSvFile()
|
||||
m_hasClk = checkIfClockExists(nodep);
|
||||
createSvFile(fl, nodep);
|
||||
|
|
@ -126,7 +126,7 @@ private:
|
|||
|
||||
void createSvFile(FileLine* fl, AstNodeModule* modp) {
|
||||
// Comments
|
||||
AstTextBlock* txtp = new AstTextBlock(fl);
|
||||
AstTextBlock* const txtp = new AstTextBlock(fl);
|
||||
addComment(txtp, fl, "Wrapper module for DPI protected library");
|
||||
addComment(txtp, fl,
|
||||
"This module requires lib" + m_libName + ".a or lib" + m_libName
|
||||
|
|
@ -288,7 +288,7 @@ private:
|
|||
|
||||
void createCppFile(FileLine* fl) {
|
||||
// Comments
|
||||
AstTextBlock* txtp = new AstTextBlock(fl);
|
||||
AstTextBlock* const txtp = new AstTextBlock(fl);
|
||||
addComment(txtp, fl, "Wrapper functions for DPI protected library\n");
|
||||
|
||||
// Includes
|
||||
|
|
@ -408,7 +408,7 @@ private:
|
|||
}
|
||||
|
||||
void handleClock(AstVar* varp) {
|
||||
FileLine* fl = varp->fileline();
|
||||
FileLine* const fl = varp->fileline();
|
||||
handleInput(varp);
|
||||
m_seqPortsp->addNodep(varp->cloneTree(false));
|
||||
if (m_hasClk) {
|
||||
|
|
@ -420,7 +420,7 @@ private:
|
|||
}
|
||||
|
||||
void handleDataInput(AstVar* varp) {
|
||||
FileLine* fl = varp->fileline();
|
||||
FileLine* const fl = varp->fileline();
|
||||
handleInput(varp);
|
||||
m_comboPortsp->addNodep(varp->cloneTree(false));
|
||||
m_comboParamsp->addText(fl, varp->name() + "\n");
|
||||
|
|
@ -434,13 +434,13 @@ private:
|
|||
void handleInput(AstVar* varp) { m_modPortsp->addNodep(varp->cloneTree(false)); }
|
||||
|
||||
static void addLocalVariable(AstTextBlock* textp, AstVar* varp, const char* suffix) {
|
||||
AstVar* newVarp
|
||||
AstVar* const newVarp
|
||||
= new AstVar(varp->fileline(), AstVarType::VAR, varp->name() + suffix, varp->dtypep());
|
||||
textp->addNodep(newVarp);
|
||||
}
|
||||
|
||||
void handleOutput(AstVar* varp) {
|
||||
FileLine* fl = varp->fileline();
|
||||
FileLine* const fl = varp->fileline();
|
||||
m_modPortsp->addNodep(varp->cloneTree(false));
|
||||
m_comboPortsp->addNodep(varp->cloneTree(false));
|
||||
m_comboParamsp->addText(fl, varp->name() + "_combo__V\n");
|
||||
|
|
@ -471,7 +471,7 @@ private:
|
|||
|
||||
static bool checkIfClockExists(AstNodeModule* modp) {
|
||||
for (AstNode* stmtp = modp->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (AstVar* varp = VN_CAST(stmtp, Var)) {
|
||||
if (const AstVar* const varp = VN_CAST(stmtp, Var)) {
|
||||
if (varp->direction() == VDirection::INPUT
|
||||
&& (varp->isUsedClock()
|
||||
|| varp->attrClocker() == VVarAttrClocker::CLOCKER_YES)) {
|
||||
|
|
|
|||
|
|
@ -53,8 +53,8 @@ private:
|
|||
for (auto* memberp = classp->stmtsp(); memberp; memberp = memberp->nextp()) {
|
||||
// If member is rand and of class type, mark its class
|
||||
if (VN_IS(memberp, Var) && VN_AS(memberp, Var)->isRand()) {
|
||||
if (auto* classRefp = VN_CAST(memberp->dtypep(), ClassRefDType)) {
|
||||
auto* rclassp = classRefp->classp();
|
||||
if (const auto* const classRefp = VN_CAST(memberp->dtypep(), ClassRefDType)) {
|
||||
auto* const rclassp = classRefp->classp();
|
||||
markMembers(rclassp);
|
||||
markDerived(rclassp);
|
||||
rclassp->user1(true);
|
||||
|
|
@ -84,15 +84,16 @@ private:
|
|||
iterateChildren(nodep);
|
||||
if (nodep->extendsp()) {
|
||||
// Save pointer to derived class
|
||||
auto* basep = nodep->extendsp()->classp();
|
||||
auto* const basep = nodep->extendsp()->classp();
|
||||
m_baseToDerivedMap[basep].insert(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstMethodCall* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (nodep->name() != "randomize") return;
|
||||
if (AstClassRefDType* classRefp = VN_CAST(nodep->fromp()->dtypep(), ClassRefDType)) {
|
||||
auto* classp = classRefp->classp();
|
||||
if (const AstClassRefDType* const classRefp
|
||||
= VN_CAST(nodep->fromp()->dtypep(), ClassRefDType)) {
|
||||
auto* const classp = classRefp->classp();
|
||||
classp->user1(true);
|
||||
markMembers(classp);
|
||||
}
|
||||
|
|
@ -129,13 +130,14 @@ private:
|
|||
AstVar* enumValueTabp(AstEnumDType* nodep) {
|
||||
if (nodep->user2p()) return VN_AS(nodep->user2p(), Var);
|
||||
UINFO(9, "Construct Venumvaltab " << nodep << endl);
|
||||
AstNodeArrayDType* vardtypep
|
||||
AstNodeArrayDType* const vardtypep
|
||||
= new AstUnpackArrayDType(nodep->fileline(), nodep->dtypep(),
|
||||
new AstRange(nodep->fileline(), nodep->itemCount(), 0));
|
||||
AstInitArray* initp = new AstInitArray(nodep->fileline(), vardtypep, nullptr);
|
||||
AstInitArray* const initp = new AstInitArray(nodep->fileline(), vardtypep, nullptr);
|
||||
v3Global.rootp()->typeTablep()->addTypesp(vardtypep);
|
||||
AstVar* varp = new AstVar(nodep->fileline(), AstVarType::MODULETEMP,
|
||||
"__Venumvaltab_" + cvtToStr(m_enumValueTabCount++), vardtypep);
|
||||
AstVar* const varp
|
||||
= new AstVar(nodep->fileline(), AstVarType::MODULETEMP,
|
||||
"__Venumvaltab_" + cvtToStr(m_enumValueTabCount++), vardtypep);
|
||||
varp->isConst(true);
|
||||
varp->isStatic(true);
|
||||
varp->valuep(initp);
|
||||
|
|
@ -144,7 +146,7 @@ private:
|
|||
UASSERT_OBJ(nodep->itemsp(), nodep, "Enum without items");
|
||||
for (AstEnumItem* itemp = nodep->itemsp(); itemp;
|
||||
itemp = VN_AS(itemp->nextp(), EnumItem)) {
|
||||
AstConst* vconstp = VN_AS(itemp->valuep(), Const);
|
||||
AstConst* const vconstp = VN_AS(itemp->valuep(), Const);
|
||||
UASSERT_OBJ(vconstp, nodep, "Enum item without constified value");
|
||||
initp->addValuep(vconstp->cloneTree(false));
|
||||
}
|
||||
|
|
@ -153,15 +155,15 @@ private:
|
|||
}
|
||||
AstNodeStmt* newRandStmtsp(FileLine* fl, AstNodeVarRef* varrefp, int offset = 0,
|
||||
AstMemberDType* memberp = nullptr) {
|
||||
if (auto* structDtp
|
||||
if (const auto* const structDtp
|
||||
= VN_CAST(memberp ? memberp->subDTypep()->skipRefp() : varrefp->dtypep()->skipRefp(),
|
||||
StructDType)) {
|
||||
AstNodeStmt* stmtsp = nullptr;
|
||||
offset += memberp ? memberp->lsb() : 0;
|
||||
for (auto* smemberp = structDtp->membersp(); smemberp;
|
||||
smemberp = VN_AS(smemberp->nextp(), MemberDType)) {
|
||||
auto* randp = newRandStmtsp(fl, stmtsp ? varrefp->cloneTree(false) : varrefp,
|
||||
offset, smemberp);
|
||||
auto* const randp = newRandStmtsp(fl, stmtsp ? varrefp->cloneTree(false) : varrefp,
|
||||
offset, smemberp);
|
||||
if (stmtsp) {
|
||||
stmtsp->addNext(randp);
|
||||
} else {
|
||||
|
|
@ -171,13 +173,15 @@ private:
|
|||
return stmtsp;
|
||||
} else {
|
||||
AstNodeMath* valp;
|
||||
if (auto* enumDtp = VN_CAST(memberp ? memberp->subDTypep()->subDTypep()
|
||||
: varrefp->dtypep()->subDTypep(),
|
||||
EnumDType)) {
|
||||
AstVarRef* tabRefp = new AstVarRef(fl, enumValueTabp(enumDtp), VAccess::READ);
|
||||
if (auto* const enumDtp = VN_CAST(memberp ? memberp->subDTypep()->subDTypep()
|
||||
: varrefp->dtypep()->subDTypep(),
|
||||
EnumDType)) {
|
||||
AstVarRef* const tabRefp
|
||||
= new AstVarRef(fl, enumValueTabp(enumDtp), VAccess::READ);
|
||||
tabRefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgAddp());
|
||||
auto* randp = new AstRand(fl, nullptr, false);
|
||||
auto* moddivp = new AstModDiv(fl, randp, new AstConst(fl, enumDtp->itemCount()));
|
||||
auto* const randp = new AstRand(fl, nullptr, false);
|
||||
auto* const moddivp
|
||||
= new AstModDiv(fl, randp, new AstConst(fl, enumDtp->itemCount()));
|
||||
randp->dtypep(varrefp->findBasicDType(AstBasicDTypeKwd::UINT32));
|
||||
moddivp->dtypep(enumDtp);
|
||||
valp = new AstArraySel(fl, tabRefp, moddivp);
|
||||
|
|
@ -197,25 +201,28 @@ private:
|
|||
iterateChildren(nodep);
|
||||
if (!nodep->user1()) return; // Doesn't need randomize, or already processed
|
||||
UINFO(9, "Define randomize() for " << nodep << endl);
|
||||
auto* funcp = V3Randomize::newRandomizeFunc(nodep);
|
||||
auto* fvarp = VN_AS(funcp->fvarp(), Var);
|
||||
auto* const funcp = V3Randomize::newRandomizeFunc(nodep);
|
||||
auto* const fvarp = VN_AS(funcp->fvarp(), Var);
|
||||
funcp->addStmtsp(new AstAssign(
|
||||
nodep->fileline(), new AstVarRef(nodep->fileline(), fvarp, VAccess::WRITE),
|
||||
new AstConst(nodep->fileline(), AstConst::WidthedValue(), 32, 1)));
|
||||
for (auto* classp = nodep; classp;
|
||||
classp = classp->extendsp() ? classp->extendsp()->classp() : nullptr) {
|
||||
for (auto* memberp = classp->stmtsp(); memberp; memberp = memberp->nextp()) {
|
||||
auto* memberVarp = VN_CAST(memberp, Var);
|
||||
auto* const memberVarp = VN_CAST(memberp, Var);
|
||||
if (!memberVarp || !memberVarp->isRand()) continue;
|
||||
auto* dtypep = memberp->dtypep()->skipRefp();
|
||||
const auto* const dtypep = memberp->dtypep()->skipRefp();
|
||||
if (VN_IS(dtypep, BasicDType) || VN_IS(dtypep, StructDType)) {
|
||||
auto* refp = new AstVarRef(nodep->fileline(), memberVarp, VAccess::WRITE);
|
||||
auto* stmtp = newRandStmtsp(nodep->fileline(), refp);
|
||||
auto* const refp
|
||||
= new AstVarRef(nodep->fileline(), memberVarp, VAccess::WRITE);
|
||||
auto* const stmtp = newRandStmtsp(nodep->fileline(), refp);
|
||||
funcp->addStmtsp(stmtp);
|
||||
} else if (auto* classRefp = VN_CAST(dtypep, ClassRefDType)) {
|
||||
auto* refp = new AstVarRef(nodep->fileline(), memberVarp, VAccess::WRITE);
|
||||
auto* memberFuncp = V3Randomize::newRandomizeFunc(classRefp->classp());
|
||||
auto* callp = new AstMethodCall(nodep->fileline(), refp, "randomize", nullptr);
|
||||
auto* const refp
|
||||
= new AstVarRef(nodep->fileline(), memberVarp, VAccess::WRITE);
|
||||
auto* const memberFuncp = V3Randomize::newRandomizeFunc(classRefp->classp());
|
||||
auto* const callp
|
||||
= new AstMethodCall(nodep->fileline(), refp, "randomize", nullptr);
|
||||
callp->taskp(memberFuncp);
|
||||
callp->dtypeFrom(memberFuncp);
|
||||
funcp->addStmtsp(new AstAssign(
|
||||
|
|
@ -255,9 +262,9 @@ void V3Randomize::randomizeNetlist(AstNetlist* nodep) {
|
|||
AstFunc* V3Randomize::newRandomizeFunc(AstClass* nodep) {
|
||||
auto* funcp = VN_AS(nodep->findMember("randomize"), Func);
|
||||
if (!funcp) {
|
||||
auto* dtypep
|
||||
auto* const dtypep
|
||||
= nodep->findBitDType(32, 32, VSigning::SIGNED); // IEEE says int return of 0/1
|
||||
auto* fvarp = new AstVar(nodep->fileline(), AstVarType::MEMBER, "randomize", dtypep);
|
||||
auto* const fvarp = new AstVar(nodep->fileline(), AstVarType::MEMBER, "randomize", dtypep);
|
||||
fvarp->lifetime(VLifetime::AUTOMATIC);
|
||||
fvarp->funcLocal(true);
|
||||
fvarp->funcReturn(true);
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ private:
|
|||
return;
|
||||
}
|
||||
// Of a constant index
|
||||
AstConst* const lbitp = VN_CAST(lselp->bitp(), Const);
|
||||
const AstConst* const lbitp = VN_CAST(lselp->bitp(), Const);
|
||||
if (!lbitp) {
|
||||
mergeEnd();
|
||||
return;
|
||||
|
|
@ -192,7 +192,7 @@ private:
|
|||
uint32_t rindex = lindex;
|
||||
if (rconstp) { // Ok
|
||||
} else if (rselp) {
|
||||
AstConst* const rbitp = VN_CAST(rselp->bitp(), Const);
|
||||
const AstConst* const rbitp = VN_CAST(rselp->bitp(), Const);
|
||||
rvarrefp = VN_CAST(rselp->fromp(), NodeVarRef);
|
||||
if (!rbitp || !rvarrefp || lvarrefp->varp() == rvarrefp->varp()) {
|
||||
mergeEnd();
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ private:
|
|||
|
||||
void cleanupVarRefs() {
|
||||
for (const auto& itr : m_varRefScopes) {
|
||||
AstVarRef* nodep = itr.first;
|
||||
AstVarRef* const nodep = itr.first;
|
||||
AstScope* scopep = itr.second;
|
||||
if (nodep->classOrPackagep()) {
|
||||
const auto it2 = m_packageScopes.find(nodep->classOrPackagep());
|
||||
|
|
@ -74,14 +74,14 @@ private:
|
|||
}
|
||||
const auto it3 = m_varScopes.find(std::make_pair(nodep->varp(), scopep));
|
||||
UASSERT_OBJ(it3 != m_varScopes.end(), nodep, "Can't locate varref scope");
|
||||
AstVarScope* varscp = it3->second;
|
||||
AstVarScope* const varscp = it3->second;
|
||||
nodep->varScopep(varscp);
|
||||
}
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep) override {
|
||||
AstNodeModule* modp = nodep->topModulep();
|
||||
AstNodeModule* const modp = nodep->topModulep();
|
||||
if (!modp) {
|
||||
nodep->v3error("No top level module found");
|
||||
return;
|
||||
|
|
@ -112,7 +112,7 @@ private:
|
|||
|
||||
// Now for each child cell, iterate the module this cell points to
|
||||
for (AstNode* cellnextp = nodep->stmtsp(); cellnextp; cellnextp = cellnextp->nextp()) {
|
||||
if (AstCell* cellp = VN_CAST(cellnextp, Cell)) {
|
||||
if (AstCell* const cellp = VN_CAST(cellnextp, Cell)) {
|
||||
VL_RESTORER(m_scopep); // Protects m_scopep set in called module
|
||||
// which is "above" in this code, but later in code execution order
|
||||
VL_RESTORER(m_aboveCellp);
|
||||
|
|
@ -120,7 +120,7 @@ private:
|
|||
{
|
||||
m_aboveCellp = cellp;
|
||||
m_aboveScopep = m_scopep;
|
||||
AstNodeModule* modp = cellp->modp();
|
||||
AstNodeModule* const modp = cellp->modp();
|
||||
UASSERT_OBJ(modp, cellp, "Unlinked mod");
|
||||
iterate(modp); // Recursive call to visit(AstNodeModule)
|
||||
}
|
||||
|
|
@ -163,8 +163,8 @@ private:
|
|||
UINFO(4, " CLASS AT " << scopename << " " << nodep << endl);
|
||||
AstNode::user1ClearTree();
|
||||
|
||||
AstNode* abovep = (m_aboveCellp ? static_cast<AstNode*>(m_aboveCellp)
|
||||
: static_cast<AstNode*>(nodep));
|
||||
const AstNode* const abovep = (m_aboveCellp ? static_cast<AstNode*>(m_aboveCellp)
|
||||
: static_cast<AstNode*>(nodep));
|
||||
m_scopep
|
||||
= new AstScope(abovep->fileline(), m_modp, scopename, m_aboveScopep, m_aboveCellp);
|
||||
m_packageScopes.emplace(nodep, m_scopep);
|
||||
|
|
@ -185,7 +185,7 @@ private:
|
|||
virtual void visit(AstNodeProcedure* nodep) override {
|
||||
// Add to list of blocks under this scope
|
||||
UINFO(4, " Move " << nodep << endl);
|
||||
AstNode* clonep = nodep->cloneTree(false);
|
||||
AstNode* const clonep = nodep->cloneTree(false);
|
||||
nodep->user2p(clonep);
|
||||
m_scopep->addActivep(clonep);
|
||||
iterateChildren(clonep); // We iterate under the *clone*
|
||||
|
|
@ -193,7 +193,7 @@ private:
|
|||
virtual void visit(AstAssignAlias* nodep) override {
|
||||
// Add to list of blocks under this scope
|
||||
UINFO(4, " Move " << nodep << endl);
|
||||
AstNode* clonep = nodep->cloneTree(false);
|
||||
AstNode* const clonep = nodep->cloneTree(false);
|
||||
nodep->user2p(clonep);
|
||||
m_scopep->addActivep(clonep);
|
||||
iterateChildren(clonep); // We iterate under the *clone*
|
||||
|
|
@ -201,7 +201,7 @@ private:
|
|||
virtual void visit(AstAssignVarScope* nodep) override {
|
||||
// Copy under the scope but don't recurse
|
||||
UINFO(4, " Move " << nodep << endl);
|
||||
AstNode* clonep = nodep->cloneTree(false);
|
||||
AstNode* const clonep = nodep->cloneTree(false);
|
||||
nodep->user2p(clonep);
|
||||
m_scopep->addActivep(clonep);
|
||||
iterateChildren(clonep); // We iterate under the *clone*
|
||||
|
|
@ -209,7 +209,7 @@ private:
|
|||
virtual void visit(AstAssignW* nodep) override {
|
||||
// Add to list of blocks under this scope
|
||||
UINFO(4, " Move " << nodep << endl);
|
||||
AstNode* clonep = nodep->cloneTree(false);
|
||||
AstNode* const clonep = nodep->cloneTree(false);
|
||||
nodep->user2p(clonep);
|
||||
m_scopep->addActivep(clonep);
|
||||
iterateChildren(clonep); // We iterate under the *clone*
|
||||
|
|
@ -217,7 +217,7 @@ private:
|
|||
virtual void visit(AstAlwaysPublic* nodep) override {
|
||||
// Add to list of blocks under this scope
|
||||
UINFO(4, " Move " << nodep << endl);
|
||||
AstNode* clonep = nodep->cloneTree(false);
|
||||
AstNode* const clonep = nodep->cloneTree(false);
|
||||
nodep->user2p(clonep);
|
||||
m_scopep->addActivep(clonep);
|
||||
iterateChildren(clonep); // We iterate under the *clone*
|
||||
|
|
@ -225,7 +225,7 @@ private:
|
|||
virtual void visit(AstCoverToggle* nodep) override {
|
||||
// Add to list of blocks under this scope
|
||||
UINFO(4, " Move " << nodep << endl);
|
||||
AstNode* clonep = nodep->cloneTree(false);
|
||||
AstNode* const clonep = nodep->cloneTree(false);
|
||||
nodep->user2p(clonep);
|
||||
m_scopep->addActivep(clonep);
|
||||
iterateChildren(clonep); // We iterate under the *clone*
|
||||
|
|
@ -233,7 +233,7 @@ private:
|
|||
virtual void visit(AstCFunc* nodep) override {
|
||||
// Add to list of blocks under this scope
|
||||
UINFO(4, " CFUNC " << nodep << endl);
|
||||
AstCFunc* clonep = nodep->cloneTree(false);
|
||||
AstCFunc* const clonep = nodep->cloneTree(false);
|
||||
nodep->user2p(clonep);
|
||||
m_scopep->addActivep(clonep);
|
||||
clonep->scopep(m_scopep);
|
||||
|
|
@ -259,7 +259,7 @@ private:
|
|||
virtual void visit(AstVar* nodep) override {
|
||||
// Make new scope variable
|
||||
if (!nodep->user1p()) {
|
||||
AstVarScope* varscp = new AstVarScope(nodep->fileline(), m_scopep, nodep);
|
||||
AstVarScope* const varscp = new AstVarScope(nodep->fileline(), m_scopep, nodep);
|
||||
UINFO(6, " New scope " << varscp << endl);
|
||||
if (m_aboveCellp && !m_aboveCellp->isTrace()) varscp->trace(false);
|
||||
nodep->user1p(varscp);
|
||||
|
|
@ -369,7 +369,7 @@ private:
|
|||
if (nodep->classOrPackagep()) {
|
||||
// Point to the clone
|
||||
UASSERT_OBJ(nodep->taskp(), nodep, "Unlinked");
|
||||
AstNodeFTask* newp = VN_AS(nodep->taskp()->user2p(), NodeFTask);
|
||||
AstNodeFTask* const newp = VN_AS(nodep->taskp()->user2p(), NodeFTask);
|
||||
UASSERT_OBJ(newp, nodep, "No clone for package function");
|
||||
nodep->taskp(newp);
|
||||
UINFO(9, " New pkg-taskref " << nodep << endl);
|
||||
|
|
|
|||
|
|
@ -61,7 +61,8 @@ class SliceVisitor final : public AstNVisitor {
|
|||
|
||||
AstNode* cloneAndSel(AstNode* nodep, int elements, int offset) {
|
||||
// Insert an ArraySel, except for a few special cases
|
||||
AstUnpackArrayDType* arrayp = VN_CAST(nodep->dtypep()->skipRefp(), UnpackArrayDType);
|
||||
const AstUnpackArrayDType* const arrayp
|
||||
= VN_CAST(nodep->dtypep()->skipRefp(), UnpackArrayDType);
|
||||
if (!arrayp) { // V3Width should have complained, but...
|
||||
if (!m_assignError) {
|
||||
nodep->v3error(
|
||||
|
|
@ -84,7 +85,7 @@ class SliceVisitor final : public AstNVisitor {
|
|||
offset = 0;
|
||||
}
|
||||
AstNode* newp;
|
||||
if (AstInitArray* initp = VN_CAST(nodep, InitArray)) {
|
||||
if (const AstInitArray* const initp = VN_CAST(nodep, InitArray)) {
|
||||
UINFO(9, " cloneInitArray(" << elements << "," << offset << ") " << nodep << endl);
|
||||
const int leOffset = !arrayp->rangep()->littleEndian()
|
||||
? arrayp->rangep()->elementsConst() - 1 - offset
|
||||
|
|
@ -132,17 +133,17 @@ class SliceVisitor final : public AstNVisitor {
|
|||
nodep->user1(true);
|
||||
m_assignError = false;
|
||||
if (debug() >= 9) nodep->dumpTree(cout, " Deslice-In: ");
|
||||
AstNodeDType* dtp = nodep->lhsp()->dtypep()->skipRefp();
|
||||
if (AstUnpackArrayDType* arrayp = VN_CAST(dtp, UnpackArrayDType)) {
|
||||
AstNodeDType* const dtp = nodep->lhsp()->dtypep()->skipRefp();
|
||||
if (const AstUnpackArrayDType* const arrayp = VN_CAST(dtp, UnpackArrayDType)) {
|
||||
// Left and right could have different msb/lsbs/endianness, but #elements is common
|
||||
// and all variables are realigned to start at zero
|
||||
// Assign of a little endian'ed slice to a big endian one must reverse the elements
|
||||
AstNode* newlistp = nullptr;
|
||||
const int elements = arrayp->rangep()->elementsConst();
|
||||
for (int offset = 0; offset < elements; ++offset) {
|
||||
AstNode* newp = nodep->cloneType // AstNodeAssign
|
||||
(cloneAndSel(nodep->lhsp(), elements, offset),
|
||||
cloneAndSel(nodep->rhsp(), elements, offset));
|
||||
AstNode* const newp = nodep->cloneType // AstNodeAssign
|
||||
(cloneAndSel(nodep->lhsp(), elements, offset),
|
||||
cloneAndSel(nodep->rhsp(), elements, offset));
|
||||
if (debug() >= 9) newp->dumpTree(cout, "-new ");
|
||||
newlistp = AstNode::addNextNull(newlistp, newp);
|
||||
}
|
||||
|
|
@ -167,9 +168,9 @@ class SliceVisitor final : public AstNVisitor {
|
|||
if (!nodep->user1()) {
|
||||
nodep->user1(true);
|
||||
// If it's an unpacked array, blow it up into comparing each element
|
||||
AstNodeDType* fromDtp = nodep->lhsp()->dtypep()->skipRefp();
|
||||
AstNodeDType* const fromDtp = nodep->lhsp()->dtypep()->skipRefp();
|
||||
UINFO(9, " Bi-Eq/Neq expansion " << nodep << endl);
|
||||
if (AstUnpackArrayDType* adtypep = VN_CAST(fromDtp, UnpackArrayDType)) {
|
||||
if (const AstUnpackArrayDType* const adtypep = VN_CAST(fromDtp, UnpackArrayDType)) {
|
||||
AstNodeBiop* logp = nullptr;
|
||||
if (!VN_IS(nodep->lhsp()->dtypep()->skipRefp(), NodeArrayDType)) {
|
||||
nodep->lhsp()->v3error(
|
||||
|
|
@ -184,7 +185,7 @@ class SliceVisitor final : public AstNVisitor {
|
|||
} else {
|
||||
for (int index = 0; index < adtypep->rangep()->elementsConst(); ++index) {
|
||||
// EQ(a,b) -> LOGAND(EQ(ARRAYSEL(a,0), ARRAYSEL(b,0)), ...[1])
|
||||
AstNodeBiop* clonep
|
||||
AstNodeBiop* const clonep
|
||||
= VN_AS(nodep->cloneType(
|
||||
new AstArraySel(nodep->fileline(),
|
||||
nodep->lhsp()->cloneTree(false), index),
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@
|
|||
// Support classes
|
||||
|
||||
class SplitNodeVertex VL_NOT_FINAL : public V3GraphVertex {
|
||||
AstNode* m_nodep;
|
||||
AstNode* const m_nodep;
|
||||
|
||||
protected:
|
||||
SplitNodeVertex(V3Graph* graphp, AstNode* nodep)
|
||||
|
|
@ -169,13 +169,13 @@ public:
|
|||
void setIgnoreThisStep() { m_ignoreInStep = s_stepNum; }
|
||||
virtual bool followScoreboard() const = 0;
|
||||
static bool followScoreboard(const V3GraphEdge* edgep) {
|
||||
const SplitEdge* oedgep = dynamic_cast<const SplitEdge*>(edgep);
|
||||
const SplitEdge* const oedgep = dynamic_cast<const SplitEdge*>(edgep);
|
||||
if (!oedgep) v3fatalSrc("Following edge of non-SplitEdge type");
|
||||
if (oedgep->ignoreThisStep()) return false;
|
||||
return oedgep->followScoreboard();
|
||||
}
|
||||
static bool followCyclic(const V3GraphEdge* edgep) {
|
||||
const SplitEdge* oedgep = dynamic_cast<const SplitEdge*>(edgep);
|
||||
const SplitEdge* const oedgep = dynamic_cast<const SplitEdge*>(edgep);
|
||||
if (!oedgep) v3fatalSrc("Following edge of non-SplitEdge type");
|
||||
return (!oedgep->ignoreThisStep());
|
||||
}
|
||||
|
|
@ -296,7 +296,7 @@ private:
|
|||
}
|
||||
void scoreboardPushStmt(AstNode* nodep) {
|
||||
// UINFO(9, " push " << nodep << endl);
|
||||
SplitLogicVertex* vertexp = new SplitLogicVertex(&m_graph, nodep);
|
||||
SplitLogicVertex* const vertexp = new SplitLogicVertex(&m_graph, nodep);
|
||||
m_stmtStackps.push_back(vertexp);
|
||||
UASSERT_OBJ(!nodep->user3p(), nodep, "user3p should not be used; cleared in processBlock");
|
||||
nodep->user3p(vertexp);
|
||||
|
|
@ -322,12 +322,12 @@ protected:
|
|||
vertexp = vertexp->verticesNextp()) {
|
||||
if (!vertexp->outBeginp() && dynamic_cast<SplitVarStdVertex*>(vertexp)) {
|
||||
if (debug() >= 9) {
|
||||
SplitVarStdVertex* stdp = static_cast<SplitVarStdVertex*>(vertexp);
|
||||
SplitVarStdVertex* const stdp = static_cast<SplitVarStdVertex*>(vertexp);
|
||||
UINFO(0, "Will prune deps on var " << stdp->nodep() << endl);
|
||||
stdp->nodep()->dumpTree(cout, "- ");
|
||||
}
|
||||
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
SplitEdge* oedgep = dynamic_cast<SplitEdge*>(edgep);
|
||||
SplitEdge* const oedgep = dynamic_cast<SplitEdge*>(edgep);
|
||||
oedgep->setIgnoreThisStep();
|
||||
}
|
||||
}
|
||||
|
|
@ -351,7 +351,7 @@ protected:
|
|||
}
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
if (!m_stmtStackps.empty()) {
|
||||
AstVarScope* vscp = nodep->varScopep();
|
||||
AstVarScope* const vscp = nodep->varScopep();
|
||||
UASSERT_OBJ(vscp, nodep, "Not linked");
|
||||
if (!nodep->varp()->isConst()) { // Constant lookups can be ignored
|
||||
// ---
|
||||
|
|
@ -374,21 +374,22 @@ protected:
|
|||
|
||||
// Create vertexes for variable
|
||||
if (!vscp->user1p()) {
|
||||
SplitVarStdVertex* vstdp = new SplitVarStdVertex(&m_graph, vscp);
|
||||
SplitVarStdVertex* const vstdp = new SplitVarStdVertex(&m_graph, vscp);
|
||||
vscp->user1p(vstdp);
|
||||
}
|
||||
SplitVarStdVertex* vstdp = reinterpret_cast<SplitVarStdVertex*>(vscp->user1p());
|
||||
SplitVarStdVertex* const vstdp
|
||||
= reinterpret_cast<SplitVarStdVertex*>(vscp->user1p());
|
||||
|
||||
// SPEEDUP: We add duplicate edges, that should be fixed
|
||||
if (m_inDly && nodep->access().isWriteOrRW()) {
|
||||
UINFO(4, " VARREFDLY: " << nodep << endl);
|
||||
// Delayed variable is different from non-delayed variable
|
||||
if (!vscp->user2p()) {
|
||||
SplitVarPostVertex* vpostp = new SplitVarPostVertex(&m_graph, vscp);
|
||||
SplitVarPostVertex* const vpostp = new SplitVarPostVertex(&m_graph, vscp);
|
||||
vscp->user2p(vpostp);
|
||||
new SplitPostEdge(&m_graph, vstdp, vpostp);
|
||||
}
|
||||
SplitVarPostVertex* vpostp
|
||||
SplitVarPostVertex* const vpostp
|
||||
= reinterpret_cast<SplitVarPostVertex*>(vscp->user2p());
|
||||
// Add edges
|
||||
for (SplitLogicVertex* vxp : m_stmtStackps) {
|
||||
|
|
@ -462,7 +463,8 @@ protected:
|
|||
// Vertex::m_user begin: true indicates logic for this step
|
||||
m_graph.userClearVertices();
|
||||
for (AstNode* nextp = nodep; nextp; nextp = nextp->nextp()) {
|
||||
SplitLogicVertex* vvertexp = reinterpret_cast<SplitLogicVertex*>(nextp->user3p());
|
||||
SplitLogicVertex* const vvertexp
|
||||
= reinterpret_cast<SplitLogicVertex*>(nextp->user3p());
|
||||
vvertexp->user(true);
|
||||
}
|
||||
|
||||
|
|
@ -475,16 +477,16 @@ protected:
|
|||
// vertexes not involved with this step as unimportant
|
||||
for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp;
|
||||
vertexp = vertexp->verticesNextp()) {
|
||||
if (SplitLogicVertex* vvertexp = dynamic_cast<SplitLogicVertex*>(vertexp)) {
|
||||
if (SplitLogicVertex* const vvertexp = dynamic_cast<SplitLogicVertex*>(vertexp)) {
|
||||
if (!vvertexp->user()) {
|
||||
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep;
|
||||
edgep = edgep->inNextp()) {
|
||||
SplitEdge* oedgep = dynamic_cast<SplitEdge*>(edgep);
|
||||
SplitEdge* const oedgep = dynamic_cast<SplitEdge*>(edgep);
|
||||
oedgep->setIgnoreThisStep();
|
||||
}
|
||||
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep;
|
||||
edgep = edgep->outNextp()) {
|
||||
SplitEdge* oedgep = dynamic_cast<SplitEdge*>(edgep);
|
||||
SplitEdge* const oedgep = dynamic_cast<SplitEdge*>(edgep);
|
||||
oedgep->setIgnoreThisStep();
|
||||
}
|
||||
}
|
||||
|
|
@ -498,7 +500,8 @@ protected:
|
|||
// Add hard orderings between all nodes of same color, in the order they appeared
|
||||
std::unordered_map<uint32_t, SplitLogicVertex*> lastOfColor;
|
||||
for (AstNode* nextp = nodep; nextp; nextp = nextp->nextp()) {
|
||||
SplitLogicVertex* vvertexp = reinterpret_cast<SplitLogicVertex*>(nextp->user3p());
|
||||
SplitLogicVertex* const vvertexp
|
||||
= reinterpret_cast<SplitLogicVertex*>(nextp->user3p());
|
||||
uint32_t color = vvertexp->color();
|
||||
UASSERT_OBJ(color, nextp, "No node color assigned");
|
||||
if (lastOfColor[color]) {
|
||||
|
|
@ -523,7 +526,8 @@ protected:
|
|||
std::multimap<uint32_t, AstNode*> rankMap;
|
||||
int currOrder = 0; // Existing sequence number of assignment
|
||||
for (AstNode* nextp = nodep; nextp; nextp = nextp->nextp()) {
|
||||
SplitLogicVertex* vvertexp = reinterpret_cast<SplitLogicVertex*>(nextp->user3p());
|
||||
SplitLogicVertex* const vvertexp
|
||||
= reinterpret_cast<SplitLogicVertex*>(nextp->user3p());
|
||||
rankMap.emplace(vvertexp->rank(), nextp);
|
||||
nextp->user4(++currOrder); // Record current ordering
|
||||
}
|
||||
|
|
@ -532,7 +536,7 @@ protected:
|
|||
bool leaveAlone = true;
|
||||
int newOrder = 0; // New sequence number of assignment
|
||||
for (auto it = rankMap.cbegin(); it != rankMap.cend(); ++it) {
|
||||
AstNode* nextp = it->second;
|
||||
AstNode* const nextp = it->second;
|
||||
if (++newOrder != nextp->user4()) leaveAlone = false;
|
||||
}
|
||||
if (leaveAlone) {
|
||||
|
|
@ -541,7 +545,7 @@ protected:
|
|||
AstNRelinker replaceHandle; // Where to add the list
|
||||
AstNode* newListp = nullptr;
|
||||
for (auto it = rankMap.cbegin(); it != rankMap.cend(); ++it) {
|
||||
AstNode* nextp = it->second;
|
||||
AstNode* const nextp = it->second;
|
||||
UINFO(6, " New order: " << nextp << endl);
|
||||
if (nextp == nodep) {
|
||||
nodep->unlinkFrBack(&replaceHandle);
|
||||
|
|
@ -564,7 +568,7 @@ protected:
|
|||
// Check there's >= 2 sub statements, else nothing to analyze
|
||||
// Save recursion state
|
||||
AstNode* firstp = nodep; // We may reorder, and nodep is no longer first.
|
||||
void* oldBlockUser3 = nodep->user3p(); // May be overloaded in below loop, save it
|
||||
void* const oldBlockUser3 = nodep->user3p(); // May be overloaded in below loop, save it
|
||||
nodep->user3p(nullptr);
|
||||
UASSERT_OBJ(nodep->firstAbovep(), nodep,
|
||||
"Node passed is in next list; should have processed all list at once");
|
||||
|
|
@ -586,7 +590,7 @@ protected:
|
|||
// First, walk back to first in list
|
||||
while (firstp->backp()->nextp() == firstp) firstp = firstp->backp();
|
||||
for (AstNode* nextp = firstp; nextp; nextp = nextp->nextp()) {
|
||||
SplitLogicVertex* vvertexp
|
||||
SplitLogicVertex* const vvertexp
|
||||
= reinterpret_cast<SplitLogicVertex*>(nextp->user3p());
|
||||
vvertexp->unlinkDelete(&m_graph);
|
||||
}
|
||||
|
|
@ -646,7 +650,7 @@ public:
|
|||
private:
|
||||
void trackNode(AstNode* nodep) {
|
||||
if (nodep->user3p()) {
|
||||
SplitLogicVertex* vertexp = reinterpret_cast<SplitLogicVertex*>(nodep->user3p());
|
||||
SplitLogicVertex* const vertexp = reinterpret_cast<SplitLogicVertex*>(nodep->user3p());
|
||||
uint32_t color = vertexp->color();
|
||||
m_colors.insert(color);
|
||||
UINFO(8, " SVL " << vertexp << " has color " << color << "\n");
|
||||
|
|
@ -677,13 +681,13 @@ private:
|
|||
|
||||
class EmitSplitVisitor final : public AstNVisitor {
|
||||
// MEMBERS
|
||||
AstAlways* m_origAlwaysp; // Block that *this will split
|
||||
const IfColorVisitor* m_ifColorp; // Digest of results of prior coloring
|
||||
AstAlways* const m_origAlwaysp; // Block that *this will split
|
||||
const IfColorVisitor* const m_ifColorp; // Digest of results of prior coloring
|
||||
|
||||
// Map each color to our current place within the color's new always
|
||||
std::unordered_map<uint32_t, AstNode*> m_addAfter;
|
||||
|
||||
AlwaysVec* m_newBlocksp; // Split always blocks we have generated
|
||||
AlwaysVec* const m_newBlocksp; // Split always blocks we have generated
|
||||
|
||||
// CONSTRUCTORS
|
||||
public:
|
||||
|
|
@ -706,11 +710,11 @@ public:
|
|||
for (unsigned int color : colors) {
|
||||
// We don't need to clone m_origAlwaysp->sensesp() here;
|
||||
// V3Activate already moved it to a parent node.
|
||||
AstAlways* alwaysp
|
||||
AstAlways* const alwaysp
|
||||
= new AstAlways(m_origAlwaysp->fileline(), VAlwaysKwd::ALWAYS, nullptr, nullptr);
|
||||
// Put a placeholder node into stmtp to track our position.
|
||||
// We'll strip these out after the blocks are fully cloned.
|
||||
AstSplitPlaceholder* placeholderp = makePlaceholderp();
|
||||
AstSplitPlaceholder* const placeholderp = makePlaceholderp();
|
||||
alwaysp->addStmtp(placeholderp);
|
||||
m_addAfter[color] = placeholderp;
|
||||
m_newBlocksp->push_back(alwaysp);
|
||||
|
|
@ -743,9 +747,9 @@ protected:
|
|||
UASSERT_OBJ(nodep->user3p(), nodep, "null user3p in V3Split leaf");
|
||||
|
||||
// Clone the leaf into its new always block
|
||||
SplitLogicVertex* vxp = reinterpret_cast<SplitLogicVertex*>(nodep->user3p());
|
||||
SplitLogicVertex* const vxp = reinterpret_cast<SplitLogicVertex*>(nodep->user3p());
|
||||
uint32_t color = vxp->color();
|
||||
AstNode* clonedp = nodep->cloneTree(false);
|
||||
AstNode* const clonedp = nodep->cloneTree(false);
|
||||
m_addAfter[color]->addNextHere(clonedp);
|
||||
m_addAfter[color] = clonedp;
|
||||
}
|
||||
|
|
@ -757,11 +761,11 @@ protected:
|
|||
|
||||
for (unsigned int color : colors) {
|
||||
// Clone this if into its set of split blocks
|
||||
AstSplitPlaceholder* if_placeholderp = makePlaceholderp();
|
||||
AstSplitPlaceholder* else_placeholderp = makePlaceholderp();
|
||||
AstIf* clonep = new AstIf(nodep->fileline(), nodep->condp()->cloneTree(true),
|
||||
if_placeholderp, else_placeholderp);
|
||||
AstIf* origp = VN_CAST(nodep, If);
|
||||
AstSplitPlaceholder* const if_placeholderp = makePlaceholderp();
|
||||
AstSplitPlaceholder* const else_placeholderp = makePlaceholderp();
|
||||
AstIf* const clonep = new AstIf(nodep->fileline(), nodep->condp()->cloneTree(true),
|
||||
if_placeholderp, else_placeholderp);
|
||||
AstIf* const origp = VN_CAST(nodep, If);
|
||||
if (origp) {
|
||||
// Preserve pragmas from unique if's
|
||||
// so assertions work properly
|
||||
|
|
@ -824,7 +828,7 @@ public:
|
|||
// from newly-split blocks. Delete the original always blocks
|
||||
// that we're replacing.
|
||||
for (auto it = m_replaceBlocks.begin(); it != m_replaceBlocks.end(); ++it) {
|
||||
AstAlways* origp = it->first;
|
||||
AstAlways* const origp = it->first;
|
||||
for (AlwaysVec::iterator addme = it->second.begin(); addme != it->second.end();
|
||||
++addme) {
|
||||
origp->addNextHere(*addme);
|
||||
|
|
@ -843,7 +847,7 @@ protected:
|
|||
// Each 'if' depends on rvalues in its own conditional ONLY,
|
||||
// not rvalues in the if/else bodies.
|
||||
for (auto it = m_stmtStackps.cbegin(); it != m_stmtStackps.cend(); ++it) {
|
||||
AstNodeIf* ifNodep = VN_CAST((*it)->nodep(), NodeIf);
|
||||
AstNodeIf* const ifNodep = VN_CAST((*it)->nodep(), NodeIf);
|
||||
if (ifNodep && (m_curIfConditional != ifNodep)) continue;
|
||||
new SplitRVEdge(&m_graph, *it, vstdp);
|
||||
}
|
||||
|
|
@ -867,15 +871,15 @@ protected:
|
|||
// inputs) prune all edges that depend on the 'if'.
|
||||
for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp;
|
||||
vertexp = vertexp->verticesNextp()) {
|
||||
SplitLogicVertex* logicp = dynamic_cast<SplitLogicVertex*>(vertexp);
|
||||
SplitLogicVertex* const logicp = dynamic_cast<SplitLogicVertex*>(vertexp);
|
||||
if (!logicp) continue;
|
||||
|
||||
AstNodeIf* ifNodep = VN_CAST(logicp->nodep(), NodeIf);
|
||||
AstNodeIf* const ifNodep = VN_CAST(logicp->nodep(), NodeIf);
|
||||
if (!ifNodep) continue;
|
||||
|
||||
bool pruneMe = true;
|
||||
for (V3GraphEdge* edgep = logicp->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||
SplitEdge* oedgep = dynamic_cast<SplitEdge*>(edgep);
|
||||
SplitEdge* const oedgep = dynamic_cast<SplitEdge*>(edgep);
|
||||
if (!oedgep->ignoreThisStep()) {
|
||||
// This if conditional depends on something we can't
|
||||
// prune -- a variable generated in the current block.
|
||||
|
|
@ -885,7 +889,7 @@ protected:
|
|||
// give a hint about why...
|
||||
if (debug() >= 9) {
|
||||
V3GraphVertex* vxp = oedgep->top();
|
||||
SplitNodeVertex* nvxp = dynamic_cast<SplitNodeVertex*>(vxp);
|
||||
SplitNodeVertex* const nvxp = dynamic_cast<SplitNodeVertex*>(vxp);
|
||||
UINFO(0, "Cannot prune if-node due to edge "
|
||||
<< oedgep << " pointing to node " << nvxp->nodep() << endl);
|
||||
nvxp->nodep()->dumpTree(cout, "- ");
|
||||
|
|
@ -899,7 +903,7 @@ protected:
|
|||
|
||||
// This if can be split; prune dependencies on it.
|
||||
for (V3GraphEdge* edgep = logicp->inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
SplitEdge* oedgep = dynamic_cast<SplitEdge*>(edgep);
|
||||
SplitEdge* const oedgep = dynamic_cast<SplitEdge*>(edgep);
|
||||
oedgep->setIgnoreThisStep();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ public:
|
|||
class SplitAsCleanVisitor final : public SplitAsBaseVisitor {
|
||||
private:
|
||||
// STATE
|
||||
AstVarScope* m_splitVscp; // Variable we want to split
|
||||
AstVarScope* const m_splitVscp; // Variable we want to split
|
||||
bool m_modeMatch; // Remove matching Vscp, else non-matching
|
||||
bool m_keepStmt = false; // Current Statement must be preserved
|
||||
bool m_matches = false; // Statement below has matching lvalue reference
|
||||
|
|
@ -140,7 +140,7 @@ private:
|
|||
UINFO(3, " For " << m_splitVscp << endl);
|
||||
if (debug() >= 9) nodep->dumpTree(cout, "-in : ");
|
||||
// Duplicate it and link in
|
||||
AstAlways* newp = nodep->cloneTree(false);
|
||||
AstAlways* const newp = nodep->cloneTree(false);
|
||||
newp->user1(true); // So we don't clone it again
|
||||
nodep->addNextHere(newp);
|
||||
{ // Delete stuff we don't want in old
|
||||
|
|
@ -156,7 +156,7 @@ private:
|
|||
virtual void visit(AstAlways* nodep) override {
|
||||
// Are there any lvalue references below this?
|
||||
// There could be more than one. So, we process the first one found first.
|
||||
AstVarScope* lastSplitVscp = nullptr;
|
||||
const AstVarScope* lastSplitVscp = nullptr;
|
||||
while (!nodep->user1()) {
|
||||
// Find any splittable variables
|
||||
SplitAsFindVisitor visitor{nodep};
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ bool VString::isWhitespace(const string& str) {
|
|||
}
|
||||
|
||||
double VString::parseDouble(const string& str, bool* successp) {
|
||||
char* strgp = new char[str.size() + 1];
|
||||
char* const strgp = new char[str.size() + 1];
|
||||
char* dp = strgp;
|
||||
if (successp) *successp = true;
|
||||
for (const char* sp = str.c_str(); *sp; ++sp) {
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ protected:
|
|||
|
||||
class SubstVarEntry final {
|
||||
// MEMBERS
|
||||
AstVar* m_varp; // Variable this tracks
|
||||
AstVar* const m_varp; // Variable this tracks
|
||||
bool m_wordAssign = false; // True if any word assignments
|
||||
bool m_wordUse = false; // True if any individual word usage
|
||||
SubstVarWord m_whole; // Data for whole vector used at once
|
||||
|
|
@ -127,7 +127,7 @@ public:
|
|||
// ACCESSORS
|
||||
AstNode* substWhole(AstNode* errp) {
|
||||
if (!m_varp->isWide() && !m_whole.m_complex && m_whole.m_assignp && !m_wordAssign) {
|
||||
AstNodeAssign* assp = m_whole.m_assignp;
|
||||
const AstNodeAssign* const assp = m_whole.m_assignp;
|
||||
UASSERT_OBJ(assp, errp, "Reading whole that was never assigned");
|
||||
return (assp->rhsp());
|
||||
} else {
|
||||
|
|
@ -137,7 +137,7 @@ public:
|
|||
// Return what to substitute given word number for
|
||||
AstNode* substWord(AstNode* errp, int word) {
|
||||
if (!m_whole.m_complex && !m_whole.m_assignp && !m_words[word].m_complex) {
|
||||
AstNodeAssign* assp = getWordAssignp(word);
|
||||
const AstNodeAssign* const assp = getWordAssignp(word);
|
||||
UASSERT_OBJ(assp, errp, "Reading a word that was never assigned, or bad word #");
|
||||
return (assp->rhsp());
|
||||
} else {
|
||||
|
|
@ -189,7 +189,7 @@ private:
|
|||
}
|
||||
// VISITORS
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
SubstVarEntry* entryp = findEntryp(nodep);
|
||||
const SubstVarEntry* const entryp = findEntryp(nodep);
|
||||
if (entryp) {
|
||||
// Don't sweat it. We assign a new temp variable for every new assignment,
|
||||
// so there's no way we'd ever replace a old value.
|
||||
|
|
@ -244,12 +244,13 @@ private:
|
|||
// METHODS
|
||||
SubstVarEntry* getEntryp(AstVarRef* nodep) {
|
||||
if (!nodep->varp()->user1p()) {
|
||||
SubstVarEntry* entryp = new SubstVarEntry(nodep->varp());
|
||||
SubstVarEntry* const entryp = new SubstVarEntry(nodep->varp());
|
||||
m_entryps.push_back(entryp);
|
||||
nodep->varp()->user1p(entryp);
|
||||
return entryp;
|
||||
} else {
|
||||
SubstVarEntry* entryp = reinterpret_cast<SubstVarEntry*>(nodep->varp()->user1p());
|
||||
SubstVarEntry* const entryp
|
||||
= reinterpret_cast<SubstVarEntry*>(nodep->varp()->user1p());
|
||||
return entryp;
|
||||
}
|
||||
}
|
||||
|
|
@ -261,9 +262,9 @@ private:
|
|||
m_assignStep++;
|
||||
iterateAndNextNull(nodep->rhsp());
|
||||
bool hit = false;
|
||||
if (AstVarRef* varrefp = VN_CAST(nodep->lhsp(), VarRef)) {
|
||||
if (AstVarRef* const varrefp = VN_CAST(nodep->lhsp(), VarRef)) {
|
||||
if (isSubstVar(varrefp->varp())) {
|
||||
SubstVarEntry* entryp = getEntryp(varrefp);
|
||||
SubstVarEntry* const entryp = getEntryp(varrefp);
|
||||
hit = true;
|
||||
if (m_ops > SUBST_MAX_OPS_SUBST) {
|
||||
UINFO(8, " ASSIGNtooDeep " << varrefp << endl);
|
||||
|
|
@ -274,10 +275,10 @@ private:
|
|||
}
|
||||
}
|
||||
} else if (AstWordSel* wordp = VN_CAST(nodep->lhsp(), WordSel)) {
|
||||
if (AstVarRef* varrefp = VN_CAST(wordp->lhsp(), VarRef)) {
|
||||
if (AstVarRef* const varrefp = VN_CAST(wordp->lhsp(), VarRef)) {
|
||||
if (VN_IS(wordp->rhsp(), Const) && isSubstVar(varrefp->varp())) {
|
||||
const int word = VN_AS(wordp->rhsp(), Const)->toUInt();
|
||||
SubstVarEntry* entryp = getEntryp(varrefp);
|
||||
SubstVarEntry* const entryp = getEntryp(varrefp);
|
||||
hit = true;
|
||||
if (m_ops > SUBST_MAX_OPS_SUBST) {
|
||||
UINFO(8, " ASSIGNtooDeep " << varrefp << endl);
|
||||
|
|
@ -304,15 +305,15 @@ private:
|
|||
}
|
||||
virtual void visit(AstWordSel* nodep) override {
|
||||
iterate(nodep->rhsp());
|
||||
AstVarRef* varrefp = VN_CAST(nodep->lhsp(), VarRef);
|
||||
AstConst* constp = VN_CAST(nodep->rhsp(), Const);
|
||||
AstVarRef* const varrefp = VN_CAST(nodep->lhsp(), VarRef);
|
||||
const AstConst* const constp = VN_CAST(nodep->rhsp(), Const);
|
||||
if (varrefp && isSubstVar(varrefp->varp()) && varrefp->access().isReadOnly() && constp) {
|
||||
// Nicely formed lvalues handled in NodeAssign
|
||||
// Other lvalues handled as unknown mess in AstVarRef
|
||||
const int word = constp->toUInt();
|
||||
UINFO(8, " USEword" << word << " " << varrefp << endl);
|
||||
SubstVarEntry* entryp = getEntryp(varrefp);
|
||||
if (AstNode* substp = entryp->substWord(nodep, word)) {
|
||||
SubstVarEntry* const entryp = getEntryp(varrefp);
|
||||
if (AstNode* const substp = entryp->substWord(nodep, word)) {
|
||||
// Check that the RHS hasn't changed value since we recorded it.
|
||||
SubstUseVisitor visitor{substp, entryp->getWordStep(word)};
|
||||
if (visitor.ok()) {
|
||||
|
|
@ -335,7 +336,7 @@ private:
|
|||
UINFO(9, " ASSIGNstep u2=" << nodep->varp()->user2() << " " << nodep << endl);
|
||||
}
|
||||
if (isSubstVar(nodep->varp())) {
|
||||
SubstVarEntry* entryp = getEntryp(nodep);
|
||||
SubstVarEntry* const entryp = getEntryp(nodep);
|
||||
if (nodep->access().isWriteOrRW()) {
|
||||
UINFO(8, " ASSIGNcpx " << nodep << endl);
|
||||
entryp->assignComplex();
|
||||
|
|
|
|||
|
|
@ -95,8 +95,8 @@ public:
|
|||
// each non-directional edge:
|
||||
void addEdge(const T_Key& from, const T_Key& to, int cost) {
|
||||
UASSERT(from != to, "Adding edge would form a loop");
|
||||
Vertex* fp = findVertex(from);
|
||||
Vertex* tp = findVertex(to);
|
||||
Vertex* const fp = findVertex(from);
|
||||
Vertex* const tp = findVertex(to);
|
||||
|
||||
// No need to dedup edges.
|
||||
// The only time we may create duplicate edges is when
|
||||
|
|
@ -164,7 +164,7 @@ public:
|
|||
|
||||
// Choose an arbitrary start vertex and visit it;
|
||||
// all incident edges from this vertex go into a pending edge set.
|
||||
Vertex* start_vertexp = castVertexp(verticesBeginp());
|
||||
Vertex* const start_vertexp = castVertexp(verticesBeginp());
|
||||
visited_set.insert(start_vertexp);
|
||||
for (V3GraphEdge* edgep = start_vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||
pendingEdges.insert(edgep);
|
||||
|
|
@ -181,12 +181,12 @@ public:
|
|||
pendingEdges.erase(firstIt);
|
||||
|
||||
// bestEdgep->fromp() should be already seen
|
||||
Vertex* from_vertexp = castVertexp(bestEdgep->fromp());
|
||||
Vertex* const from_vertexp = castVertexp(bestEdgep->fromp());
|
||||
UASSERT(visited_set.find(from_vertexp) != visited_set.end(), "Can't find vertex");
|
||||
|
||||
// If the neighbor is not yet visited, visit it and add its edges
|
||||
// to the pending set.
|
||||
Vertex* neighborp = castVertexp(bestEdgep->top());
|
||||
Vertex* const neighborp = castVertexp(bestEdgep->top());
|
||||
if (visited_set.find(neighborp) == visited_set.end()) {
|
||||
const int bestCost = bestEdgep->weight();
|
||||
UINFO(6, "bestCost = " << bestCost << " from " << from_vertexp->key() << " to "
|
||||
|
|
@ -260,8 +260,8 @@ public:
|
|||
// haven't been matched yet, match them.
|
||||
for (typename PendingEdgeSet::iterator it = pendingEdges.begin(); it != pendingEdges.end();
|
||||
++it) {
|
||||
Vertex* fromp = castVertexp((*it)->fromp());
|
||||
Vertex* top = castVertexp((*it)->top());
|
||||
Vertex* const fromp = castVertexp((*it)->fromp());
|
||||
Vertex* const top = castVertexp((*it)->top());
|
||||
if ((unmatchedOdds.find(fromp) != unmatchedOdds.end())
|
||||
&& (unmatchedOdds.find(top) != unmatchedOdds.end())) {
|
||||
outp->addEdge(fromp->key(), top->key(), (*it)->weight());
|
||||
|
|
@ -275,9 +275,9 @@ public:
|
|||
void combineGraph(const TspGraphTmpl& g) {
|
||||
std::unordered_set<vluint32_t> edges_done;
|
||||
for (V3GraphVertex* vxp = g.verticesBeginp(); vxp; vxp = vxp->verticesNextp()) {
|
||||
Vertex* fromp = castVertexp(vxp);
|
||||
const Vertex* const fromp = castVertexp(vxp);
|
||||
for (V3GraphEdge* edgep = fromp->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||
Vertex* top = castVertexp(edgep->top());
|
||||
const Vertex* const top = castVertexp(edgep->top());
|
||||
if (edges_done.find(edgep->user()) == edges_done.end()) {
|
||||
addEdge(fromp->key(), top->key(), edgep->weight());
|
||||
edges_done.insert(edgep->user());
|
||||
|
|
@ -302,7 +302,7 @@ public:
|
|||
if (markedEdgesp->end() == markedEdgesp->find(edgeId)) {
|
||||
// This edge is not yet marked, so follow it.
|
||||
markedEdgesp->insert(edgeId);
|
||||
Vertex* neighborp = castVertexp(edgep->top());
|
||||
Vertex* const neighborp = castVertexp(edgep->top());
|
||||
UINFO(6, "following edge " << edgeId << " from " << cur_vertexp->key()
|
||||
<< " to " << neighborp->key() << endl);
|
||||
cur_vertexp = neighborp;
|
||||
|
|
@ -344,10 +344,10 @@ public:
|
|||
// UINFO(0) as controlled by caller
|
||||
os << "At " << nameComment << ", dumping graph. Keys:\n";
|
||||
for (V3GraphVertex* vxp = verticesBeginp(); vxp; vxp = vxp->verticesNextp()) {
|
||||
Vertex* tspvp = castVertexp(vxp);
|
||||
const Vertex* const tspvp = castVertexp(vxp);
|
||||
os << " " << tspvp->key() << '\n';
|
||||
for (V3GraphEdge* edgep = tspvp->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||
Vertex* neighborp = castVertexp(edgep->top());
|
||||
const Vertex* const neighborp = castVertexp(edgep->top());
|
||||
os << " has edge " << edgep->user() << " to " << neighborp->key() << '\n';
|
||||
}
|
||||
}
|
||||
|
|
@ -366,14 +366,14 @@ public:
|
|||
if (debug() >= 6) dumpDotFilePrefixed("findEulerTour");
|
||||
std::unordered_set<unsigned /*edgeID*/> markedEdges;
|
||||
// Pick a start node
|
||||
Vertex* start_vertexp = castVertexp(verticesBeginp());
|
||||
Vertex* const start_vertexp = castVertexp(verticesBeginp());
|
||||
findEulerTourRecurse(&markedEdges, start_vertexp, sortedOutp);
|
||||
}
|
||||
|
||||
std::vector<T_Key> getOddDegreeKeys() const {
|
||||
std::vector<T_Key> result;
|
||||
for (V3GraphVertex* vxp = verticesBeginp(); vxp; vxp = vxp->verticesNextp()) {
|
||||
Vertex* tspvp = castVertexp(vxp);
|
||||
const Vertex* const tspvp = castVertexp(vxp);
|
||||
vluint32_t degree = 0;
|
||||
for (V3GraphEdge* edgep = vxp->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||
degree++;
|
||||
|
|
@ -442,7 +442,7 @@ void V3TSP::tspSort(const V3TSP::StateVec& states, V3TSP::StateVec* resultp) {
|
|||
std::unordered_set<const TspStateBase*> seen;
|
||||
for (V3TSP::StateVec::iterator it = prelim_result.begin(); it != prelim_result.end();
|
||||
++it) {
|
||||
const TspStateBase* elemp = *it;
|
||||
const TspStateBase* const elemp = *it;
|
||||
if (seen.find(elemp) == seen.end()) {
|
||||
seen.insert(elemp);
|
||||
resultp->push_back(elemp);
|
||||
|
|
@ -460,8 +460,8 @@ void V3TSP::tspSort(const V3TSP::StateVec& states, V3TSP::StateVec* resultp) {
|
|||
unsigned max_cost = 0;
|
||||
unsigned max_cost_idx = 0;
|
||||
for (unsigned i = 0; i < resultp->size(); ++i) {
|
||||
const TspStateBase* ap = (*resultp)[i];
|
||||
const TspStateBase* bp
|
||||
const TspStateBase* const ap = (*resultp)[i];
|
||||
const TspStateBase* const bp
|
||||
= (i + 1 == resultp->size()) ? (*resultp)[0] : (*resultp)[i + 1];
|
||||
const unsigned cost = ap->cost(bp);
|
||||
if (cost > max_cost) {
|
||||
|
|
@ -560,7 +560,7 @@ void V3TSP::selfTestStates() {
|
|||
expect.push_back(&s5);
|
||||
if (VL_UNCOVERABLE(expect != result)) {
|
||||
for (V3TSP::StateVec::iterator it = result.begin(); it != result.end(); ++it) {
|
||||
const TspTestState* statep = dynamic_cast<const TspTestState*>(*it);
|
||||
const TspTestState* const statep = dynamic_cast<const TspTestState*>(*it);
|
||||
cout << statep->xpos() << " ";
|
||||
}
|
||||
cout << endl;
|
||||
|
|
@ -602,7 +602,7 @@ void V3TSP::selfTestStates() {
|
|||
|
||||
if (VL_UNCOVERABLE(expect != result)) {
|
||||
for (V3TSP::StateVec::iterator it = result.begin(); it != result.end(); ++it) {
|
||||
const TspTestState* statep = dynamic_cast<const TspTestState*>(*it);
|
||||
const TspTestState* const statep = dynamic_cast<const TspTestState*>(*it);
|
||||
cout << statep->xpos() << "," << statep->ypos() << " ";
|
||||
}
|
||||
cout << endl;
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class TableVisitor;
|
|||
|
||||
class TableSimulateVisitor final : public SimulateVisitor {
|
||||
// MEMBERS
|
||||
TableVisitor* m_cbthis; ///< Class for callback
|
||||
TableVisitor* const m_cbthis; ///< Class for callback
|
||||
|
||||
public:
|
||||
///< Call other-this function on all new var references
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public:
|
|||
|
||||
class TaskFTaskVertex final : public TaskBaseVertex {
|
||||
// Every task gets a vertex, and we link tasks together based on funcrefs.
|
||||
AstNodeFTask* m_nodep;
|
||||
AstNodeFTask* const m_nodep;
|
||||
AstCFunc* m_cFuncp = nullptr;
|
||||
|
||||
public:
|
||||
|
|
@ -118,7 +118,7 @@ private:
|
|||
public:
|
||||
// METHODS
|
||||
AstScope* getScope(AstNodeFTask* nodep) {
|
||||
AstScope* scopep = VN_AS(nodep->user3p(), Scope);
|
||||
AstScope* const scopep = VN_AS(nodep->user3p(), Scope);
|
||||
UASSERT_OBJ(scopep, nodep, "No scope for function");
|
||||
return scopep;
|
||||
}
|
||||
|
|
@ -128,7 +128,7 @@ public:
|
|||
return iter->second;
|
||||
}
|
||||
AstClass* getClassp(AstNodeFTask* nodep) {
|
||||
AstClass* classp = m_funcToClassMap[nodep];
|
||||
AstClass* const classp = m_funcToClassMap[nodep];
|
||||
UASSERT_OBJ(classp, nodep, "No class for ctor func");
|
||||
return classp;
|
||||
}
|
||||
|
|
@ -171,7 +171,7 @@ private:
|
|||
// However, to create variables, we need to track the scopes involved.
|
||||
// Find all var->varscope mappings, for later cleanup
|
||||
for (AstNode* stmtp = nodep->varsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (AstVarScope* vscp = VN_CAST(stmtp, VarScope)) {
|
||||
if (AstVarScope* const vscp = VN_CAST(stmtp, VarScope)) {
|
||||
if (vscp->varp()->isFuncLocal()) {
|
||||
UINFO(9, " funcvsc " << vscp << endl);
|
||||
m_varToScopeMap.insert(
|
||||
|
|
@ -181,7 +181,7 @@ private:
|
|||
}
|
||||
// Likewise, all FTask->scope mappings
|
||||
for (AstNode* stmtp = nodep->blocksp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (AstNodeFTask* taskp = VN_CAST(stmtp, NodeFTask)) taskp->user3p(nodep);
|
||||
if (AstNodeFTask* const taskp = VN_CAST(stmtp, NodeFTask)) taskp->user3p(nodep);
|
||||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
|
@ -248,7 +248,7 @@ private:
|
|||
}
|
||||
UASSERT_OBJ(m_ctorp, nodep, "class constructor missing"); // LinkDot always makes it
|
||||
for (AstInitial* initialp : m_initialps) {
|
||||
if (AstNode* newp = initialp->bodysp()) {
|
||||
if (AstNode* const newp = initialp->bodysp()) {
|
||||
newp->unlinkFrBackWithNext();
|
||||
if (!m_ctorp->stmtsp()) {
|
||||
m_ctorp->addStmtsp(newp);
|
||||
|
|
@ -300,7 +300,7 @@ private:
|
|||
if (nodep->varp()->user2p()) { // It's being converted to an alias.
|
||||
UINFO(9,
|
||||
" relinkVar " << cvtToHex(nodep->varp()->user2p()) << " " << nodep << endl);
|
||||
AstVarScope* newvscp = VN_AS(nodep->varp()->user2p(), VarScope);
|
||||
AstVarScope* const newvscp = VN_AS(nodep->varp()->user2p(), VarScope);
|
||||
UASSERT_OBJ(newvscp, nodep, "not linked");
|
||||
nodep->varScopep(newvscp);
|
||||
nodep->varp(nodep->varScopep()->varp());
|
||||
|
|
@ -327,7 +327,7 @@ struct TaskDpiUtils {
|
|||
static std::vector<std::pair<AstUnpackArrayDType*, int>>
|
||||
unpackDimsAndStrides(AstNodeDType* dtypep) {
|
||||
std::vector<std::pair<AstUnpackArrayDType*, int>> dimStrides;
|
||||
if (AstUnpackArrayDType* unpackp = VN_CAST(dtypep->skipRefp(), UnpackArrayDType)) {
|
||||
if (AstUnpackArrayDType* const unpackp = VN_CAST(dtypep->skipRefp(), UnpackArrayDType)) {
|
||||
const std::vector<AstUnpackArrayDType*> dims = unpackp->unpackDimensions();
|
||||
dimStrides.resize(dims.size(), {nullptr, 0});
|
||||
dimStrides.back() = {dims.back(), 1};
|
||||
|
|
@ -353,7 +353,7 @@ struct TaskDpiUtils {
|
|||
frstmt = "VL_SET_W_" + frSvType + "(" + cvtToStr(portp->width()) + ",";
|
||||
return true;
|
||||
} else {
|
||||
const AstNodeDType* dtypep = portp->dtypep()->skipRefp();
|
||||
const AstNodeDType* const dtypep = portp->dtypep()->skipRefp();
|
||||
frstmt = "VL_SET_" + string(dtypep->charIQWN()) + "_" + frSvType + "(";
|
||||
if (VN_IS(dtypep, UnpackArrayDType)) frstmt += "&";
|
||||
frstmt += frName;
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ public:
|
|||
};
|
||||
|
||||
class TraceCFuncVertex final : public V3GraphVertex {
|
||||
AstCFunc* m_nodep;
|
||||
AstCFunc* const m_nodep;
|
||||
|
||||
public:
|
||||
TraceCFuncVertex(V3Graph* graphp, AstCFunc* nodep)
|
||||
|
|
@ -134,7 +134,7 @@ public:
|
|||
};
|
||||
|
||||
class TraceVarVertex final : public V3GraphVertex {
|
||||
AstVarScope* m_nodep;
|
||||
AstVarScope* const m_nodep;
|
||||
|
||||
public:
|
||||
TraceVarVertex(V3Graph* graphp, AstVarScope* nodep)
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ public:
|
|||
// Graph support classes
|
||||
|
||||
class TristateVertex final : public V3GraphVertex {
|
||||
AstNode* m_nodep;
|
||||
AstNode* const m_nodep;
|
||||
bool m_isTristate = false; // Logic indicates a tristate
|
||||
bool m_feedsTri = false; // Propagates to a tristate node (on RHS)
|
||||
bool m_processed = false; // Tristating was cleaned up
|
||||
|
|
@ -90,7 +90,7 @@ public:
|
|||
virtual ~TristateVertex() override = default;
|
||||
// ACCESSORS
|
||||
AstNode* nodep() const { return m_nodep; }
|
||||
AstVar* varp() const { return VN_CAST(nodep(), Var); }
|
||||
const AstVar* varp() const { return VN_CAST(nodep(), Var); }
|
||||
virtual string name() const override {
|
||||
return ((isTristate() ? "tri\\n"
|
||||
: feedsTri() ? "feed\\n"
|
||||
|
|
@ -160,7 +160,7 @@ private:
|
|||
UINFO(9, " Mark tri " << level << " " << vtxp << endl);
|
||||
if (!vtxp->varp()) { // not a var where we stop the recursion
|
||||
for (V3GraphEdge* edgep = vtxp->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||
TristateVertex* vvertexp = dynamic_cast<TristateVertex*>(edgep->top());
|
||||
TristateVertex* const vvertexp = dynamic_cast<TristateVertex*>(edgep->top());
|
||||
// Doesn't hurt to not check if already set, but by doing so when we
|
||||
// print out the debug messages, we'll see this node at level 0 instead.
|
||||
if (!vvertexp->isTristate()) {
|
||||
|
|
@ -172,8 +172,8 @@ private:
|
|||
// A variable is tristated. Find all of the LHS VARREFs that
|
||||
// drive this signal now need tristate drivers
|
||||
for (V3GraphEdge* edgep = vtxp->inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
TristateVertex* vvertexp = dynamic_cast<TristateVertex*>(edgep->fromp());
|
||||
if (const AstVarRef* refp = VN_CAST(vvertexp->nodep(), VarRef)) {
|
||||
TristateVertex* const vvertexp = dynamic_cast<TristateVertex*>(edgep->fromp());
|
||||
if (const AstVarRef* const refp = VN_CAST(vvertexp->nodep(), VarRef)) {
|
||||
if (refp->access().isWriteOrRW()
|
||||
// Doesn't hurt to not check if already set, but by doing so when we
|
||||
// print out the debug messages, we'll see this node at level 0 instead.
|
||||
|
|
@ -197,7 +197,7 @@ private:
|
|||
UINFO(9, " Mark feedstri " << level << " " << vtxp << endl);
|
||||
if (!vtxp->varp()) { // not a var where we stop the recursion
|
||||
for (V3GraphEdge* edgep = vtxp->inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
TristateVertex* vvertexp = dynamic_cast<TristateVertex*>(edgep->fromp());
|
||||
TristateVertex* const vvertexp = dynamic_cast<TristateVertex*>(edgep->fromp());
|
||||
// Doesn't hurt to not check if already set, but by doing so when we
|
||||
// print out the debug messages, we'll see this node at level 0 instead.
|
||||
if (!vvertexp->feedsTri()) {
|
||||
|
|
@ -213,7 +213,7 @@ public:
|
|||
bool empty() const { return m_graph.empty(); }
|
||||
void clear() {
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
TristateVertex* vvertexp = static_cast<TristateVertex*>(itp);
|
||||
TristateVertex* const vvertexp = static_cast<TristateVertex*>(itp);
|
||||
if (vvertexp->isTristate() && !vvertexp->processed()) {
|
||||
// Not v3errorSrc as no reason to stop the world
|
||||
vvertexp->nodep()->v3error("Unsupported tristate construct"
|
||||
|
|
@ -240,15 +240,15 @@ public:
|
|||
new V3GraphEdge(&m_graph, makeVertex(fromp), makeVertex(top), 1);
|
||||
}
|
||||
bool isTristate(AstNode* nodep) {
|
||||
TristateVertex* vertexp = reinterpret_cast<TristateVertex*>(nodep->user5p());
|
||||
TristateVertex* const vertexp = reinterpret_cast<TristateVertex*>(nodep->user5p());
|
||||
return vertexp && vertexp->isTristate();
|
||||
}
|
||||
bool feedsTri(AstNode* nodep) {
|
||||
TristateVertex* vertexp = reinterpret_cast<TristateVertex*>(nodep->user5p());
|
||||
TristateVertex* const vertexp = reinterpret_cast<TristateVertex*>(nodep->user5p());
|
||||
return vertexp && vertexp->feedsTri();
|
||||
}
|
||||
void didProcess(AstNode* nodep) {
|
||||
TristateVertex* vertexp = reinterpret_cast<TristateVertex*>(nodep->user5p());
|
||||
TristateVertex* const vertexp = reinterpret_cast<TristateVertex*>(nodep->user5p());
|
||||
if (!vertexp) {
|
||||
// Not v3errorSrc as no reason to stop the world
|
||||
nodep->v3error("Unsupported tristate construct (not in propagation graph): "
|
||||
|
|
@ -264,9 +264,9 @@ public:
|
|||
// Return all tristate variables
|
||||
VarVec v;
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
TristateVertex* vvertexp = static_cast<TristateVertex*>(itp);
|
||||
TristateVertex* const vvertexp = static_cast<TristateVertex*>(itp);
|
||||
if (vvertexp->isTristate()) {
|
||||
if (AstVar* nodep = VN_CAST(vvertexp->nodep(), Var)) v.push_back(nodep);
|
||||
if (AstVar* const nodep = VN_CAST(vvertexp->nodep(), Var)) v.push_back(nodep);
|
||||
}
|
||||
}
|
||||
return v;
|
||||
|
|
@ -371,7 +371,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
if (!nodep->user1p()) {
|
||||
V3Number num(nodep, nodep->width());
|
||||
num.setAllBits1();
|
||||
AstNode* enp = new AstConst(nodep->fileline(), num);
|
||||
AstNode* const enp = new AstConst(nodep->fileline(), num);
|
||||
nodep->user1p(enp);
|
||||
}
|
||||
return nodep->user1p();
|
||||
|
|
@ -380,8 +380,8 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
AstVar* getCreateEnVarp(AstVar* invarp) {
|
||||
// Return the master __en for the specified input variable
|
||||
if (!invarp->user1p()) {
|
||||
AstVar* newp = new AstVar(invarp->fileline(), AstVarType::MODULETEMP,
|
||||
invarp->name() + "__en", invarp);
|
||||
AstVar* const newp = new AstVar(invarp->fileline(), AstVarType::MODULETEMP,
|
||||
invarp->name() + "__en", invarp);
|
||||
UINFO(9, " newenv " << newp << endl);
|
||||
if (!m_modp) {
|
||||
invarp->v3warn(E_UNSUPPORTED,
|
||||
|
|
@ -398,8 +398,8 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
AstVar* getCreateOutVarp(AstVar* invarp) {
|
||||
// Return the master __out for the specified input variable
|
||||
if (!invarp->user4p()) {
|
||||
AstVar* newp = new AstVar(invarp->fileline(), AstVarType::MODULETEMP,
|
||||
invarp->name() + "__out", invarp);
|
||||
AstVar* const newp = new AstVar(invarp->fileline(), AstVarType::MODULETEMP,
|
||||
invarp->name() + "__out", invarp);
|
||||
UINFO(9, " newout " << newp << endl);
|
||||
if (!m_modp) {
|
||||
invarp->v3warn(E_UNSUPPORTED,
|
||||
|
|
@ -414,8 +414,8 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
}
|
||||
|
||||
AstVar* getCreateUnconnVarp(AstNode* fromp, AstNodeDType* dtypep) {
|
||||
AstVar* newp = new AstVar(fromp->fileline(), AstVarType::MODULETEMP,
|
||||
"__Vtriunconn" + cvtToStr(m_unique++), dtypep);
|
||||
AstVar* const newp = new AstVar(fromp->fileline(), AstVarType::MODULETEMP,
|
||||
"__Vtriunconn" + cvtToStr(m_unique++), dtypep);
|
||||
UINFO(9, " newunc " << newp << endl);
|
||||
if (!m_modp) {
|
||||
newp->v3warn(E_UNSUPPORTED,
|
||||
|
|
@ -427,11 +427,11 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
}
|
||||
|
||||
void mapInsertLhsVarRef(AstVarRef* nodep) {
|
||||
AstVar* key = nodep->varp();
|
||||
AstVar* const key = nodep->varp();
|
||||
const auto it = m_lhsmap.find(key);
|
||||
UINFO(9, " mapInsertLhsVarRef " << nodep << endl);
|
||||
if (it == m_lhsmap.end()) { // Not found
|
||||
RefVec* refsp = new RefVec();
|
||||
RefVec* const refsp = new RefVec();
|
||||
refsp->push_back(nodep);
|
||||
m_lhsmap.emplace(key, refsp);
|
||||
} else {
|
||||
|
|
@ -442,14 +442,14 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
AstNode* newEnableDeposit(AstSel* selp, AstNode* enp) {
|
||||
// Form a "deposit" instruction for given enable, using existing select as a template.
|
||||
// Would be nicer if we made this a new AST type
|
||||
AstNode* newp = new AstShiftL(selp->fileline(),
|
||||
new AstExtend(selp->fileline(), enp, selp->fromp()->width()),
|
||||
selp->lsbp()->cloneTree(false), selp->fromp()->width());
|
||||
AstNode* const newp = new AstShiftL(
|
||||
selp->fileline(), new AstExtend(selp->fileline(), enp, selp->fromp()->width()),
|
||||
selp->lsbp()->cloneTree(false), selp->fromp()->width());
|
||||
return newp;
|
||||
}
|
||||
|
||||
void setPullDirection(AstVar* varp, AstPull* pullp) {
|
||||
AstPull* oldpullp = static_cast<AstPull*>(varp->user3p());
|
||||
AstPull* const oldpullp = static_cast<AstPull*>(varp->user3p());
|
||||
if (!oldpullp) {
|
||||
varp->user3p(pullp); // save off to indicate the pull direction
|
||||
} else {
|
||||
|
|
@ -493,10 +493,11 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
// set output enable to always be off on this assign
|
||||
// statement so that this var is floating
|
||||
UINFO(8, " Adding driver to var " << varp << endl);
|
||||
AstConst* constp = new AstConst(varp->fileline(), AstConst::WidthedValue(),
|
||||
varp->width(), 0);
|
||||
AstVarRef* varrefp = new AstVarRef(varp->fileline(), varp, VAccess::WRITE);
|
||||
AstNode* newp = new AstAssignW(varp->fileline(), varrefp, constp);
|
||||
AstConst* const constp = new AstConst(
|
||||
varp->fileline(), AstConst::WidthedValue(), varp->width(), 0);
|
||||
AstVarRef* const varrefp
|
||||
= new AstVarRef(varp->fileline(), varp, VAccess::WRITE);
|
||||
AstNode* const newp = new AstAssignW(varp->fileline(), varrefp, constp);
|
||||
UINFO(9, " newoev " << newp << endl);
|
||||
varrefp->user1p(new AstConst(varp->fileline(), AstConst::WidthedValue(),
|
||||
varp->width(), 0));
|
||||
|
|
@ -513,8 +514,8 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
for (VarMap::iterator nextit, it = m_lhsmap.begin(); it != m_lhsmap.end(); it = nextit) {
|
||||
nextit = it;
|
||||
++nextit;
|
||||
AstVar* invarp = it->first;
|
||||
RefVec* refsp = it->second;
|
||||
AstVar* const invarp = it->first;
|
||||
RefVec* const refsp = it->second;
|
||||
|
||||
// Figure out if this var needs tristate expanded.
|
||||
if (!m_tgraph.isTristate(invarp)) {
|
||||
|
|
@ -566,40 +567,40 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
int w = lhsp->width();
|
||||
|
||||
// create the new lhs driver for this var
|
||||
AstVar* newlhsp = new AstVar(lhsp->fileline(), AstVarType::MODULETEMP,
|
||||
lhsp->name() + "__out" + cvtToStr(m_unique),
|
||||
VFlagBitPacked(), w); // 2-state ok; sep enable
|
||||
AstVar* const newlhsp = new AstVar(lhsp->fileline(), AstVarType::MODULETEMP,
|
||||
lhsp->name() + "__out" + cvtToStr(m_unique),
|
||||
VFlagBitPacked(), w); // 2-state ok; sep enable
|
||||
UINFO(9, " newout " << newlhsp << endl);
|
||||
nodep->addStmtp(newlhsp);
|
||||
refp->varp(newlhsp); // assign the new var to the varref
|
||||
refp->name(newlhsp->name());
|
||||
|
||||
// create a new var for this drivers enable signal
|
||||
AstVar* newenp = new AstVar(lhsp->fileline(), AstVarType::MODULETEMP,
|
||||
lhsp->name() + "__en" + cvtToStr(m_unique++),
|
||||
VFlagBitPacked(), w); // 2-state ok
|
||||
AstVar* const newenp = new AstVar(lhsp->fileline(), AstVarType::MODULETEMP,
|
||||
lhsp->name() + "__en" + cvtToStr(m_unique++),
|
||||
VFlagBitPacked(), w); // 2-state ok
|
||||
UINFO(9, " newenp " << newenp << endl);
|
||||
nodep->addStmtp(newenp);
|
||||
|
||||
AstNode* enassp = new AstAssignW(
|
||||
AstNode* const enassp = new AstAssignW(
|
||||
refp->fileline(), new AstVarRef(refp->fileline(), newenp, VAccess::WRITE),
|
||||
getEnp(refp));
|
||||
UINFO(9, " newass " << enassp << endl);
|
||||
nodep->addStmtp(enassp);
|
||||
|
||||
// now append this driver to the driver logic.
|
||||
AstNode* ref1p = new AstVarRef(refp->fileline(), newlhsp, VAccess::READ);
|
||||
AstNode* ref2p = new AstVarRef(refp->fileline(), newenp, VAccess::READ);
|
||||
AstNode* andp = new AstAnd(refp->fileline(), ref1p, ref2p);
|
||||
AstNode* const ref1p = new AstVarRef(refp->fileline(), newlhsp, VAccess::READ);
|
||||
AstNode* const ref2p = new AstVarRef(refp->fileline(), newenp, VAccess::READ);
|
||||
AstNode* const andp = new AstAnd(refp->fileline(), ref1p, ref2p);
|
||||
|
||||
// or this to the others
|
||||
orp = (!orp) ? andp : new AstOr(refp->fileline(), orp, andp);
|
||||
|
||||
if (envarp) {
|
||||
AstNode* ref3p = new AstVarRef(refp->fileline(), newenp, VAccess::READ);
|
||||
AstNode* const ref3p = new AstVarRef(refp->fileline(), newenp, VAccess::READ);
|
||||
enp = (!enp) ? ref3p : new AstOr(ref3p->fileline(), enp, ref3p);
|
||||
}
|
||||
AstNode* tmp = new AstNot(
|
||||
AstNode* const tmp = new AstNot(
|
||||
newenp->fileline(), new AstVarRef(newenp->fileline(), newenp, VAccess::READ));
|
||||
undrivenp = ((!undrivenp) ? tmp : new AstAnd(refp->fileline(), tmp, undrivenp));
|
||||
}
|
||||
|
|
@ -612,7 +613,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
// This is the final resolution of the tristate, so we apply
|
||||
// the pull direction to any undriven pins.
|
||||
V3Number pull(invarp, lhsp->width());
|
||||
AstPull* pullp = static_cast<AstPull*>(lhsp->user3p());
|
||||
AstPull* const pullp = static_cast<AstPull*>(lhsp->user3p());
|
||||
if (pullp && pullp->direction() == 1) {
|
||||
pull.setAllBits1();
|
||||
UINFO(9, "Has pullup " << pullp << endl);
|
||||
|
|
@ -631,7 +632,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
enp));
|
||||
}
|
||||
// __out (child) or <in> (parent) = drive-value expression
|
||||
AstNode* assp = new AstAssignW(
|
||||
AstNode* const assp = new AstAssignW(
|
||||
lhsp->fileline(), new AstVarRef(lhsp->fileline(), lhsp, VAccess::WRITE), orp);
|
||||
assp->user2(U2_BOTH); // Don't process further; already resolved
|
||||
if (debug() >= 9) assp->dumpTree(cout, "-lhsp-eqn: ");
|
||||
|
|
@ -653,22 +654,22 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
// A pin with 1'b0 or similar connection results in an assign with constant on LHS
|
||||
// due to the pinReconnectSimple call in visit AstPin.
|
||||
// We can ignore the output override by making a temporary
|
||||
AstVar* varp = getCreateUnconnVarp(nodep, nodep->dtypep());
|
||||
AstNode* newp = new AstVarRef(nodep->fileline(), varp, VAccess::WRITE);
|
||||
AstVar* const varp = getCreateUnconnVarp(nodep, nodep->dtypep());
|
||||
AstNode* const newp = new AstVarRef(nodep->fileline(), varp, VAccess::WRITE);
|
||||
UINFO(9, " const->" << newp << endl);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (m_tgraph.isTristate(nodep)) {
|
||||
m_tgraph.didProcess(nodep);
|
||||
FileLine* fl = nodep->fileline();
|
||||
FileLine* const fl = nodep->fileline();
|
||||
V3Number numz(nodep, nodep->width());
|
||||
numz.opBitsZ(nodep->num()); // Z->1, else 0
|
||||
V3Number numz0(nodep, nodep->width());
|
||||
numz0.opNot(numz); // Z->0, else 1
|
||||
V3Number num1(nodep, nodep->width());
|
||||
num1.opAnd(nodep->num(), numz0); // 01X->01X, Z->0
|
||||
AstConst* newconstp = new AstConst(fl, num1);
|
||||
AstConst* enp = new AstConst(fl, numz0);
|
||||
AstConst* const newconstp = new AstConst(fl, num1);
|
||||
AstConst* const enp = new AstConst(fl, numz0);
|
||||
nodep->replaceWith(newconstp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
newconstp->user1p(enp); // Propagate up constant with non-Z bits as 1
|
||||
|
|
@ -698,20 +699,21 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
// expression 1 or 2 have an output enable '__en' signal. If the
|
||||
// condition has an enable, not sure what to do, so generate an
|
||||
// error.
|
||||
AstNode* condp = nodep->condp();
|
||||
AstNode* const condp = nodep->condp();
|
||||
if (condp->user1p()) {
|
||||
condp->v3warn(E_UNSUPPORTED, "Unsupported: don't know how to deal with "
|
||||
"tristate logic in the conditional expression");
|
||||
}
|
||||
AstNode* expr1p = nodep->expr1p();
|
||||
AstNode* expr2p = nodep->expr2p();
|
||||
AstNode* const expr1p = nodep->expr1p();
|
||||
AstNode* const expr2p = nodep->expr2p();
|
||||
if (expr1p->user1p() || expr2p->user1p()) { // else no tristates
|
||||
m_tgraph.didProcess(nodep);
|
||||
AstNode* en1p = getEnp(expr1p);
|
||||
AstNode* en2p = getEnp(expr2p);
|
||||
AstNode* const en1p = getEnp(expr1p);
|
||||
AstNode* const en2p = getEnp(expr2p);
|
||||
// The output enable of a cond is a cond of the output enable of the
|
||||
// two expressions with the same conditional.
|
||||
AstNode* enp = new AstCond(nodep->fileline(), condp->cloneTree(false), en1p, en2p);
|
||||
AstNode* const enp
|
||||
= new AstCond(nodep->fileline(), condp->cloneTree(false), en1p, en2p);
|
||||
UINFO(9, " newcond " << enp << endl);
|
||||
nodep->user1p(enp); // propagate up COND(lhsp->enable, rhsp->enable)
|
||||
expr1p->user1p(nullptr);
|
||||
|
|
@ -733,7 +735,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
UINFO(9, dbgState() << nodep << endl);
|
||||
if (nodep->user1p()) {
|
||||
// Form a "deposit" instruction. Would be nicer if we made this a new AST type
|
||||
AstNode* newp = newEnableDeposit(nodep, nodep->user1p());
|
||||
AstNode* const newp = newEnableDeposit(nodep, nodep->user1p());
|
||||
nodep->fromp()->user1p(newp); // Push to varref (etc)
|
||||
if (debug() >= 9) newp->dumpTree(cout, "-assign-sel; ");
|
||||
m_tgraph.didProcess(nodep);
|
||||
|
|
@ -747,8 +749,8 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
<< nodep->prettyTypeName());
|
||||
}
|
||||
if (nodep->fromp()->user1p()) { // SEL(VARREF, lsb)
|
||||
AstNode* en1p = getEnp(nodep->fromp());
|
||||
AstNode* enp
|
||||
AstNode* const en1p = getEnp(nodep->fromp());
|
||||
AstNode* const enp
|
||||
= new AstSel(nodep->fileline(), en1p, nodep->lsbp()->cloneTree(true),
|
||||
nodep->widthp()->cloneTree(true));
|
||||
UINFO(9, " newsel " << enp << endl);
|
||||
|
|
@ -774,7 +776,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
UINFO(9, dbgState() << nodep << endl);
|
||||
if (nodep->user1p()) {
|
||||
// Each half of the concat gets a select of the enable expression
|
||||
AstNode* enp = nodep->user1p();
|
||||
AstNode* const enp = nodep->user1p();
|
||||
nodep->user1p(nullptr);
|
||||
nodep->lhsp()->user1p(new AstSel(nodep->fileline(), enp->cloneTree(true),
|
||||
nodep->rhsp()->width(),
|
||||
|
|
@ -789,13 +791,13 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
UINFO(9, dbgState() << nodep << endl);
|
||||
// Generate the new output enable signal, just as a concat
|
||||
// identical to the data concat
|
||||
AstNode* expr1p = nodep->lhsp();
|
||||
AstNode* expr2p = nodep->rhsp();
|
||||
AstNode* const expr1p = nodep->lhsp();
|
||||
AstNode* const expr2p = nodep->rhsp();
|
||||
if (expr1p->user1p() || expr2p->user1p()) { // else no tristates
|
||||
m_tgraph.didProcess(nodep);
|
||||
AstNode* en1p = getEnp(expr1p);
|
||||
AstNode* en2p = getEnp(expr2p);
|
||||
AstNode* enp = new AstConcat(nodep->fileline(), en1p, en2p);
|
||||
AstNode* const en1p = getEnp(expr1p);
|
||||
AstNode* const en2p = getEnp(expr2p);
|
||||
AstNode* const enp = new AstConcat(nodep->fileline(), en1p, en2p);
|
||||
UINFO(9, " newconc " << enp << endl);
|
||||
nodep->user1p(enp); // propagate up CONCAT(lhsp->enable, rhsp->enable)
|
||||
expr1p->user1p(nullptr);
|
||||
|
|
@ -820,10 +822,10 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
return;
|
||||
}
|
||||
m_tgraph.didProcess(nodep);
|
||||
AstNode* expr1p = nodep->lhsp()->unlinkFrBack();
|
||||
AstNode* expr2p = nodep->rhsp()->unlinkFrBack();
|
||||
AstNode* const expr1p = nodep->lhsp()->unlinkFrBack();
|
||||
AstNode* const expr2p = nodep->rhsp()->unlinkFrBack();
|
||||
AstNode* enp;
|
||||
if (AstNode* en2p = expr2p->user1p()) {
|
||||
if (AstNode* const en2p = expr2p->user1p()) {
|
||||
enp = new AstAnd(nodep->fileline(), expr1p, en2p);
|
||||
} else {
|
||||
enp = expr1p;
|
||||
|
|
@ -863,14 +865,14 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
// have to define what is means to OR 1'bz with other
|
||||
// expressions. Here I take the approach that when one expression
|
||||
// is 0, that is passes the other.
|
||||
AstNode* expr1p = nodep->lhsp();
|
||||
AstNode* expr2p = nodep->rhsp();
|
||||
AstNode* const expr1p = nodep->lhsp();
|
||||
AstNode* const expr2p = nodep->rhsp();
|
||||
if (!expr1p->user1p() && !expr2p->user1p()) {
|
||||
return; // no tristates in either expression, so nothing to do
|
||||
}
|
||||
m_tgraph.didProcess(nodep);
|
||||
AstNode* en1p = getEnp(expr1p);
|
||||
AstNode* en2p = getEnp(expr2p);
|
||||
AstNode* const en1p = getEnp(expr1p);
|
||||
AstNode* const en2p = getEnp(expr2p);
|
||||
AstNode* subexpr1p = expr1p->cloneTree(false);
|
||||
AstNode* subexpr2p = expr2p->cloneTree(false);
|
||||
if (isAnd) {
|
||||
|
|
@ -878,7 +880,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
subexpr2p = new AstNot(nodep->fileline(), subexpr2p);
|
||||
}
|
||||
// calc new output enable
|
||||
AstNode* enp = new AstOr(
|
||||
AstNode* const enp = new AstOr(
|
||||
nodep->fileline(), new AstAnd(nodep->fileline(), en1p, en2p),
|
||||
new AstOr(nodep->fileline(),
|
||||
new AstAnd(nodep->fileline(), en1p->cloneTree(false), subexpr1p),
|
||||
|
|
@ -942,16 +944,16 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
iterateChildren(nodep);
|
||||
UINFO(9, dbgState() << nodep << endl);
|
||||
// Constification always moves const to LHS
|
||||
const AstConst* constp = VN_CAST(nodep->lhsp(), Const);
|
||||
AstVarRef* varrefp = VN_CAST(nodep->rhsp(), VarRef); // Input variable
|
||||
const AstConst* const constp = VN_CAST(nodep->lhsp(), Const);
|
||||
AstVarRef* const varrefp = VN_CAST(nodep->rhsp(), VarRef); // Input variable
|
||||
if (constp && constp->user1p() && varrefp) {
|
||||
// 3'b1z0 -> ((3'b101 == in__en) && (3'b100 == in))
|
||||
varrefp->unlinkFrBack();
|
||||
FileLine* fl = nodep->fileline();
|
||||
FileLine* const fl = nodep->fileline();
|
||||
V3Number oneIfEn = VN_AS(constp->user1p(), Const)
|
||||
->num(); // visit(AstConst) already split into en/ones
|
||||
const V3Number& oneIfEnOne = constp->num();
|
||||
AstVar* envarp = getCreateEnVarp(varrefp->varp());
|
||||
AstVar* const envarp = getCreateEnVarp(varrefp->varp());
|
||||
AstNode* newp
|
||||
= new AstLogAnd(fl,
|
||||
new AstEq(fl, new AstConst(fl, oneIfEn),
|
||||
|
|
@ -993,7 +995,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
dropop[1] = VN_IS(nodep->thsp(), Const) && VN_AS(nodep->thsp(), Const)->num().isAnyZ();
|
||||
dropop[2] = VN_IS(nodep->fhsp(), Const) && VN_AS(nodep->fhsp(), Const)->num().isAnyZ();
|
||||
UINFO(4, " COUNTBITS(" << dropop[0] << dropop[1] << dropop[2] << " " << nodep << endl);
|
||||
AstVarRef* varrefp = VN_AS(nodep->lhsp(), VarRef); // Input variable
|
||||
AstVarRef* const varrefp = VN_AS(nodep->lhsp(), VarRef); // Input variable
|
||||
if (m_graphing) {
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
if (!dropop[0]) iterateAndNextNull(nodep->rhsp());
|
||||
|
|
@ -1018,7 +1020,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
<< nodep->prettyTypeName());
|
||||
return;
|
||||
}
|
||||
AstVar* envarp = getCreateEnVarp(varrefp->varp());
|
||||
AstVar* const envarp = getCreateEnVarp(varrefp->varp());
|
||||
// If any drops, we need to add in the count of Zs (from __en)
|
||||
UINFO(4, " COUNTBITS('z)-> " << nodep << endl);
|
||||
AstNRelinker relinkHandle;
|
||||
|
|
@ -1126,7 +1128,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
if (nodep->user2() & U2_GRAPHING) return; // This pin is already expanded
|
||||
nodep->user2(U2_GRAPHING);
|
||||
// Find child module's new variables.
|
||||
AstVar* enModVarp = static_cast<AstVar*>(nodep->modVarp()->user1p());
|
||||
AstVar* const enModVarp = static_cast<AstVar*>(nodep->modVarp()->user1p());
|
||||
if (!enModVarp) {
|
||||
// May have an output only that later connects to a tristate, so simplify now.
|
||||
V3Inst::pinReconnectSimple(nodep, m_cellp, false);
|
||||
|
|
@ -1147,7 +1149,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
&& !nodep->modVarp()->declDirection().isWritable());
|
||||
if (!nodep->exprp()) { // No-connect; covert to empty connection
|
||||
UINFO(5, "Unconnected pin terminate " << nodep << endl);
|
||||
AstVar* ucVarp = getCreateUnconnVarp(nodep, nodep->modVarp()->dtypep());
|
||||
AstVar* const ucVarp = getCreateUnconnVarp(nodep, nodep->modVarp()->dtypep());
|
||||
nodep->exprp(new AstVarRef(nodep->fileline(), ucVarp,
|
||||
// We converted, so use declaration output state
|
||||
nodep->modVarp()->declDirection().isWritable()
|
||||
|
|
@ -1158,7 +1160,8 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
} else if (inDeclProcessing) { // Not an input that was a converted tristate
|
||||
// Input only may have driver in underneath module which would stomp
|
||||
// the input value. So make a temporary connection.
|
||||
AstAssignW* reAssignp = V3Inst::pinReconnectSimple(nodep, m_cellp, true, true);
|
||||
AstAssignW* const reAssignp
|
||||
= V3Inst::pinReconnectSimple(nodep, m_cellp, true, true);
|
||||
UINFO(5, "Input pin buffering: " << reAssignp << endl);
|
||||
m_tgraph.setTristate(reAssignp->lhsp());
|
||||
}
|
||||
|
|
@ -1169,12 +1172,12 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
// Create the output enable pin, connect to new signal
|
||||
AstNode* enrefp;
|
||||
{
|
||||
AstVar* enVarp = new AstVar(nodep->fileline(), AstVarType::MODULETEMP,
|
||||
nodep->name() + "__en" + cvtToStr(m_unique++),
|
||||
VFlagBitPacked(), enModVarp->width());
|
||||
AstVar* const enVarp = new AstVar(nodep->fileline(), AstVarType::MODULETEMP,
|
||||
nodep->name() + "__en" + cvtToStr(m_unique++),
|
||||
VFlagBitPacked(), enModVarp->width());
|
||||
enModVarp->direction(VDirection::INPUT);
|
||||
UINFO(9, " newenv " << enVarp << endl);
|
||||
AstPin* enpinp
|
||||
AstPin* const enpinp
|
||||
= new AstPin(nodep->fileline(), nodep->pinNum(),
|
||||
enModVarp->name(), // should be {var}"__en"
|
||||
new AstVarRef(nodep->fileline(), enVarp, VAccess::WRITE));
|
||||
|
|
@ -1190,7 +1193,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
// Create new output pin
|
||||
AstAssignW* outAssignp = nullptr; // If reconnected, the related assignment
|
||||
AstPin* outpinp = nullptr;
|
||||
AstVar* outModVarp = static_cast<AstVar*>(nodep->modVarp()->user4p());
|
||||
AstVar* const outModVarp = static_cast<AstVar*>(nodep->modVarp()->user4p());
|
||||
if (!outModVarp) {
|
||||
// At top, no need for __out as might be input only. Otherwise resolvable.
|
||||
if (!m_modp->isTop()) {
|
||||
|
|
@ -1198,7 +1201,8 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
<< nodep->prettyNameQ());
|
||||
}
|
||||
} else {
|
||||
AstNode* outexprp = nodep->exprp()->cloneTree(false); // Note has lvalue() set
|
||||
AstNode* const outexprp
|
||||
= nodep->exprp()->cloneTree(false); // Note has lvalue() set
|
||||
outpinp = new AstPin(nodep->fileline(), nodep->pinNum(),
|
||||
outModVarp->name(), // should be {var}"__out"
|
||||
outexprp);
|
||||
|
|
@ -1225,7 +1229,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
|
||||
// Existing pin becomes an input, and we mark each resulting signal as tristate
|
||||
TristatePinVisitor visitor{nodep->exprp(), m_tgraph, false};
|
||||
AstNode* inAssignp = V3Inst::pinReconnectSimple(
|
||||
AstNode* const inAssignp = V3Inst::pinReconnectSimple(
|
||||
nodep, m_cellp, true); // Note may change nodep->exprp()
|
||||
if (debug() >= 9) nodep->dumpTree(cout, "-pin-in: ");
|
||||
if (debug() >= 9 && inAssignp) inAssignp->dumpTree(cout, "-pin-as: ");
|
||||
|
|
@ -1264,7 +1268,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
|
||||
// Propagate any pullups/pulldowns upwards if necessary
|
||||
if (exprrefp) {
|
||||
if (AstPull* pullp = static_cast<AstPull*>(nodep->modVarp()->user3p())) {
|
||||
if (AstPull* const pullp = static_cast<AstPull*>(nodep->modVarp()->user3p())) {
|
||||
UINFO(9, "propagate pull on " << exprrefp << endl);
|
||||
setPullDirection(exprrefp->varp(), pullp);
|
||||
}
|
||||
|
|
@ -1309,7 +1313,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
&& m_tgraph.feedsTri(nodep)) {
|
||||
// Then propagate the enable from the original variable
|
||||
UINFO(9, " Ref-to-tri " << nodep << endl);
|
||||
AstVar* enVarp = getCreateEnVarp(nodep->varp());
|
||||
AstVar* const enVarp = getCreateEnVarp(nodep->varp());
|
||||
nodep->user1p(new AstVarRef(nodep->fileline(), enVarp, VAccess::READ));
|
||||
}
|
||||
if (m_alhs) {} // NOP; user1() already passed down from assignment
|
||||
|
|
@ -1324,7 +1328,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
if (nodep->user2() & U2_GRAPHING) return; // Already processed
|
||||
nodep->user2(U2_GRAPHING);
|
||||
if (nodep->isPulldown() || nodep->isPullup()) {
|
||||
AstNode* newp = new AstPull(
|
||||
AstNode* const newp = new AstPull(
|
||||
nodep->fileline(), new AstVarRef(nodep->fileline(), nodep, VAccess::WRITE),
|
||||
nodep->isPullup());
|
||||
UINFO(9, " newpul " << newp << endl);
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ private:
|
|||
msb = bit;
|
||||
}
|
||||
} else if (prev) {
|
||||
AstBasicDType* bdtypep = m_varp->basicp();
|
||||
const AstBasicDType* const bdtypep = m_varp->basicp();
|
||||
const int lsb = bit + 1;
|
||||
if (bits != "") bits += ",";
|
||||
if (lsb == msb) {
|
||||
|
|
@ -148,7 +148,7 @@ public:
|
|||
}
|
||||
void reportViolations() {
|
||||
// Combine bits into overall state
|
||||
AstVar* nodep = m_varp;
|
||||
AstVar* const nodep = m_varp;
|
||||
{
|
||||
bool allU = true;
|
||||
bool allD = true;
|
||||
|
|
|
|||
|
|
@ -91,9 +91,9 @@ private:
|
|||
if (m_assigndlyp) {
|
||||
// Delayed assignments become normal assignments,
|
||||
// then the temp created becomes the delayed assignment
|
||||
AstNode* newp = new AstAssign(m_assigndlyp->fileline(),
|
||||
m_assigndlyp->lhsp()->unlinkFrBackWithNext(),
|
||||
m_assigndlyp->rhsp()->unlinkFrBackWithNext());
|
||||
AstNode* const newp = new AstAssign(m_assigndlyp->fileline(),
|
||||
m_assigndlyp->lhsp()->unlinkFrBackWithNext(),
|
||||
m_assigndlyp->rhsp()->unlinkFrBackWithNext());
|
||||
m_assigndlyp->replaceWith(newp);
|
||||
VL_DO_CLEAR(pushDeletep(m_assigndlyp), m_assigndlyp = nullptr);
|
||||
}
|
||||
|
|
@ -103,16 +103,16 @@ private:
|
|||
while (VN_IS(prep->backp(), NodeSel) || VN_IS(prep->backp(), Sel)) {
|
||||
prep = prep->backp();
|
||||
}
|
||||
FileLine* fl = nodep->fileline();
|
||||
FileLine* const fl = nodep->fileline();
|
||||
VL_DANGLING(nodep); // Zap it so we don't use it by mistake - use prep
|
||||
|
||||
// Already exists; rather than IF(a,... IF(b... optimize to IF(a&&b,
|
||||
// Saves us teaching V3Const how to optimize, and it won't be needed again.
|
||||
if (AstIf* ifp = VN_AS(prep->user2p(), If)) {
|
||||
if (const AstIf* const ifp = VN_AS(prep->user2p(), If)) {
|
||||
UASSERT_OBJ(!needDly, prep, "Should have already converted to non-delay");
|
||||
AstNRelinker replaceHandle;
|
||||
AstNode* earliercondp = ifp->condp()->unlinkFrBack(&replaceHandle);
|
||||
AstNode* newp = new AstLogAnd(condp->fileline(), condp, earliercondp);
|
||||
AstNode* const earliercondp = ifp->condp()->unlinkFrBack(&replaceHandle);
|
||||
AstNode* const newp = new AstLogAnd(condp->fileline(), condp, earliercondp);
|
||||
UINFO(4, "Edit BOUNDLVALUE " << newp << endl);
|
||||
replaceHandle.relink(newp);
|
||||
} else {
|
||||
|
|
@ -363,7 +363,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
if (!nodep->user1SetOnce()) {
|
||||
// Guard against reading/writing past end of bit vector array
|
||||
AstNode* basefromp = AstArraySel::baseFromp(nodep, true);
|
||||
const AstNode* basefromp = AstArraySel::baseFromp(nodep, true);
|
||||
bool lvalue = false;
|
||||
if (const AstNodeVarRef* varrefp = VN_CAST(basefromp, NodeVarRef)) {
|
||||
lvalue = varrefp->access().isWriteOrRW();
|
||||
|
|
|
|||
|
|
@ -85,12 +85,12 @@ private:
|
|||
return bodySizeOverRecurse(nodep->nextp(), bodySize, bodyLimit);
|
||||
}
|
||||
|
||||
bool
|
||||
forUnrollCheck(AstNode* nodep,
|
||||
AstNode* initp, // Maybe under nodep (no nextp), or standalone (ignore nextp)
|
||||
AstNode* precondsp, AstNode* condp,
|
||||
AstNode* incp, // Maybe under nodep or in bodysp
|
||||
AstNode* bodysp) {
|
||||
bool forUnrollCheck(
|
||||
AstNode* nodep,
|
||||
AstNode* const initp, // Maybe under nodep (no nextp), or standalone (ignore nextp)
|
||||
AstNode* const precondsp, AstNode* condp,
|
||||
AstNode* const incp, // Maybe under nodep or in bodysp
|
||||
AstNode* bodysp) {
|
||||
// To keep the IF levels low, we return as each test fails.
|
||||
UINFO(4, " FOR Check " << nodep << endl);
|
||||
if (initp) UINFO(6, " Init " << initp << endl);
|
||||
|
|
@ -99,7 +99,7 @@ private:
|
|||
if (incp) UINFO(6, " Inc " << incp << endl);
|
||||
|
||||
// Initial value check
|
||||
AstAssign* initAssp = VN_CAST(initp, Assign);
|
||||
AstAssign* const initAssp = VN_CAST(initp, Assign);
|
||||
if (!initAssp) return cantUnroll(nodep, "no initial assignment");
|
||||
UASSERT_OBJ(!(initp->nextp() && initp->nextp() != nodep), nodep,
|
||||
"initial assignment shouldn't be a list");
|
||||
|
|
@ -111,7 +111,7 @@ private:
|
|||
UASSERT_OBJ(!condp->nextp(), nodep, "conditional shouldn't be a list");
|
||||
//
|
||||
// Assignment of next value check
|
||||
AstAssign* incAssp = VN_CAST(incp, Assign);
|
||||
const AstAssign* const incAssp = VN_CAST(incp, Assign);
|
||||
if (!incAssp) return cantUnroll(nodep, "no increment assignment");
|
||||
if (incAssp->nextp()) return cantUnroll(nodep, "multiple increments");
|
||||
|
||||
|
|
@ -131,7 +131,7 @@ private:
|
|||
// however, for repeat loops, the loop variable is auto-generated
|
||||
// and the initp statements will reference a variable outside of the initp scope
|
||||
// alas, failing to simulate.
|
||||
AstConst* constInitp = VN_CAST(initAssp->rhsp(), Const);
|
||||
const AstConst* const constInitp = VN_CAST(initAssp->rhsp(), Const);
|
||||
if (!constInitp) return cantUnroll(nodep, "non-constant initializer");
|
||||
|
||||
//
|
||||
|
|
@ -155,7 +155,7 @@ private:
|
|||
if (debug() >= 9) nodep->dumpTree(cout, "- for: ");
|
||||
|
||||
if (!m_generate) {
|
||||
AstAssign* incpAssign = VN_AS(incp, Assign);
|
||||
const AstAssign* const incpAssign = VN_AS(incp, Assign);
|
||||
if (!canSimulate(incpAssign->rhsp())) {
|
||||
return cantUnroll(incp, "Unable to simulate increment");
|
||||
}
|
||||
|
|
@ -255,7 +255,7 @@ private:
|
|||
outLoopsr++;
|
||||
|
||||
// Run inc
|
||||
AstAssign* incpass = VN_AS(incp, Assign);
|
||||
AstAssign* const incpass = VN_AS(incp, Assign);
|
||||
V3Number newLoopValue = V3Number(initp);
|
||||
if (!simulateTree(incpass->rhsp(), &loopValue, incpass, newLoopValue)) {
|
||||
return false;
|
||||
|
|
@ -315,7 +315,7 @@ private:
|
|||
|
||||
// Iteration requires a back, so put under temporary node
|
||||
if (oneloopp) {
|
||||
AstBegin* tempp
|
||||
AstBegin* const tempp
|
||||
= new AstBegin(oneloopp->fileline(), "[EditWrapper]", oneloopp);
|
||||
m_varModeReplace = true;
|
||||
iterateAndNextNull(tempp->stmtsp());
|
||||
|
|
@ -345,7 +345,7 @@ private:
|
|||
}
|
||||
|
||||
// loopValue += valInc
|
||||
AstAssign* incpass = VN_AS(incp, Assign);
|
||||
AstAssign* const incpass = VN_AS(incp, Assign);
|
||||
V3Number newLoopValue = V3Number(nodep);
|
||||
if (!simulateTree(incpass->rhsp(), &loopValue, incpass, newLoopValue)) {
|
||||
nodep->v3error("Loop unrolling failed");
|
||||
|
|
@ -452,7 +452,7 @@ private:
|
|||
|
||||
if (m_varModeReplace && nodep->varp() == m_forVarp && nodep->varScopep() == m_forVscp
|
||||
&& nodep->access().isReadOnly()) {
|
||||
AstNode* newconstp = m_varValuep->cloneTree(false);
|
||||
AstNode* const newconstp = m_varValuep->cloneTree(false);
|
||||
nodep->replaceWith(newconstp);
|
||||
pushDeletep(nodep);
|
||||
}
|
||||
|
|
|
|||
195
src/V3Width.cpp
195
src/V3Width.cpp
|
|
@ -112,7 +112,7 @@ std::ostream& operator<<(std::ostream& str, const Castable& rhs) {
|
|||
|
||||
class WidthVP final {
|
||||
// Parameters to pass down hierarchy with visit functions.
|
||||
AstNodeDType* m_dtypep; // Parent's data type to resolve to
|
||||
AstNodeDType* const m_dtypep; // Parent's data type to resolve to
|
||||
Stage m_stage; // If true, report errors
|
||||
public:
|
||||
WidthVP(AstNodeDType* dtypep, Stage stage)
|
||||
|
|
@ -475,8 +475,8 @@ private:
|
|||
}
|
||||
}
|
||||
if (m_vup->final()) {
|
||||
AstNodeDType* expDTypep = m_vup->dtypeOverridep(nodep->dtypep());
|
||||
AstNodeDType* subDTypep = expDTypep;
|
||||
AstNodeDType* const expDTypep = m_vup->dtypeOverridep(nodep->dtypep());
|
||||
AstNodeDType* const subDTypep = expDTypep;
|
||||
nodep->dtypeFrom(expDTypep);
|
||||
// Error report and change sizes for suboperands of this node.
|
||||
iterateCheck(nodep, "Conditional True", nodep->expr1p(), CONTEXT, FINAL, subDTypep,
|
||||
|
|
@ -492,20 +492,20 @@ private:
|
|||
// LHS, RHS is self-determined
|
||||
// signed: Unsigned (11.8.1)
|
||||
// width: LHS + RHS
|
||||
AstNodeDType* vdtypep = m_vup->dtypeNullSkipRefp();
|
||||
AstNodeDType* const vdtypep = m_vup->dtypeNullSkipRefp();
|
||||
userIterate(vdtypep, WidthVP(SELF, BOTH).p());
|
||||
if (VN_IS(vdtypep, QueueDType)) {
|
||||
// Queue "element 0" is lhsp, so we need to swap arguments
|
||||
auto* newp = new AstConsQueue(nodep->fileline(), nodep->rhsp()->unlinkFrBack(),
|
||||
nodep->lhsp()->unlinkFrBack());
|
||||
auto* const newp = new AstConsQueue(nodep->fileline(), nodep->rhsp()->unlinkFrBack(),
|
||||
nodep->lhsp()->unlinkFrBack());
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
userIterateChildren(newp, m_vup);
|
||||
return;
|
||||
}
|
||||
if (VN_IS(vdtypep, DynArrayDType)) {
|
||||
auto* newp = new AstConsDynArray(nodep->fileline(), nodep->rhsp()->unlinkFrBack(),
|
||||
nodep->lhsp()->unlinkFrBack());
|
||||
auto* const newp = new AstConsDynArray(
|
||||
nodep->fileline(), nodep->rhsp()->unlinkFrBack(), nodep->lhsp()->unlinkFrBack());
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
userIterateChildren(newp, m_vup);
|
||||
|
|
@ -526,14 +526,14 @@ private:
|
|||
VSigning::UNSIGNED);
|
||||
// Cleanup zero width Verilog2001 {x,{0{foo}}} now,
|
||||
// otherwise having width(0) will cause later assertions to fire
|
||||
if (AstReplicate* repp = VN_CAST(nodep->lhsp(), Replicate)) {
|
||||
if (const AstReplicate* const repp = VN_CAST(nodep->lhsp(), Replicate)) {
|
||||
if (repp->width() == 0) { // Keep rhs
|
||||
nodep->replaceWith(nodep->rhsp()->unlinkFrBack());
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (AstReplicate* repp = VN_CAST(nodep->rhsp(), Replicate)) {
|
||||
if (const AstReplicate* const repp = VN_CAST(nodep->rhsp(), Replicate)) {
|
||||
if (repp->width() == 0) { // Keep lhs
|
||||
nodep->replaceWith(nodep->lhsp()->unlinkFrBack());
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
|
|
@ -543,8 +543,9 @@ private:
|
|||
}
|
||||
if (m_vup->final()) {
|
||||
if (nodep->lhsp()->isString() || nodep->rhsp()->isString()) {
|
||||
AstNode* newp = new AstConcatN(nodep->fileline(), nodep->lhsp()->unlinkFrBack(),
|
||||
nodep->rhsp()->unlinkFrBack());
|
||||
AstNode* const newp
|
||||
= new AstConcatN(nodep->fileline(), nodep->lhsp()->unlinkFrBack(),
|
||||
nodep->rhsp()->unlinkFrBack());
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
return;
|
||||
|
|
@ -601,7 +602,7 @@ private:
|
|||
|| (!nodep->stmtsp()->nextp() && !nodep->joinType().joinNone())) {
|
||||
AstNode* stmtsp = nullptr;
|
||||
if (nodep->stmtsp()) stmtsp = nodep->stmtsp()->unlinkFrBack();
|
||||
AstBegin* newp = new AstBegin{nodep->fileline(), nodep->name(), stmtsp};
|
||||
AstBegin* const newp = new AstBegin{nodep->fileline(), nodep->name(), stmtsp};
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
} else {
|
||||
|
|
@ -636,7 +637,7 @@ private:
|
|||
if (m_vup->prelim()) {
|
||||
iterateCheckSizedSelf(nodep, "RHS", nodep->rhsp(), SELF, BOTH);
|
||||
V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change
|
||||
const AstConst* constp = VN_CAST(nodep->rhsp(), Const);
|
||||
const AstConst* const constp = VN_CAST(nodep->rhsp(), Const);
|
||||
if (!constp) {
|
||||
nodep->v3error("Replication value isn't a constant.");
|
||||
return;
|
||||
|
|
@ -649,7 +650,7 @@ private:
|
|||
times = 1;
|
||||
}
|
||||
|
||||
AstNodeDType* vdtypep = m_vup->dtypeNullSkipRefp();
|
||||
AstNodeDType* const vdtypep = m_vup->dtypeNullSkipRefp();
|
||||
if (VN_IS(vdtypep, QueueDType) || VN_IS(vdtypep, DynArrayDType)) {
|
||||
if (times != 1)
|
||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: Non-1 replication to form "
|
||||
|
|
@ -668,8 +669,9 @@ private:
|
|||
}
|
||||
iterateCheckSizedSelf(nodep, "LHS", nodep->lhsp(), SELF, BOTH);
|
||||
if (nodep->lhsp()->isString()) {
|
||||
AstNode* newp = new AstReplicateN(nodep->fileline(), nodep->lhsp()->unlinkFrBack(),
|
||||
nodep->rhsp()->unlinkFrBack());
|
||||
AstNode* const newp
|
||||
= new AstReplicateN(nodep->fileline(), nodep->lhsp()->unlinkFrBack(),
|
||||
nodep->rhsp()->unlinkFrBack());
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
return;
|
||||
|
|
@ -693,7 +695,7 @@ private:
|
|||
iterateCheckString(nodep, "LHS", nodep->lhsp(), BOTH);
|
||||
iterateCheckSizedSelf(nodep, "RHS", nodep->rhsp(), SELF, BOTH);
|
||||
V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change
|
||||
const AstConst* constp = VN_CAST(nodep->rhsp(), Const);
|
||||
const AstConst* const constp = VN_CAST(nodep->rhsp(), Const);
|
||||
if (!constp) {
|
||||
nodep->v3error("Replication value isn't a constant.");
|
||||
return;
|
||||
|
|
@ -719,14 +721,14 @@ private:
|
|||
iterateCheckSizedSelf(nodep, "LHS", nodep->lhsp(), SELF, BOTH);
|
||||
iterateCheckSizedSelf(nodep, "RHS", nodep->rhsp(), SELF, BOTH);
|
||||
V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change
|
||||
const AstConst* constp = VN_CAST(nodep->rhsp(), Const);
|
||||
AstBasicDType* basicp = VN_CAST(nodep->rhsp(), BasicDType);
|
||||
const AstConst* const constp = VN_CAST(nodep->rhsp(), Const);
|
||||
AstBasicDType* const basicp = VN_CAST(nodep->rhsp(), BasicDType);
|
||||
if (!constp && !basicp) {
|
||||
nodep->v3error("Slice size isn't a constant or basic data type.");
|
||||
return;
|
||||
}
|
||||
if (basicp) { // Convert data type to a constant size
|
||||
AstConst* newp = new AstConst(basicp->fileline(), basicp->width());
|
||||
AstConst* const newp = new AstConst(basicp->fileline(), basicp->width());
|
||||
nodep->rhsp()->replaceWith(newp);
|
||||
pushDeletep(basicp);
|
||||
} else {
|
||||
|
|
@ -787,7 +789,7 @@ private:
|
|||
iterateCheckSizedSelf(nodep, "Select Width", nodep->widthp(), SELF, BOTH);
|
||||
iterateCheckSizedSelf(nodep, "Select LHS", nodep->lhsp(), SELF, BOTH);
|
||||
V3Const::constifyParamsEdit(nodep->widthp()); // widthp may change
|
||||
AstConst* widthConstp = VN_CAST(nodep->widthp(), Const);
|
||||
AstConst* const widthConstp = VN_CAST(nodep->widthp(), Const);
|
||||
if (!widthConstp) {
|
||||
nodep->v3error("Width of bit extract isn't a constant");
|
||||
nodep->dtypeSetBit();
|
||||
|
|
@ -808,7 +810,7 @@ private:
|
|||
nodep->v3warn(SELRANGE, "Extracting " << width << " bits from only "
|
||||
<< nodep->fromp()->width() << " bit number");
|
||||
// Extend it.
|
||||
AstNodeDType* subDTypep
|
||||
AstNodeDType* const subDTypep
|
||||
= nodep->findLogicDType(width, width, nodep->fromp()->dtypep()->numeric());
|
||||
widthCheckSized(nodep, "errorless...", nodep->fromp(), subDTypep, EXTEND_EXP,
|
||||
false /*noerror*/);
|
||||
|
|
@ -828,7 +830,7 @@ private:
|
|||
// nodep->v3fatalSrc("Should have been declRanged in V3WidthSel");
|
||||
}
|
||||
const int selwidth = V3Number::log2b(frommsb + 1 - 1) + 1; // Width to address a bit
|
||||
AstNodeDType* selwidthDTypep
|
||||
AstNodeDType* const selwidthDTypep
|
||||
= nodep->findLogicDType(selwidth, selwidth, nodep->lsbp()->dtypep()->numeric());
|
||||
userIterateAndNext(nodep->fromp(), WidthVP(SELF, FINAL).p());
|
||||
userIterateAndNext(nodep->lsbp(), WidthVP(SELF, FINAL).p());
|
||||
|
|
@ -890,8 +892,8 @@ private:
|
|||
//
|
||||
int frommsb;
|
||||
int fromlsb;
|
||||
AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefp();
|
||||
if (const AstUnpackArrayDType* adtypep = VN_CAST(fromDtp, UnpackArrayDType)) {
|
||||
AstNodeDType* const fromDtp = nodep->fromp()->dtypep()->skipRefp();
|
||||
if (const AstUnpackArrayDType* const adtypep = VN_CAST(fromDtp, UnpackArrayDType)) {
|
||||
frommsb = adtypep->hi();
|
||||
fromlsb = adtypep->lo();
|
||||
if (fromlsb > frommsb) {
|
||||
|
|
@ -909,7 +911,7 @@ private:
|
|||
frommsb = fromlsb = 0;
|
||||
}
|
||||
const int selwidth = V3Number::log2b(frommsb + 1 - 1) + 1; // Width to address a bit
|
||||
AstNodeDType* selwidthDTypep
|
||||
AstNodeDType* const selwidthDTypep
|
||||
= nodep->findLogicDType(selwidth, selwidth, nodep->bitp()->dtypep()->numeric());
|
||||
if (widthBad(nodep->bitp(), selwidthDTypep) && nodep->bitp()->width() != 32) {
|
||||
nodep->v3warn(WIDTH, "Bit extraction of array["
|
||||
|
|
@ -945,8 +947,8 @@ private:
|
|||
virtual void visit(AstAssocSel* nodep) override {
|
||||
// Signed/Real: Output type based on array-declared type; binary operator
|
||||
if (m_vup->prelim()) {
|
||||
AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefp();
|
||||
AstAssocArrayDType* adtypep = VN_CAST(fromDtp, AssocArrayDType);
|
||||
AstNodeDType* const fromDtp = nodep->fromp()->dtypep()->skipRefp();
|
||||
AstAssocArrayDType* const adtypep = VN_CAST(fromDtp, AssocArrayDType);
|
||||
if (!adtypep) {
|
||||
UINFO(1, " Related dtype: " << fromDtp << endl);
|
||||
nodep->v3fatalSrc("Associative array reference is not to associative array");
|
||||
|
|
@ -963,14 +965,14 @@ private:
|
|||
userIterateAndNext(nodep->fromp(), WidthVP(SELF, BOTH).p());
|
||||
//
|
||||
// Array indices are always constant
|
||||
AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefp();
|
||||
AstUnpackArrayDType* adtypep = VN_CAST(fromDtp, UnpackArrayDType);
|
||||
AstNodeDType* const fromDtp = nodep->fromp()->dtypep()->skipRefp();
|
||||
AstUnpackArrayDType* const adtypep = VN_CAST(fromDtp, UnpackArrayDType);
|
||||
if (!adtypep) {
|
||||
UINFO(1, " Related dtype: " << fromDtp << endl);
|
||||
nodep->v3fatalSrc("Packed array reference exceeds dimension of array");
|
||||
}
|
||||
// Build new array Dtype based on the original's base type, but with new bounds
|
||||
AstNodeDType* newDtp
|
||||
AstNodeDType* const newDtp
|
||||
= new AstUnpackArrayDType(nodep->fileline(), adtypep->subDTypep(),
|
||||
new AstRange(nodep->fileline(), nodep->declRange()));
|
||||
v3Global.rootp()->typeTablep()->addTypesp(newDtp);
|
||||
|
|
@ -1007,7 +1009,7 @@ private:
|
|||
userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT, PRELIM).p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->thsp(), WidthVP(CONTEXT, PRELIM).p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->attrp(), WidthVP(SELF, BOTH).p());
|
||||
AstNode* selp = V3Width::widthSelNoIterEdit(nodep);
|
||||
AstNode* const selp = V3Width::widthSelNoIterEdit(nodep);
|
||||
if (selp != nodep) {
|
||||
nodep = nullptr;
|
||||
userIterate(selp, m_vup);
|
||||
|
|
@ -1021,7 +1023,7 @@ private:
|
|||
userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT, PRELIM).p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->thsp(), WidthVP(CONTEXT, PRELIM).p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->attrp(), WidthVP(SELF, BOTH).p());
|
||||
AstNode* selp = V3Width::widthSelNoIterEdit(nodep);
|
||||
AstNode* const selp = V3Width::widthSelNoIterEdit(nodep);
|
||||
if (selp != nodep) {
|
||||
nodep = nullptr;
|
||||
userIterate(selp, m_vup);
|
||||
|
|
@ -1034,7 +1036,7 @@ private:
|
|||
userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT, PRELIM).p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->thsp(), WidthVP(CONTEXT, PRELIM).p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->attrp(), WidthVP(SELF, BOTH).p());
|
||||
AstNode* selp = V3Width::widthSelNoIterEdit(nodep);
|
||||
AstNode* const selp = V3Width::widthSelNoIterEdit(nodep);
|
||||
if (selp != nodep) {
|
||||
nodep = nullptr;
|
||||
userIterate(selp, m_vup);
|
||||
|
|
@ -1047,7 +1049,7 @@ private:
|
|||
userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT, PRELIM).p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->thsp(), WidthVP(CONTEXT, PRELIM).p()); // FINAL in AstSel
|
||||
userIterateAndNext(nodep->attrp(), WidthVP(SELF, BOTH).p());
|
||||
AstNode* selp = V3Width::widthSelNoIterEdit(nodep);
|
||||
AstNode* const selp = V3Width::widthSelNoIterEdit(nodep);
|
||||
if (selp != nodep) {
|
||||
nodep = nullptr;
|
||||
userIterate(selp, m_vup);
|
||||
|
|
@ -1097,7 +1099,7 @@ private:
|
|||
if (nodep->ticksp()) {
|
||||
iterateCheckSizedSelf(nodep, "Ticks", nodep->ticksp(), SELF, BOTH);
|
||||
V3Const::constifyParamsEdit(nodep->ticksp()); // ticksp may change
|
||||
const AstConst* constp = VN_CAST(nodep->ticksp(), Const);
|
||||
const AstConst* const constp = VN_CAST(nodep->ticksp(), Const);
|
||||
if (!constp) {
|
||||
nodep->v3error("$past tick value must be constant (IEEE 1800-2017 16.9.3)");
|
||||
nodep->ticksp()->unlinkFrBack()->deleteTree();
|
||||
|
|
@ -1156,7 +1158,7 @@ private:
|
|||
virtual void visit(AstURandomRange* nodep) override {
|
||||
if (m_vup->prelim()) {
|
||||
nodep->dtypeSetUInt32(); // Says the spec
|
||||
AstNodeDType* expDTypep = nodep->findUInt32DType();
|
||||
AstNodeDType* const expDTypep = nodep->findUInt32DType();
|
||||
userIterateAndNext(nodep->lhsp(), WidthVP(CONTEXT, PRELIM).p());
|
||||
userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT, PRELIM).p());
|
||||
iterateCheck(nodep, "LHS", nodep->lhsp(), SELF, FINAL, expDTypep, EXTEND_EXP);
|
||||
|
|
@ -1167,11 +1169,11 @@ private:
|
|||
nodep->dtypeSetSigned32(); // Used in int context
|
||||
if (VN_IS(nodep->backp(), IsUnbounded)) return; // Ok, leave
|
||||
if (VN_IS(nodep->backp(), BracketArrayDType)) return; // Ok, leave
|
||||
if (auto* varp = VN_CAST(nodep->backp(), Var)) {
|
||||
if (auto* const varp = VN_CAST(nodep->backp(), Var)) {
|
||||
if (varp->isParam()) return; // Ok, leave
|
||||
}
|
||||
// queue_slice[#:$]
|
||||
if (auto* selp = VN_CAST(nodep->backp(), SelExtract)) {
|
||||
if (auto* const selp = VN_CAST(nodep->backp(), SelExtract)) {
|
||||
if (VN_IS(selp->fromp()->dtypep(), QueueDType)) {
|
||||
nodep->replaceWith(
|
||||
new AstConst(nodep->fileline(), AstConst::Signed32(), 0x7FFFFFFF));
|
||||
|
|
@ -1195,7 +1197,7 @@ private:
|
|||
userIterateChildren(nodep, WidthVP(SELF, BOTH).p());
|
||||
}
|
||||
if (m_vup->final()) {
|
||||
AstNodeDType* expDTypep = m_vup->dtypeOverridep(nodep->dtypep());
|
||||
AstNodeDType* const expDTypep = m_vup->dtypeOverridep(nodep->dtypep());
|
||||
nodep->dtypeFrom(expDTypep); // Assume user knows the rules; go with the flow
|
||||
if (nodep->width() > 64) {
|
||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: $c can't generate wider than 64 bits");
|
||||
|
|
@ -1229,7 +1231,7 @@ private:
|
|||
}
|
||||
|
||||
if (m_vup->final()) {
|
||||
AstNodeDType* expDTypep = m_vup->dtypeOverridep(nodep->dtypep());
|
||||
AstNodeDType* const expDTypep = m_vup->dtypeOverridep(nodep->dtypep());
|
||||
nodep->dtypeFrom(expDTypep);
|
||||
// rhs already finalized in iterate_shift_prelim
|
||||
iterateCheck(nodep, "LHS", nodep->lhsp(), SELF, FINAL, nodep->dtypep(), EXTEND_EXP);
|
||||
|
|
@ -1300,14 +1302,14 @@ private:
|
|||
// LHS is a real number in seconds
|
||||
// Need to round to time units and precision
|
||||
userIterateAndNext(nodep->lhsp(), WidthVP(SELF, BOTH).p());
|
||||
AstConst* constp = VN_CAST(nodep->lhsp(), Const);
|
||||
AstConst* const constp = VN_CAST(nodep->lhsp(), Const);
|
||||
if (!constp || !constp->isDouble()) nodep->v3fatalSrc("Times should be doubles");
|
||||
if (nodep->timeunit().isNone()) nodep->v3fatalSrc("$time import no units");
|
||||
double time = constp->num().toDouble();
|
||||
if (v3Global.rootp()->timeprecision().isNone()) nodep->v3fatalSrc("Never set precision?");
|
||||
time /= nodep->timeunit().multiplier();
|
||||
// IEEE claims you should round to time precision here, but no simulator seems to do this
|
||||
AstConst* newp = new AstConst(nodep->fileline(), AstConst::RealDouble(), time);
|
||||
AstConst* const newp = new AstConst(nodep->fileline(), AstConst::RealDouble(), time);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
|
|
@ -1352,7 +1354,7 @@ private:
|
|||
if (VN_IS(nodep->fromp()->dtypep(), QueueDType)) {
|
||||
switch (nodep->attrType()) {
|
||||
case AstAttrType::DIM_SIZE: {
|
||||
AstNode* newp = new AstCMethodHard(
|
||||
AstNode* const newp = new AstCMethodHard(
|
||||
nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size", nullptr);
|
||||
newp->dtypeSetSigned32();
|
||||
newp->didWidth(true);
|
||||
|
|
@ -1363,19 +1365,19 @@ private:
|
|||
}
|
||||
case AstAttrType::DIM_LEFT:
|
||||
case AstAttrType::DIM_LOW: {
|
||||
AstNode* newp = new AstConst(nodep->fileline(), AstConst::Signed32(), 0);
|
||||
AstNode* const newp = new AstConst(nodep->fileline(), AstConst::Signed32(), 0);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
break;
|
||||
}
|
||||
case AstAttrType::DIM_RIGHT:
|
||||
case AstAttrType::DIM_HIGH: {
|
||||
AstNode* sizep = new AstCMethodHard(
|
||||
AstNode* const sizep = new AstCMethodHard(
|
||||
nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size", nullptr);
|
||||
sizep->dtypeSetSigned32();
|
||||
sizep->didWidth(true);
|
||||
sizep->protect(false);
|
||||
AstNode* newp
|
||||
AstNode* const newp
|
||||
= new AstSub(nodep->fileline(), sizep,
|
||||
new AstConst(nodep->fileline(), AstConst::Signed32(), 1));
|
||||
nodep->replaceWith(newp);
|
||||
|
|
@ -1383,7 +1385,8 @@ private:
|
|||
break;
|
||||
}
|
||||
case AstAttrType::DIM_INCREMENT: {
|
||||
AstNode* newp = new AstConst(nodep->fileline(), AstConst::Signed32(), -1);
|
||||
AstNode* const newp
|
||||
= new AstConst(nodep->fileline(), AstConst::Signed32(), -1);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
break;
|
||||
|
|
@ -1400,25 +1403,26 @@ private:
|
|||
uint32_t msbdim = dimpair.first + dimpair.second;
|
||||
if (!nodep->dimp() || msbdim < 1) {
|
||||
const int dim = 1;
|
||||
AstConst* newp = dimensionValue(nodep->fileline(), nodep->fromp()->dtypep(),
|
||||
nodep->attrType(), dim);
|
||||
AstConst* const newp = dimensionValue(
|
||||
nodep->fileline(), nodep->fromp()->dtypep(), nodep->attrType(), dim);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
} else if (VN_IS(nodep->dimp(), Const)) {
|
||||
const int dim = VN_AS(nodep->dimp(), Const)->toSInt();
|
||||
AstConst* newp = dimensionValue(nodep->fileline(), nodep->fromp()->dtypep(),
|
||||
nodep->attrType(), dim);
|
||||
AstConst* const newp = dimensionValue(
|
||||
nodep->fileline(), nodep->fromp()->dtypep(), nodep->attrType(), dim);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
} else { // Need a runtime lookup table. Yuk.
|
||||
UASSERT_OBJ(nodep->fromp() && nodep->fromp()->dtypep(), nodep,
|
||||
"Unsized expression");
|
||||
AstVar* varp
|
||||
AstVar* const varp
|
||||
= dimensionVarp(nodep->fromp()->dtypep(), nodep->attrType(), msbdim);
|
||||
AstNode* dimp = nodep->dimp()->unlinkFrBack();
|
||||
AstVarRef* varrefp = new AstVarRef(nodep->fileline(), varp, VAccess::READ);
|
||||
AstNode* const dimp = nodep->dimp()->unlinkFrBack();
|
||||
AstVarRef* const varrefp
|
||||
= new AstVarRef(nodep->fileline(), varp, VAccess::READ);
|
||||
varrefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgAddp());
|
||||
AstNode* newp = new AstArraySel(nodep->fileline(), varrefp, dimp);
|
||||
AstNode* const newp = new AstArraySel(nodep->fileline(), varrefp, dimp);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
|
|
@ -1428,7 +1432,7 @@ private:
|
|||
case AstAttrType::TYPENAME: {
|
||||
UASSERT_OBJ(nodep->fromp(), nodep, "Unprovided expression");
|
||||
const string result = nodep->fromp()->dtypep()->prettyDTypeName();
|
||||
AstNode* newp = new AstConst(nodep->fileline(), AstConst::String(), result);
|
||||
AstNode* const newp = new AstConst(nodep->fileline(), AstConst::String(), result);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
break;
|
||||
|
|
@ -1455,12 +1459,12 @@ private:
|
|||
if (nodep->didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed
|
||||
|
||||
if (nodep->subDTypep() == nodep->basicp()) { // Innermost dimension
|
||||
AstBasicDType* basicp = nodep->basicp();
|
||||
AstBasicDType* const basicp = nodep->basicp();
|
||||
// If basic dtype is LOGIC_IMPLICIT, it is actually 1 bit LOGIC
|
||||
if (basicp->implicit()) {
|
||||
UASSERT_OBJ(basicp->width() <= 1, basicp,
|
||||
"must be 1 bit but actually " << basicp->width() << " bits");
|
||||
AstBasicDType* newp = new AstBasicDType(
|
||||
AstBasicDType* const newp = new AstBasicDType(
|
||||
basicp->fileline(), AstBasicDTypeKwd::LOGIC, basicp->numeric());
|
||||
newp->widthForce(1, 1);
|
||||
basicp->replaceWith(newp);
|
||||
|
|
@ -1472,7 +1476,7 @@ private:
|
|||
// Cleanup array size
|
||||
userIterateAndNext(nodep->rangep(), WidthVP(SELF, BOTH).p());
|
||||
nodep->dtypep(nodep); // The array itself, not subDtype
|
||||
if (auto* adtypep = VN_CAST(nodep, UnpackArrayDType)) {
|
||||
if (auto* const adtypep = VN_CAST(nodep, UnpackArrayDType)) {
|
||||
// Historically array elements have width of the ref type not the full array
|
||||
nodep->widthFromSub(nodep->subDTypep());
|
||||
if (nodep->subDTypep()->skipRefp()->isCompound()) adtypep->isCompound(true);
|
||||
|
|
@ -1496,9 +1500,9 @@ private:
|
|||
userIterateChildren(nodep, WidthVP(SELF, BOTH).p());
|
||||
// We must edit when dtype still under normal nodes and before type table
|
||||
// See notes in iterateEditMoveDTypep
|
||||
AstNodeDType* childp = nodep->childDTypep();
|
||||
AstNodeDType* const childp = nodep->childDTypep();
|
||||
childp->unlinkFrBack();
|
||||
AstNode* elementsp = nodep->elementsp()->unlinkFrBack();
|
||||
AstNode* const elementsp = nodep->elementsp()->unlinkFrBack();
|
||||
AstNode* newp;
|
||||
if (VN_IS(elementsp, Unbounded)) {
|
||||
newp = new AstQueueDType(nodep->fileline(), VFlagChildDType(), childp, nullptr);
|
||||
|
|
@ -1593,7 +1597,7 @@ private:
|
|||
if (nodep->typeofp()) { // type(typeofp_expression)
|
||||
// Type comes from expression's type
|
||||
userIterateAndNext(nodep->typeofp(), WidthVP(SELF, BOTH).p());
|
||||
AstNode* typeofp = nodep->typeofp();
|
||||
AstNode* const typeofp = nodep->typeofp();
|
||||
nodep->typedefp(nullptr);
|
||||
nodep->refDTypep(typeofp->dtypep());
|
||||
VL_DO_DANGLING(typeofp->unlinkFrBack()->deleteTree(), typeofp);
|
||||
|
|
@ -1621,7 +1625,7 @@ private:
|
|||
}
|
||||
virtual void visit(AstTypedef* nodep) override {
|
||||
if (nodep->didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed
|
||||
if (auto* refp = checkRefToTypedefRecurse(nodep, nodep)) {
|
||||
if (auto* const refp = checkRefToTypedefRecurse(nodep, nodep)) {
|
||||
nodep->v3error("Typedef has self-reference: " << nodep->prettyNameQ() << '\n'
|
||||
<< nodep->warnContextPrimary() << '\n'
|
||||
<< refp->warnOther()
|
||||
|
|
@ -1644,9 +1648,9 @@ private:
|
|||
virtual void visit(AstCastDynamic* nodep) override {
|
||||
nodep->dtypeChgWidthSigned(32, 1, VSigning::SIGNED); // Spec says integer return
|
||||
userIterateChildren(nodep, WidthVP(SELF, BOTH).p());
|
||||
AstNodeDType* toDtp = nodep->top()->dtypep()->skipRefToEnump();
|
||||
AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefToEnump();
|
||||
FileLine* fl = nodep->fileline();
|
||||
AstNodeDType* const toDtp = nodep->top()->dtypep()->skipRefToEnump();
|
||||
AstNodeDType* const fromDtp = nodep->fromp()->dtypep()->skipRefToEnump();
|
||||
FileLine* const fl = nodep->fileline();
|
||||
const auto castable = computeCastable(toDtp, fromDtp, nodep->fromp());
|
||||
AstNode* newp;
|
||||
if (castable == DYNAMIC_CLASS) {
|
||||
|
|
@ -1657,16 +1661,17 @@ private:
|
|||
// elimination should do much the same
|
||||
// Form: "( ((v > size) ? false : enum_valid[v[N:0]])
|
||||
// ? ExprStmt(ExprAssign(out, Cast(v, type)), 1) : 0)"
|
||||
auto* enumDtp = VN_AS(toDtp, EnumDType);
|
||||
auto* const enumDtp = VN_AS(toDtp, EnumDType);
|
||||
UASSERT_OBJ(enumDtp, nodep, "$cast determined as enum, but not enum type");
|
||||
uint64_t maxval = enumMaxValue(nodep, enumDtp);
|
||||
const int selwidth = V3Number::log2b(maxval) + 1; // Width to address a bit
|
||||
AstVar* varp = enumVarp(enumDtp, AstAttrType::ENUM_VALID, (1ULL << selwidth) - 1);
|
||||
AstVarRef* varrefp = new AstVarRef(fl, varp, VAccess::READ);
|
||||
AstVar* const varp
|
||||
= enumVarp(enumDtp, AstAttrType::ENUM_VALID, (1ULL << selwidth) - 1);
|
||||
AstVarRef* const varrefp = new AstVarRef(fl, varp, VAccess::READ);
|
||||
varrefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgAddp());
|
||||
FileLine* fl_nowarn = new FileLine(fl);
|
||||
FileLine* const fl_nowarn = new FileLine(fl);
|
||||
fl_nowarn->warnOff(V3ErrorCode::WIDTH, true);
|
||||
auto* testp = new AstCond{
|
||||
auto* const testp = new AstCond{
|
||||
fl,
|
||||
new AstGt{fl_nowarn, nodep->fromp()->cloneTree(false),
|
||||
new AstConst{fl_nowarn, AstConst::Unsized64{}, maxval}},
|
||||
|
|
@ -1712,9 +1717,9 @@ private:
|
|||
// nodep->dtp could be data type, or a primary_constant
|
||||
// Don't iterate lhsp, will deal with that once convert the type
|
||||
V3Const::constifyParamsEdit(nodep->dtp()); // itemp may change
|
||||
if (AstConst* constp = VN_CAST(nodep->dtp(), Const)) {
|
||||
if (AstConst* const constp = VN_CAST(nodep->dtp(), Const)) {
|
||||
constp->unlinkFrBack();
|
||||
AstNode* newp
|
||||
AstNode* const newp
|
||||
= new AstCastSize(nodep->fileline(), nodep->lhsp()->unlinkFrBack(), constp);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
|
|
@ -1730,8 +1735,8 @@ private:
|
|||
if (m_vup->prelim()) {
|
||||
// if (debug()) nodep->dumpTree(cout, " CastPre: ");
|
||||
userIterateAndNext(nodep->fromp(), WidthVP(SELF, PRELIM).p());
|
||||
AstNodeDType* toDtp = nodep->dtypep()->skipRefToEnump();
|
||||
AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefToEnump();
|
||||
AstNodeDType* const toDtp = nodep->dtypep()->skipRefToEnump();
|
||||
AstNodeDType* const fromDtp = nodep->fromp()->dtypep()->skipRefToEnump();
|
||||
const auto castable = computeCastable(toDtp, fromDtp, nodep->fromp());
|
||||
bool bad = false;
|
||||
if (castable == UNSUPPORTED) {
|
||||
|
|
@ -1805,7 +1810,7 @@ private:
|
|||
if (m_vup->final()) {
|
||||
iterateCheck(nodep, "value", nodep->lhsp(), SELF, FINAL, nodep->lhsp()->dtypep(),
|
||||
EXTEND_EXP, false);
|
||||
AstNode* underp = nodep->lhsp()->unlinkFrBack();
|
||||
AstNode* const underp = nodep->lhsp()->unlinkFrBack();
|
||||
if (debug()) underp->dumpTree(cout, " CastRep: ");
|
||||
nodep->replaceWith(underp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
|
|
@ -1827,7 +1832,7 @@ private:
|
|||
}
|
||||
if (m_vup->final()) {
|
||||
// CastSize not needed once sizes determined
|
||||
AstNode* underp = nodep->lhsp()->unlinkFrBack();
|
||||
AstNode* const underp = nodep->lhsp()->unlinkFrBack();
|
||||
underp->dtypeFrom(nodep);
|
||||
nodep->replaceWith(underp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
|
|
@ -1848,7 +1853,7 @@ private:
|
|||
// So two steps, first do the calculation's width (max of the two widths)
|
||||
{
|
||||
const int calcWidth = std::max(width, underDtp->width());
|
||||
AstNodeDType* calcDtp
|
||||
AstNodeDType* const calcDtp
|
||||
= (underDtp->isFourstate()
|
||||
? nodep->findLogicDType(calcWidth, calcWidth, underDtp->numeric())
|
||||
: nodep->findBitDType(calcWidth, calcWidth, underDtp->numeric()));
|
||||
|
|
@ -1861,9 +1866,10 @@ private:
|
|||
// if (debug()) nodep->dumpTree(cout, " CastSizeClc: ");
|
||||
// Next step, make the proper output width
|
||||
{
|
||||
AstNodeDType* outDtp = (underDtp->isFourstate()
|
||||
? nodep->findLogicDType(width, width, underDtp->numeric())
|
||||
: nodep->findBitDType(width, width, underDtp->numeric()));
|
||||
AstNodeDType* const outDtp
|
||||
= (underDtp->isFourstate()
|
||||
? nodep->findLogicDType(width, width, underDtp->numeric())
|
||||
: nodep->findBitDType(width, width, underDtp->numeric()));
|
||||
nodep->dtypep(outDtp);
|
||||
// We ignore warnings as that is sort of the point of a cast
|
||||
widthCheckSized(nodep, "Cast expr", underp, outDtp, EXTEND_EXP, false);
|
||||
|
|
@ -1889,10 +1895,11 @@ private:
|
|||
// Make sure dtype is sized
|
||||
nodep->dtypep(iterateEditMoveDTypep(nodep, nodep->subDTypep()));
|
||||
UASSERT_OBJ(nodep->dtypep(), nodep, "No dtype determined for var");
|
||||
if (AstUnsizedArrayDType* unsizedp = VN_CAST(nodep->dtypeSkipRefp(), UnsizedArrayDType)) {
|
||||
if (AstUnsizedArrayDType* const unsizedp
|
||||
= VN_CAST(nodep->dtypeSkipRefp(), UnsizedArrayDType)) {
|
||||
if (!(m_ftaskp && m_ftaskp->dpiImport())) {
|
||||
UINFO(9, "Unsized becomes dynamic array " << nodep << endl);
|
||||
AstDynArrayDType* newp
|
||||
AstDynArrayDType* const newp
|
||||
= new AstDynArrayDType(unsizedp->fileline(), unsizedp->subDTypep());
|
||||
nodep->dtypep(newp);
|
||||
v3Global.rootp()->typeTablep()->addTypesp(newp);
|
||||
|
|
@ -1900,7 +1907,7 @@ private:
|
|||
}
|
||||
if (VN_IS(nodep->dtypep()->skipRefToConstp(), ConstDType)) nodep->isConst(true);
|
||||
// Parameters if implicit untyped inherit from what they are assigned to
|
||||
AstBasicDType* bdtypep = VN_CAST(nodep->dtypep(), BasicDType);
|
||||
AstBasicDType* const bdtypep = VN_CAST(nodep->dtypep(), BasicDType);
|
||||
bool didchk = false;
|
||||
const bool implicitParam = nodep->isParam() && bdtypep && bdtypep->implicit();
|
||||
if (implicitParam) {
|
||||
|
|
@ -1916,7 +1923,7 @@ private:
|
|||
VL_DANGLING(bdtypep);
|
||||
} else {
|
||||
int width = 0;
|
||||
AstBasicDType* valueBdtypep = nodep->valuep()->dtypep()->basicp();
|
||||
AstBasicDType* const valueBdtypep = nodep->valuep()->dtypep()->basicp();
|
||||
bool issigned = false;
|
||||
if (bdtypep->isNosign()) {
|
||||
if (valueBdtypep && valueBdtypep->isSigned()) issigned = true;
|
||||
|
|
@ -2052,7 +2059,7 @@ private:
|
|||
itemp->valuep(new AstConst(itemp->fileline(), num));
|
||||
}
|
||||
|
||||
AstConst* constp = VN_AS(itemp->valuep(), Const);
|
||||
AstConst* const constp = VN_AS(itemp->valuep(), Const);
|
||||
if (constp->num().isFourState() && nodep->dtypep()->basicp()
|
||||
&& !nodep->dtypep()->basicp()->isFourstate()) {
|
||||
itemp->v3error("Enum value with X/Zs cannot be assigned to non-fourstate type "
|
||||
|
|
@ -2061,7 +2068,7 @@ private:
|
|||
num.opAssign(constp->num());
|
||||
// Look for duplicates
|
||||
if (inits.find(num) != inits.end()) { // IEEE says illegal
|
||||
AstNode* otherp = inits.find(num)->second;
|
||||
AstNode* const otherp = inits.find(num)->second;
|
||||
itemp->v3error("Overlapping enumeration value: "
|
||||
<< itemp->prettyNameQ() << '\n'
|
||||
<< itemp->warnContextPrimary() << '\n'
|
||||
|
|
@ -2075,7 +2082,7 @@ private:
|
|||
}
|
||||
virtual void visit(AstEnumItem* nodep) override {
|
||||
UINFO(5, " ENUMITEM " << nodep << endl);
|
||||
AstNodeDType* vdtypep = m_vup->dtypep();
|
||||
AstNodeDType* const vdtypep = m_vup->dtypep();
|
||||
UASSERT_OBJ(vdtypep, nodep, "ENUMITEM not under ENUM");
|
||||
nodep->dtypep(vdtypep);
|
||||
if (nodep->valuep()) { // else the value will be assigned sequentially
|
||||
|
|
@ -2102,7 +2109,7 @@ private:
|
|||
}
|
||||
virtual void visit(AstConsAssoc* nodep) override {
|
||||
// Type computed when constructed here
|
||||
auto* vdtypep = VN_AS(m_vup->dtypep()->skipRefp(), AssocArrayDType);
|
||||
auto* const vdtypep = VN_AS(m_vup->dtypep()->skipRefp(), AssocArrayDType);
|
||||
UASSERT_OBJ(vdtypep, nodep, "ConsAssoc requires assoc upper parent data type");
|
||||
if (m_vup->prelim()) {
|
||||
nodep->dtypeFrom(vdtypep);
|
||||
|
|
@ -2114,7 +2121,7 @@ private:
|
|||
}
|
||||
virtual void visit(AstSetAssoc* nodep) override {
|
||||
// Type computed when constructed here
|
||||
auto* vdtypep = VN_AS(m_vup->dtypep()->skipRefp(), AssocArrayDType);
|
||||
auto* const vdtypep = VN_AS(m_vup->dtypep()->skipRefp(), AssocArrayDType);
|
||||
UASSERT_OBJ(vdtypep, nodep, "SetsAssoc requires assoc upper parent data type");
|
||||
if (m_vup->prelim()) {
|
||||
nodep->dtypeFrom(vdtypep);
|
||||
|
|
@ -2127,7 +2134,7 @@ private:
|
|||
}
|
||||
virtual void visit(AstConsDynArray* nodep) override {
|
||||
// Type computed when constructed here
|
||||
AstDynArrayDType* vdtypep = VN_AS(m_vup->dtypep()->skipRefp(), DynArrayDType);
|
||||
AstDynArrayDType* const vdtypep = VN_AS(m_vup->dtypep()->skipRefp(), DynArrayDType);
|
||||
UASSERT_OBJ(vdtypep, nodep, "ConsDynArray requires queue upper parent data type");
|
||||
if (m_vup->prelim()) {
|
||||
userIterateAndNext(nodep->lhsp(), WidthVP(vdtypep, PRELIM).p());
|
||||
|
|
@ -2159,7 +2166,7 @@ private:
|
|||
}
|
||||
virtual void visit(AstConsQueue* nodep) override {
|
||||
// Type computed when constructed here
|
||||
AstQueueDType* vdtypep = VN_AS(m_vup->dtypep()->skipRefp(), QueueDType);
|
||||
AstQueueDType* const vdtypep = VN_AS(m_vup->dtypep()->skipRefp(), QueueDType);
|
||||
UASSERT_OBJ(vdtypep, nodep, "ConsQueue requires queue upper parent data type");
|
||||
if (m_vup->prelim()) {
|
||||
userIterateAndNext(nodep->lhsp(), WidthVP(vdtypep, PRELIM).p());
|
||||
|
|
|
|||
|
|
@ -60,8 +60,8 @@ private:
|
|||
|
||||
// RETURN TYPE
|
||||
struct FromData {
|
||||
AstNodeDType* m_errp; // Node that was found, for error reporting if not known type
|
||||
AstNodeDType* m_dtypep; // Data type for the 'from' slice
|
||||
AstNodeDType* const m_errp; // Node that was found, for error reporting if not known type
|
||||
AstNodeDType* const m_dtypep; // Data type for the 'from' slice
|
||||
VNumRange m_fromRange; // Numeric range bounds for the 'from' slice
|
||||
FromData(AstNodeDType* errp, AstNodeDType* dtypep, const VNumRange& fromRange)
|
||||
: m_errp{errp}
|
||||
|
|
@ -81,10 +81,10 @@ private:
|
|||
break;
|
||||
}
|
||||
UASSERT_OBJ(basefromp && basefromp->dtypep(), nodep, "Select with no from dtype");
|
||||
AstNodeDType* ddtypep = basefromp->dtypep()->skipRefp();
|
||||
AstNodeDType* errp = ddtypep;
|
||||
AstNodeDType* const ddtypep = basefromp->dtypep()->skipRefp();
|
||||
AstNodeDType* const errp = ddtypep;
|
||||
UINFO(9, " fromData.ddtypep = " << ddtypep << endl);
|
||||
if (const AstNodeArrayDType* adtypep = VN_CAST(ddtypep, NodeArrayDType)) {
|
||||
if (const AstNodeArrayDType* const adtypep = VN_CAST(ddtypep, NodeArrayDType)) {
|
||||
fromRange = adtypep->declRange();
|
||||
} else if (VN_IS(ddtypep, AssocArrayDType)) {
|
||||
} else if (VN_IS(ddtypep, DynArrayDType)) {
|
||||
|
|
@ -122,16 +122,17 @@ private:
|
|||
V3Number num(lhsp, lhsp->width());
|
||||
num.opSub(VN_AS(lhsp, Const)->num(), V3Number(lhsp, 32, rhs));
|
||||
num.isSigned(lhsp->isSigned());
|
||||
AstNode* newp = new AstConst(lhsp->fileline(), num);
|
||||
AstNode* const newp = new AstConst(lhsp->fileline(), num);
|
||||
return newp;
|
||||
} else if (rhs > 0) {
|
||||
AstNode* newp = new AstSub(lhsp->fileline(), lhsp,
|
||||
new AstConst(lhsp->fileline(), AstConst::Unsized32(), rhs));
|
||||
AstNode* const newp
|
||||
= new AstSub(lhsp->fileline(), lhsp,
|
||||
new AstConst(lhsp->fileline(), AstConst::Unsized32(), rhs));
|
||||
// We must make sure sub gets sign of original value, not from the constant
|
||||
newp->dtypeFrom(lhsp);
|
||||
return newp;
|
||||
} else { // rhs < 0;
|
||||
AstNode* newp
|
||||
AstNode* const newp
|
||||
= new AstAdd(lhsp->fileline(), lhsp,
|
||||
new AstConst(lhsp->fileline(), AstConst::Unsized32(), -rhs));
|
||||
// We must make sure sub gets sign of original value, not from the constant
|
||||
|
|
@ -142,7 +143,7 @@ private:
|
|||
AstNode* newSubNeg(vlsint32_t lhs, AstNode* rhsp) {
|
||||
// Return lhs-rhs
|
||||
// We must make sure sub gets sign of original value
|
||||
AstNode* newp = new AstSub(
|
||||
AstNode* const newp = new AstSub(
|
||||
rhsp->fileline(), new AstConst(rhsp->fileline(), AstConst::Unsized32(), lhs), rhsp);
|
||||
newp->dtypeFrom(rhsp); // Important as AstSub default is lhs's sign
|
||||
return newp;
|
||||
|
|
@ -160,11 +161,11 @@ private:
|
|||
} else {
|
||||
if (fromRange.littleEndian()) {
|
||||
// reg [1:3] was swapped to [3:1] (lsbEndianedp==3) and needs a SUB(3,under)
|
||||
AstNode* newp = newSubNeg(fromRange.hi(), underp);
|
||||
AstNode* const newp = newSubNeg(fromRange.hi(), underp);
|
||||
return newp;
|
||||
} else {
|
||||
// reg [3:1] needs a SUB(under,1)
|
||||
AstNode* newp = newSubNeg(underp, fromRange.lo());
|
||||
AstNode* const newp = newSubNeg(underp, fromRange.lo());
|
||||
return newp;
|
||||
}
|
||||
}
|
||||
|
|
@ -179,7 +180,7 @@ private:
|
|||
// Need a slice data type, which is an array of the extracted
|
||||
// type, but with (presumably) different size
|
||||
VNumRange newRange(msb, lsb, nodep->declRange().littleEndian());
|
||||
AstNodeDType* vardtypep
|
||||
AstNodeDType* const vardtypep
|
||||
= new AstPackArrayDType(nodep->fileline(),
|
||||
nodep->subDTypep(), // Need to strip off array reference
|
||||
new AstRange(nodep->fileline(), newRange));
|
||||
|
|
@ -204,20 +205,20 @@ private:
|
|||
UINFO(6, "SELBIT " << nodep << endl);
|
||||
if (debug() >= 9) nodep->backp()->dumpTree(cout, "--SELBT0: ");
|
||||
// lhsp/rhsp do not need to be constant
|
||||
AstNode* fromp = nodep->fromp()->unlinkFrBack();
|
||||
AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); // bit we're extracting
|
||||
AstNode* const fromp = nodep->fromp()->unlinkFrBack();
|
||||
AstNode* const rhsp = nodep->rhsp()->unlinkFrBack(); // bit we're extracting
|
||||
if (debug() >= 9) nodep->dumpTree(cout, "--SELBT2: ");
|
||||
const FromData fromdata = fromDataForArray(nodep, fromp);
|
||||
AstNodeDType* ddtypep = fromdata.m_dtypep;
|
||||
AstNodeDType* const ddtypep = fromdata.m_dtypep;
|
||||
const VNumRange fromRange = fromdata.m_fromRange;
|
||||
UINFO(6, " ddtypep " << ddtypep << endl);
|
||||
if (AstUnpackArrayDType* adtypep = VN_CAST(ddtypep, UnpackArrayDType)) {
|
||||
if (AstUnpackArrayDType* const adtypep = VN_CAST(ddtypep, UnpackArrayDType)) {
|
||||
// SELBIT(array, index) -> ARRAYSEL(array, index)
|
||||
AstNode* subp = rhsp;
|
||||
if (fromRange.lo() != 0 || fromRange.hi() < 0) {
|
||||
subp = newSubNeg(subp, fromRange.lo());
|
||||
}
|
||||
AstArraySel* newp = new AstArraySel(nodep->fileline(), fromp, subp);
|
||||
AstArraySel* const newp = new AstArraySel(nodep->fileline(), fromp, subp);
|
||||
newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off array reference
|
||||
if (debug() >= 9) newp->dumpTree(cout, "--SELBTn: ");
|
||||
nodep->replaceWith(newp);
|
||||
|
|
@ -235,7 +236,7 @@ private:
|
|||
"Array extraction with width miscomputed " << adtypep->width() << "/"
|
||||
<< fromRange.elements());
|
||||
const int elwidth = adtypep->width() / fromRange.elements();
|
||||
AstSel* newp = new AstSel(
|
||||
AstSel* const newp = new AstSel(
|
||||
nodep->fileline(), fromp,
|
||||
new AstMul(nodep->fileline(),
|
||||
new AstConst(nodep->fileline(), AstConst::Unsized32(), elwidth), subp),
|
||||
|
|
@ -248,31 +249,31 @@ private:
|
|||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (AstAssocArrayDType* adtypep = VN_CAST(ddtypep, AssocArrayDType)) {
|
||||
// SELBIT(array, index) -> ASSOCSEL(array, index)
|
||||
AstNode* subp = rhsp;
|
||||
AstAssocSel* newp = new AstAssocSel(nodep->fileline(), fromp, subp);
|
||||
AstNode* const subp = rhsp;
|
||||
AstAssocSel* const newp = new AstAssocSel(nodep->fileline(), fromp, subp);
|
||||
newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off array reference
|
||||
if (debug() >= 9) newp->dumpTree(cout, "--SELBTn: ");
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (AstDynArrayDType* adtypep = VN_CAST(ddtypep, DynArrayDType)) {
|
||||
// SELBIT(array, index) -> CMETHODCALL(queue, "at", index)
|
||||
AstNode* subp = rhsp;
|
||||
AstCMethodHard* newp = new AstCMethodHard(nodep->fileline(), fromp, "at", subp);
|
||||
AstNode* const subp = rhsp;
|
||||
AstCMethodHard* const newp = new AstCMethodHard(nodep->fileline(), fromp, "at", subp);
|
||||
newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off queue reference
|
||||
if (debug() >= 9) newp->dumpTree(cout, "--SELBTq: ");
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (AstQueueDType* adtypep = VN_CAST(ddtypep, QueueDType)) {
|
||||
// SELBIT(array, index) -> CMETHODCALL(queue, "at", index)
|
||||
AstNode* subp = rhsp;
|
||||
AstCMethodHard* newp = new AstCMethodHard(nodep->fileline(), fromp, "at", subp);
|
||||
AstNode* const subp = rhsp;
|
||||
AstCMethodHard* const newp = new AstCMethodHard(nodep->fileline(), fromp, "at", subp);
|
||||
newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off queue reference
|
||||
if (debug() >= 9) newp->dumpTree(cout, "--SELBTq: ");
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (VN_IS(ddtypep, BasicDType) && ddtypep->isString()) {
|
||||
// SELBIT(string, index) -> GETC(string, index)
|
||||
AstNodeVarRef* varrefp = VN_CAST(fromp, NodeVarRef);
|
||||
AstNodeVarRef* const varrefp = VN_CAST(fromp, NodeVarRef);
|
||||
if (!varrefp) {
|
||||
nodep->v3warn(E_UNSUPPORTED,
|
||||
"Unsupported: String array operation on non-variable");
|
||||
|
|
@ -288,9 +289,10 @@ private:
|
|||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (VN_IS(ddtypep, BasicDType)) {
|
||||
// SELBIT(range, index) -> SEL(array, index, 1)
|
||||
AstSel* newp = new AstSel(nodep->fileline(), fromp, newSubLsbOf(rhsp, fromRange),
|
||||
// Unsized so width from user
|
||||
new AstConst(nodep->fileline(), AstConst::Unsized32(), 1));
|
||||
AstSel* const newp
|
||||
= new AstSel(nodep->fileline(), fromp, newSubLsbOf(rhsp, fromRange),
|
||||
// Unsized so width from user
|
||||
new AstConst(nodep->fileline(), AstConst::Unsized32(), 1));
|
||||
newp->declRange(fromRange);
|
||||
UINFO(6, " new " << newp << endl);
|
||||
if (debug() >= 9) newp->dumpTree(cout, "--SELBTn: ");
|
||||
|
|
@ -298,9 +300,10 @@ private:
|
|||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (VN_IS(ddtypep, NodeUOrStructDType)) { // A bit from the packed struct
|
||||
// SELBIT(range, index) -> SEL(array, index, 1)
|
||||
AstSel* newp = new AstSel(nodep->fileline(), fromp, newSubLsbOf(rhsp, fromRange),
|
||||
// Unsized so width from user
|
||||
new AstConst(nodep->fileline(), AstConst::Unsized32(), 1));
|
||||
AstSel* const newp
|
||||
= new AstSel(nodep->fileline(), fromp, newSubLsbOf(rhsp, fromRange),
|
||||
// Unsized so width from user
|
||||
new AstConst(nodep->fileline(), AstConst::Unsized32(), 1));
|
||||
newp->declRange(fromRange);
|
||||
UINFO(6, " new " << newp << endl);
|
||||
if (debug() >= 9) newp->dumpTree(cout, "--SELBTn: ");
|
||||
|
|
@ -329,14 +332,14 @@ private:
|
|||
"First value of [a:b] isn't a constant, maybe you want +: or -:");
|
||||
checkConstantOrReplace(nodep->rightp(),
|
||||
"Second value of [a:b] isn't a constant, maybe you want +: or -:");
|
||||
AstNode* fromp = nodep->fromp()->unlinkFrBack();
|
||||
AstNode* msbp = nodep->rhsp()->unlinkFrBack();
|
||||
AstNode* lsbp = nodep->thsp()->unlinkFrBack();
|
||||
AstNode* const fromp = nodep->fromp()->unlinkFrBack();
|
||||
AstNode* const msbp = nodep->rhsp()->unlinkFrBack();
|
||||
AstNode* const lsbp = nodep->thsp()->unlinkFrBack();
|
||||
vlsint32_t msb = VN_AS(msbp, Const)->toSInt();
|
||||
vlsint32_t lsb = VN_AS(lsbp, Const)->toSInt();
|
||||
vlsint32_t elem = (msb > lsb) ? (msb - lsb + 1) : (lsb - msb + 1);
|
||||
const FromData fromdata = fromDataForArray(nodep, fromp);
|
||||
AstNodeDType* ddtypep = fromdata.m_dtypep;
|
||||
AstNodeDType* const ddtypep = fromdata.m_dtypep;
|
||||
const VNumRange fromRange = fromdata.m_fromRange;
|
||||
if (VN_IS(ddtypep, UnpackArrayDType)) {
|
||||
// Slice extraction
|
||||
|
|
@ -345,11 +348,11 @@ private:
|
|||
nodep->replaceWith(fromp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (fromRange.elements() == 1) { // Extracting single element
|
||||
AstArraySel* newp = new AstArraySel(nodep->fileline(), fromp, lsbp);
|
||||
AstArraySel* const newp = new AstArraySel(nodep->fileline(), fromp, lsbp);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else { // Slice
|
||||
AstSliceSel* newp
|
||||
AstSliceSel* const newp
|
||||
= new AstSliceSel{nodep->fileline(), fromp,
|
||||
VNumRange{msb - fromRange.lo(), lsb - fromRange.lo()}};
|
||||
nodep->replaceWith(newp);
|
||||
|
|
@ -379,7 +382,7 @@ private:
|
|||
lsb = x;
|
||||
}
|
||||
const int elwidth = adtypep->width() / fromRange.elements();
|
||||
AstSel* newp = new AstSel(
|
||||
AstSel* const newp = new AstSel(
|
||||
nodep->fileline(), fromp,
|
||||
new AstMul(nodep->fileline(), newSubLsbOf(lsbp, fromRange),
|
||||
new AstConst(nodep->fileline(), AstConst::Unsized32(), elwidth)),
|
||||
|
|
@ -408,10 +411,11 @@ private:
|
|||
msb = lsb;
|
||||
lsb = x;
|
||||
}
|
||||
AstNode* widthp = new AstConst(msbp->fileline(),
|
||||
AstConst::Unsized32(), // Unsized so width from user
|
||||
msb + 1 - lsb);
|
||||
AstSel* newp
|
||||
AstNode* const widthp
|
||||
= new AstConst(msbp->fileline(),
|
||||
AstConst::Unsized32(), // Unsized so width from user
|
||||
msb + 1 - lsb);
|
||||
AstSel* const newp
|
||||
= new AstSel(nodep->fileline(), fromp, newSubLsbOf(lsbp, fromRange), widthp);
|
||||
newp->declRange(fromRange);
|
||||
UINFO(6, " new " << newp << endl);
|
||||
|
|
@ -430,10 +434,11 @@ private:
|
|||
msb = lsb;
|
||||
lsb = x;
|
||||
}
|
||||
AstNode* widthp = new AstConst(msbp->fileline(),
|
||||
AstConst::Unsized32(), // Unsized so width from user
|
||||
msb + 1 - lsb);
|
||||
AstSel* newp
|
||||
AstNode* const widthp
|
||||
= new AstConst(msbp->fileline(),
|
||||
AstConst::Unsized32(), // Unsized so width from user
|
||||
msb + 1 - lsb);
|
||||
AstSel* const newp
|
||||
= new AstSel(nodep->fileline(), fromp, newSubLsbOf(lsbp, fromRange), widthp);
|
||||
newp->declRange(fromRange);
|
||||
UINFO(6, " new " << newp << endl);
|
||||
|
|
@ -441,7 +446,7 @@ private:
|
|||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (VN_IS(ddtypep, QueueDType)) {
|
||||
auto* newp = new AstCMethodHard(nodep->fileline(), fromp, "slice", msbp);
|
||||
auto* const newp = new AstCMethodHard(nodep->fileline(), fromp, "slice", msbp);
|
||||
msbp->addNext(lsbp);
|
||||
newp->dtypep(ddtypep);
|
||||
newp->didWidth(true);
|
||||
|
|
@ -475,9 +480,9 @@ private:
|
|||
checkConstantOrReplace(nodep->thsp(), "Width of :+ or :- bit extract isn't a constant");
|
||||
if (debug() >= 9) nodep->dumpTree(cout, "--SELPM3: ");
|
||||
// Now replace it with an AstSel
|
||||
AstNode* fromp = nodep->fromp()->unlinkFrBack();
|
||||
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
|
||||
AstNode* widthp = nodep->thsp()->unlinkFrBack();
|
||||
AstNode* const fromp = nodep->fromp()->unlinkFrBack();
|
||||
AstNode* const rhsp = nodep->rhsp()->unlinkFrBack();
|
||||
AstNode* const widthp = nodep->thsp()->unlinkFrBack();
|
||||
warnTri(rhsp);
|
||||
const int width = VN_AS(widthp, Const)->toSInt();
|
||||
if (width > (1 << 28)) {
|
||||
|
|
@ -486,7 +491,7 @@ private:
|
|||
}
|
||||
if (width < 0) nodep->v3error("Width of :+ or :- is < 0: " << widthp->prettyName());
|
||||
const FromData fromdata = fromDataForArray(nodep, fromp);
|
||||
AstNodeDType* ddtypep = fromdata.m_dtypep;
|
||||
AstNodeDType* const ddtypep = fromdata.m_dtypep;
|
||||
const VNumRange fromRange = fromdata.m_fromRange;
|
||||
if (VN_IS(ddtypep, UnpackArrayDType)) {
|
||||
// Slice +: and -: extraction
|
||||
|
|
@ -496,7 +501,7 @@ private:
|
|||
nodep->replaceWith(fromp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (fromRange.elements() == 1) { // Extracting single element
|
||||
AstArraySel* newp = new AstArraySel(nodep->fileline(), fromp, rhsp);
|
||||
AstArraySel* const newp = new AstArraySel(nodep->fileline(), fromp, rhsp);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (VN_IS(rhsp, Const)) { // Slice
|
||||
|
|
@ -507,8 +512,8 @@ private:
|
|||
// up array: lsb/hi -: width
|
||||
vlsint32_t msb = VN_IS(nodep, SelPlus) ? rhs + width - 1 : rhs;
|
||||
vlsint32_t lsb = VN_IS(nodep, SelPlus) ? rhs : rhs - width + 1;
|
||||
AstSliceSel* newp = new AstSliceSel(nodep->fileline(), fromp,
|
||||
VNumRange(msb, lsb, fromRange.littleEndian()));
|
||||
AstSliceSel* const newp = new AstSliceSel(
|
||||
nodep->fileline(), fromp, VNumRange(msb, lsb, fromRange.littleEndian()));
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else {
|
||||
|
|
@ -519,7 +524,7 @@ private:
|
|||
&& VN_AS(ddtypep, NodeUOrStructDType)->packedUnsup())) {
|
||||
int elwidth = 1;
|
||||
AstNode* newwidthp = widthp;
|
||||
if (const AstPackArrayDType* adtypep = VN_CAST(ddtypep, PackArrayDType)) {
|
||||
if (const AstPackArrayDType* const adtypep = VN_CAST(ddtypep, PackArrayDType)) {
|
||||
elwidth = adtypep->width() / fromRange.elements();
|
||||
newwidthp
|
||||
= new AstConst(nodep->fileline(), AstConst::Unsized32(), width * elwidth);
|
||||
|
|
@ -548,7 +553,7 @@ private:
|
|||
newlsbp = new AstMul(nodep->fileline(), newlsbp,
|
||||
new AstConst(nodep->fileline(), elwidth));
|
||||
}
|
||||
AstSel* newp = new AstSel(nodep->fileline(), fromp, newlsbp, newwidthp);
|
||||
AstSel* const newp = new AstSel(nodep->fileline(), fromp, newlsbp, newwidthp);
|
||||
newp->declRange(fromRange);
|
||||
newp->declElWidth(elwidth);
|
||||
UINFO(6, " new " << newp << endl);
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ void VlcTop::rank() {
|
|||
|
||||
VlcBuckets remaining;
|
||||
for (const auto& i : m_points) {
|
||||
VlcPoint* const pointp = &points().pointNumber(i.second);
|
||||
const VlcPoint* const pointp = &points().pointNumber(i.second);
|
||||
// If any tests hit this point, then we'll need to cover it.
|
||||
if (pointp->testsCovering()) remaining.addData(pointp->pointNum(), 1);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue