Internals: More const. No functional change intended.
This commit is contained in:
parent
010084201a
commit
cd737065f2
|
|
@ -1445,7 +1445,7 @@ vpiHandle vpi_handle(PLI_INT32 type, vpiHandle object) {
|
|||
if (const VerilatedVpioVarBase* const vop = VerilatedVpioVarBase::castp(object)) {
|
||||
if (VL_UNLIKELY(!vop->rangep())) return nullptr;
|
||||
return (new VerilatedVpioConst{vop->rangep()->left()})->castVpiHandle();
|
||||
} else if (VerilatedVpioRange* const vop = VerilatedVpioRange::castp(object)) {
|
||||
} else if (const VerilatedVpioRange* const vop = VerilatedVpioRange::castp(object)) {
|
||||
if (VL_UNLIKELY(!vop->rangep())) return nullptr;
|
||||
return (new VerilatedVpioConst{vop->rangep()->left()})->castVpiHandle();
|
||||
}
|
||||
|
|
@ -1458,7 +1458,7 @@ vpiHandle vpi_handle(PLI_INT32 type, vpiHandle object) {
|
|||
if (const VerilatedVpioVarBase* const vop = VerilatedVpioVarBase::castp(object)) {
|
||||
if (VL_UNLIKELY(!vop->rangep())) return nullptr;
|
||||
return (new VerilatedVpioConst{vop->rangep()->right()})->castVpiHandle();
|
||||
} else if (VerilatedVpioRange* const vop = VerilatedVpioRange::castp(object)) {
|
||||
} else if (const VerilatedVpioRange* const vop = VerilatedVpioRange::castp(object)) {
|
||||
if (VL_UNLIKELY(!vop->rangep())) return nullptr;
|
||||
return (new VerilatedVpioConst{vop->rangep()->right()})->castVpiHandle();
|
||||
}
|
||||
|
|
@ -1905,7 +1905,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value valuep) {
|
|||
} else if (const VerilatedVpioParam* const vop = VerilatedVpioParam::castp(object)) {
|
||||
vl_get_value(vop->varp(), vop->varDatap(), valuep, vop->fullname());
|
||||
return;
|
||||
} else if (VerilatedVpioConst* const vop = VerilatedVpioConst::castp(object)) {
|
||||
} else if (const VerilatedVpioConst* const vop = VerilatedVpioConst::castp(object)) {
|
||||
if (valuep->format == vpiIntVal) {
|
||||
valuep->value.integer = vop->num();
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -50,8 +50,8 @@ public:
|
|||
enum VertexType : uint8_t { VT_BLOCK, VT_BRANCH, VT_OUTPUT };
|
||||
|
||||
private:
|
||||
string m_name; // Only used for .dot file generation
|
||||
VertexType m_type; // Vertex type (BLOCK/BRANCH/OUTPUT)
|
||||
const string m_name; // Only used for .dot file generation
|
||||
const VertexType m_type; // Vertex type (BLOCK/BRANCH/OUTPUT)
|
||||
|
||||
string typestr() const { // "
|
||||
switch (m_type) {
|
||||
|
|
@ -342,8 +342,8 @@ public:
|
|||
|
||||
private:
|
||||
const CheckType m_check; // Combo logic or other
|
||||
AstNode* const m_alwaysp; // Always we're under
|
||||
AstNode* m_assignp = nullptr; // In assign
|
||||
const AstNode* const m_alwaysp; // Always we're under
|
||||
const AstNode* m_assignp = nullptr; // In assign
|
||||
// VISITORS
|
||||
virtual void visit(AstAssignDly* nodep) override {
|
||||
if (m_check != CT_SEQ) {
|
||||
|
|
@ -438,7 +438,7 @@ private:
|
|||
virtual void visit(AstInitial* nodep) override {
|
||||
// Relink to IACTIVE, unless already under it
|
||||
UINFO(4, " INITIAL " << nodep << endl);
|
||||
ActiveDlyVisitor dlyvisitor{nodep, ActiveDlyVisitor::CT_INITIAL};
|
||||
const ActiveDlyVisitor dlyvisitor{nodep, ActiveDlyVisitor::CT_INITIAL};
|
||||
AstActive* const wantactivep = m_namer.getIActive(nodep->fileline());
|
||||
nodep->unlinkFrBack();
|
||||
wantactivep->addStmtsp(nodep);
|
||||
|
|
@ -471,7 +471,7 @@ private:
|
|||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
return;
|
||||
}
|
||||
ActiveDlyVisitor dlyvisitor{nodep, ActiveDlyVisitor::CT_INITIAL};
|
||||
const ActiveDlyVisitor dlyvisitor{nodep, ActiveDlyVisitor::CT_INITIAL};
|
||||
if (!m_scopeFinalp) {
|
||||
m_scopeFinalp = new AstCFunc(
|
||||
nodep->fileline(), "_final_" + m_namer.scopep()->nameDotless(), m_namer.scopep());
|
||||
|
|
@ -540,7 +540,7 @@ private:
|
|||
|
||||
// Warn and/or convert any delayed assignments
|
||||
if (combo && !sequent) {
|
||||
ActiveLatchCheckVisitor latchvisitor{nodep, kwd};
|
||||
const ActiveLatchCheckVisitor latchvisitor{nodep, kwd};
|
||||
if (kwd == VAlwaysKwd::ALWAYS_LATCH) {
|
||||
ActiveDlyVisitor{nodep, ActiveDlyVisitor::CT_LATCH};
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ private:
|
|||
|
||||
// STATE
|
||||
AstNodeModule* m_modp = nullptr; // Last module
|
||||
AstBegin* m_beginp = nullptr; // Last begin
|
||||
const AstBegin* m_beginp = nullptr; // Last begin
|
||||
unsigned m_monitorNum = 0; // Global $monitor numbering (not per module)
|
||||
AstVar* m_monitorNumVarp = nullptr; // $monitor number variable
|
||||
AstVar* m_monitorOffVarp = nullptr; // $monitoroff variable
|
||||
|
|
|
|||
|
|
@ -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* const objp = static_cast<AstNode*>(::operator new(size));
|
||||
const 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* const nodep = static_cast<AstNode*>(objp);
|
||||
const AstNode* const nodep = static_cast<AstNode*>(objp);
|
||||
V3Broken::deleted(nodep);
|
||||
::operator delete(objp);
|
||||
}
|
||||
|
|
@ -995,7 +995,7 @@ 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* const headp = this;
|
||||
AstNode* tailp = this;
|
||||
const AstNode* tailp = this;
|
||||
for (AstNode* nodep = headp; nodep; nodep = nodep->nextp()) {
|
||||
nodep->checkTreeIter(backp);
|
||||
UASSERT_OBJ(headp == this || !nextp(), this,
|
||||
|
|
|
|||
20
src/V3Ast.h
20
src/V3Ast.h
|
|
@ -1008,7 +1008,7 @@ public:
|
|||
// MEMBERS
|
||||
void init(int hi, int lo, bool littleEndian) {
|
||||
if (lo > hi) {
|
||||
int t = hi;
|
||||
const int t = hi;
|
||||
hi = lo;
|
||||
lo = t;
|
||||
}
|
||||
|
|
@ -1077,11 +1077,11 @@ inline std::ostream& operator<<(std::ostream& os, const VUseType& rhs) {
|
|||
|
||||
class VBasicTypeKey final {
|
||||
public:
|
||||
int m_width; // From AstNodeDType: Bit width of operation
|
||||
int m_widthMin; // From AstNodeDType: If unsized, bitwidth of minimum implementation
|
||||
VSigning m_numeric; // From AstNodeDType: Node is signed
|
||||
AstBasicDTypeKwd m_keyword; // From AstBasicDType: What keyword created basic type
|
||||
VNumRange m_nrange; // From AstBasicDType: Numeric msb/lsb (if non-opaque keyword)
|
||||
const int m_width; // From AstNodeDType: Bit width of operation
|
||||
const int m_widthMin; // From AstNodeDType: If unsized, bitwidth of minimum implementation
|
||||
const VSigning m_numeric; // From AstNodeDType: Node is signed
|
||||
const AstBasicDTypeKwd m_keyword; // From AstBasicDType: What keyword created basic type
|
||||
const VNumRange m_nrange; // From AstBasicDType: Numeric msb/lsb (if non-opaque keyword)
|
||||
bool operator==(const VBasicTypeKey& rhs) const {
|
||||
return m_width == rhs.m_width && m_widthMin == rhs.m_widthMin && m_numeric == rhs.m_numeric
|
||||
&& m_keyword == rhs.m_keyword && m_nrange == rhs.m_nrange;
|
||||
|
|
@ -2612,12 +2612,12 @@ public:
|
|||
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
|
||||
}
|
||||
virtual bool same(const AstNode* samep) const override {
|
||||
const AstNodeArrayDType* asamep = static_cast<const AstNodeArrayDType*>(samep);
|
||||
const AstNodeArrayDType* const asamep = static_cast<const AstNodeArrayDType*>(samep);
|
||||
return (hi() == asamep->hi() && subDTypep() == asamep->subDTypep()
|
||||
&& rangenp()->sameTree(asamep->rangenp()));
|
||||
} // HashedDT doesn't recurse, so need to check children
|
||||
virtual bool similarDType(AstNodeDType* samep) const override {
|
||||
const AstNodeArrayDType* asamep = static_cast<const AstNodeArrayDType*>(samep);
|
||||
const AstNodeArrayDType* const asamep = static_cast<const AstNodeArrayDType*>(samep);
|
||||
return (asamep && type() == samep->type() && hi() == asamep->hi()
|
||||
&& rangenp()->sameTree(asamep->rangenp())
|
||||
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()));
|
||||
|
|
@ -2705,7 +2705,7 @@ public:
|
|||
virtual const char* broken() const override;
|
||||
virtual int instrCount() const override { return INSTR_COUNT_CALL; }
|
||||
virtual bool same(const AstNode* samep) const override {
|
||||
const AstNodeCCall* asamep = static_cast<const AstNodeCCall*>(samep);
|
||||
const AstNodeCCall* const asamep = static_cast<const AstNodeCCall*>(samep);
|
||||
return (funcp() == asamep->funcp() && argTypes() == asamep->argTypes());
|
||||
}
|
||||
AstNode* exprsp() const { return op2p(); } // op2 = expressions to print
|
||||
|
|
@ -2901,7 +2901,7 @@ class AstNodeModule VL_NOT_FINAL : public AstNode {
|
|||
// excluding $unit package stuff
|
||||
private:
|
||||
string m_name; // Name of the module
|
||||
string m_origName; // Name of the module, ignoring name() changes, for dot lookup
|
||||
const string m_origName; // Name of the module, ignoring name() changes, for dot lookup
|
||||
string m_hierName; // Hierarchical name for errors, etc.
|
||||
bool m_modPublic : 1; // Module has public references
|
||||
bool m_modTrace : 1; // Tracing this module
|
||||
|
|
|
|||
|
|
@ -226,11 +226,11 @@ AstConst* AstConst::parseParamLiteral(FileLine* fl, const string& literal) {
|
|||
bool success = false;
|
||||
if (literal[0] == '"') {
|
||||
// This is a string
|
||||
string v = literal.substr(1, literal.find('"', 1) - 1);
|
||||
const string v = literal.substr(1, literal.find('"', 1) - 1);
|
||||
return new AstConst(fl, AstConst::VerilogStringLiteral(), v);
|
||||
} else if (literal.find_first_of(".eEpP") != string::npos) {
|
||||
// This may be a real
|
||||
double v = VString::parseDouble(literal, &success);
|
||||
const double v = VString::parseDouble(literal, &success);
|
||||
if (success) return new AstConst(fl, AstConst::RealDouble(), v);
|
||||
}
|
||||
if (!success) {
|
||||
|
|
@ -242,7 +242,7 @@ AstConst* AstConst::parseParamLiteral(FileLine* fl, const string& literal) {
|
|||
// the string after the number, this is invalid C and we try
|
||||
// the Verilog literal parser.
|
||||
char* endp;
|
||||
int v = strtol(literal.c_str(), &endp, 0);
|
||||
const int v = strtol(literal.c_str(), &endp, 0);
|
||||
if ((v != 0) && (endp[0] == 0)) { // C literal
|
||||
return new AstConst(fl, AstConst::Signed32(), v);
|
||||
} else { // Try a Verilog literal (fatals if not)
|
||||
|
|
@ -475,7 +475,7 @@ public:
|
|||
string convert(const AstVar* varp) const {
|
||||
if (varp->isDpiOpenArray()) {
|
||||
return openArray(varp);
|
||||
} else if (const AstBasicDType* basicp = varp->basicp()) {
|
||||
} else if (const AstBasicDType* const basicp = varp->basicp()) {
|
||||
if (basicp->isDpiBitVec() || basicp->isDpiLogicVec()) {
|
||||
return bitLogicVector(varp, basicp->isDpiBitVec());
|
||||
} else {
|
||||
|
|
@ -515,9 +515,9 @@ string AstVar::dpiArgType(bool named, bool forReturn) const {
|
|||
|
||||
string AstVar::dpiTmpVarType(const string& varName) const {
|
||||
class converter final : public dpiTypesToStringConverter {
|
||||
string m_name;
|
||||
const string m_name;
|
||||
string arraySuffix(const AstVar* varp, size_t n) const {
|
||||
if (AstUnpackArrayDType* unpackp
|
||||
if (AstUnpackArrayDType* const unpackp
|
||||
= VN_CAST(varp->dtypep()->skipRefp(), UnpackArrayDType)) {
|
||||
// Convert multi dimensional unpacked array to 1D array
|
||||
if (n == 0) n = 1;
|
||||
|
|
@ -583,7 +583,7 @@ AstVar* AstVar::scVarRecurse(AstNode* nodep) {
|
|||
// See if this is a SC assignment; if so return that type
|
||||
// Historically sc variables are identified by a variable
|
||||
// attribute. TODO it would better be a data type attribute.
|
||||
if (AstVar* anodep = VN_CAST(nodep, Var)) {
|
||||
if (AstVar* const anodep = VN_CAST(nodep, Var)) {
|
||||
if (anodep->isSc()) {
|
||||
return anodep;
|
||||
} else {
|
||||
|
|
@ -642,29 +642,29 @@ AstNodeDType::CTypeRecursed AstNodeDType::cTypeRecurse(bool compound) const {
|
|||
// Legacy compound argument currently just passed through and unused
|
||||
CTypeRecursed info;
|
||||
|
||||
const AstNodeDType* dtypep = this->skipRefp();
|
||||
if (const auto* adtypep = VN_CAST(dtypep, AssocArrayDType)) {
|
||||
const AstNodeDType* const dtypep = this->skipRefp();
|
||||
if (const auto* const adtypep = VN_CAST(dtypep, AssocArrayDType)) {
|
||||
const CTypeRecursed key = adtypep->keyDTypep()->cTypeRecurse(true);
|
||||
const CTypeRecursed val = adtypep->subDTypep()->cTypeRecurse(true);
|
||||
info.m_type = "VlAssocArray<" + key.m_type + ", " + val.m_type + ">";
|
||||
} else if (const auto* adtypep = VN_CAST(dtypep, DynArrayDType)) {
|
||||
} else if (const auto* const adtypep = VN_CAST(dtypep, DynArrayDType)) {
|
||||
const CTypeRecursed sub = adtypep->subDTypep()->cTypeRecurse(true);
|
||||
info.m_type = "VlQueue<" + sub.m_type + ">";
|
||||
} else if (const auto* adtypep = VN_CAST(dtypep, QueueDType)) {
|
||||
} else if (const auto* const adtypep = VN_CAST(dtypep, QueueDType)) {
|
||||
const CTypeRecursed sub = adtypep->subDTypep()->cTypeRecurse(true);
|
||||
info.m_type = "VlQueue<" + sub.m_type;
|
||||
// + 1 below as VlQueue uses 0 to mean unlimited, 1 to mean size() max is 1
|
||||
if (adtypep->boundp()) info.m_type += ", " + cvtToStr(adtypep->boundConst() + 1);
|
||||
info.m_type += ">";
|
||||
} else if (const auto* adtypep = VN_CAST(dtypep, ClassRefDType)) {
|
||||
} else if (const auto* const adtypep = VN_CAST(dtypep, ClassRefDType)) {
|
||||
info.m_type = "VlClassRef<" + EmitCBaseVisitor::prefixNameProtect(adtypep) + ">";
|
||||
} else if (const auto* adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||
} else if (const auto* const adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||
if (adtypep->isCompound()) compound = true;
|
||||
const CTypeRecursed sub = adtypep->subDTypep()->cTypeRecurse(compound);
|
||||
info.m_type = "VlUnpacked<" + sub.m_type;
|
||||
info.m_type += ", " + cvtToStr(adtypep->declRange().elements());
|
||||
info.m_type += ">";
|
||||
} else if (const AstBasicDType* bdtypep = dtypep->basicp()) {
|
||||
} else if (const AstBasicDType* const bdtypep = dtypep->basicp()) {
|
||||
// We don't print msb()/lsb() as multidim packed would require recursion,
|
||||
// and may confuse users as C++ data is stored always with bit 0 used
|
||||
const string bitvec = (!bdtypep->isOpaque() && !v3Global.opt.protectIds())
|
||||
|
|
@ -704,7 +704,7 @@ uint32_t AstNodeDType::arrayUnpackedElements() {
|
|||
uint32_t entries = 1;
|
||||
for (AstNodeDType* dtypep = this; dtypep;) {
|
||||
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
||||
if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||
if (AstUnpackArrayDType* const adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||
entries *= adtypep->elementsConst();
|
||||
dtypep = adtypep->subDTypep();
|
||||
} else {
|
||||
|
|
@ -721,7 +721,7 @@ std::pair<uint32_t, uint32_t> AstNodeDType::dimensions(bool includeBasic) {
|
|||
uint32_t unpacked = 0;
|
||||
for (AstNodeDType* dtypep = this; dtypep;) {
|
||||
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
||||
if (const AstNodeArrayDType* adtypep = VN_CAST(dtypep, NodeArrayDType)) {
|
||||
if (const AstNodeArrayDType* const adtypep = VN_CAST(dtypep, NodeArrayDType)) {
|
||||
if (VN_IS(adtypep, PackArrayDType)) {
|
||||
++packed;
|
||||
} else {
|
||||
|
|
@ -729,11 +729,11 @@ std::pair<uint32_t, uint32_t> AstNodeDType::dimensions(bool includeBasic) {
|
|||
}
|
||||
dtypep = adtypep->subDTypep();
|
||||
continue;
|
||||
} else if (const AstQueueDType* qdtypep = VN_CAST(dtypep, QueueDType)) {
|
||||
} else if (const AstQueueDType* const qdtypep = VN_CAST(dtypep, QueueDType)) {
|
||||
unpacked++;
|
||||
dtypep = qdtypep->subDTypep();
|
||||
continue;
|
||||
} else if (const AstBasicDType* adtypep = VN_CAST(dtypep, BasicDType)) {
|
||||
} else if (const AstBasicDType* const adtypep = VN_CAST(dtypep, BasicDType)) {
|
||||
if (includeBasic && (adtypep->isRanged() || adtypep->isString())) packed++;
|
||||
} else if (VN_IS(dtypep, StructDType)) {
|
||||
packed++;
|
||||
|
|
@ -745,7 +745,7 @@ std::pair<uint32_t, uint32_t> AstNodeDType::dimensions(bool includeBasic) {
|
|||
|
||||
int AstNodeDType::widthPow2() const {
|
||||
// I.e. width 30 returns 32, width 32 returns 32.
|
||||
uint32_t width = this->width();
|
||||
const uint32_t width = this->width();
|
||||
for (int p2 = 30; p2 >= 0; p2--) {
|
||||
if (width > (1UL << p2)) return (1UL << (p2 + 1));
|
||||
}
|
||||
|
|
@ -753,11 +753,11 @@ int AstNodeDType::widthPow2() const {
|
|||
}
|
||||
|
||||
bool AstNodeDType::isLiteralType() const {
|
||||
if (auto* const dtypep = VN_CAST(skipRefp(), BasicDType)) {
|
||||
if (const auto* const dtypep = VN_CAST(skipRefp(), BasicDType)) {
|
||||
return dtypep->keyword().isLiteralType();
|
||||
} else if (auto* const dtypep = VN_CAST(skipRefp(), UnpackArrayDType)) {
|
||||
} else if (const auto* const dtypep = VN_CAST(skipRefp(), UnpackArrayDType)) {
|
||||
return dtypep->basicp()->isLiteralType();
|
||||
} else if (auto* const dtypep = VN_CAST(skipRefp(), StructDType)) {
|
||||
} else if (const auto* const dtypep = VN_CAST(skipRefp(), StructDType)) {
|
||||
// Currently all structs are packed, later this can be expanded to
|
||||
// 'forall members _.isLiteralType()'
|
||||
return dtypep->packed();
|
||||
|
|
@ -894,7 +894,7 @@ void AstTypeTable::clearCache() {
|
|||
m_detailedMap.clear();
|
||||
// Clear generic()'s so dead detection will work
|
||||
for (AstNode* nodep = typesp(); nodep; nodep = nodep->nextp()) {
|
||||
if (AstBasicDType* bdtypep = VN_CAST(nodep, BasicDType)) bdtypep->generic(false);
|
||||
if (AstBasicDType* const bdtypep = VN_CAST(nodep, BasicDType)) bdtypep->generic(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -902,7 +902,7 @@ void AstTypeTable::repairCache() {
|
|||
// After we mass-change widthMin in V3WidthCommit, we need to correct the table.
|
||||
clearCache();
|
||||
for (AstNode* nodep = typesp(); nodep; nodep = nodep->nextp()) {
|
||||
if (AstBasicDType* bdtypep = VN_CAST(nodep, BasicDType)) {
|
||||
if (AstBasicDType* const bdtypep = VN_CAST(nodep, BasicDType)) {
|
||||
(void)findInsertSameDType(bdtypep);
|
||||
}
|
||||
}
|
||||
|
|
@ -910,7 +910,7 @@ void AstTypeTable::repairCache() {
|
|||
|
||||
AstEmptyQueueDType* AstTypeTable::findEmptyQueueDType(FileLine* fl) {
|
||||
if (VL_UNLIKELY(!m_emptyQueuep)) {
|
||||
AstEmptyQueueDType* newp = new AstEmptyQueueDType{fl};
|
||||
AstEmptyQueueDType* const newp = new AstEmptyQueueDType{fl};
|
||||
addTypesp(newp);
|
||||
m_emptyQueuep = newp;
|
||||
}
|
||||
|
|
@ -919,7 +919,7 @@ AstEmptyQueueDType* AstTypeTable::findEmptyQueueDType(FileLine* fl) {
|
|||
|
||||
AstVoidDType* AstTypeTable::findVoidDType(FileLine* fl) {
|
||||
if (VL_UNLIKELY(!m_voidp)) {
|
||||
AstVoidDType* newp = new AstVoidDType{fl};
|
||||
AstVoidDType* const newp = new AstVoidDType{fl};
|
||||
addTypesp(newp);
|
||||
m_voidp = newp;
|
||||
}
|
||||
|
|
@ -928,7 +928,7 @@ AstVoidDType* AstTypeTable::findVoidDType(FileLine* fl) {
|
|||
|
||||
AstQueueDType* AstTypeTable::findQueueIndexDType(FileLine* fl) {
|
||||
if (VL_UNLIKELY(!m_queueIndexp)) {
|
||||
AstQueueDType* newp = new AstQueueDType(fl, AstNode::findUInt32DType(), nullptr);
|
||||
AstQueueDType* const newp = new AstQueueDType(fl, AstNode::findUInt32DType(), nullptr);
|
||||
addTypesp(newp);
|
||||
m_queueIndexp = newp;
|
||||
}
|
||||
|
|
@ -938,11 +938,11 @@ AstQueueDType* AstTypeTable::findQueueIndexDType(FileLine* fl) {
|
|||
AstBasicDType* AstTypeTable::findBasicDType(FileLine* fl, AstBasicDTypeKwd kwd) {
|
||||
if (m_basicps[kwd]) return m_basicps[kwd];
|
||||
//
|
||||
AstBasicDType* new1p = new AstBasicDType(fl, kwd);
|
||||
AstBasicDType* const new1p = new AstBasicDType(fl, kwd);
|
||||
// Because the detailed map doesn't update this map,
|
||||
// check the detailed map for this same node
|
||||
// Also adds this new node to the detailed map
|
||||
AstBasicDType* newp = findInsertSameDType(new1p);
|
||||
AstBasicDType* const newp = findInsertSameDType(new1p);
|
||||
if (newp != new1p) {
|
||||
VL_DO_DANGLING(new1p->deleteTree(), new1p);
|
||||
} else {
|
||||
|
|
@ -955,8 +955,8 @@ AstBasicDType* AstTypeTable::findBasicDType(FileLine* fl, AstBasicDTypeKwd kwd)
|
|||
|
||||
AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, int width,
|
||||
int widthMin, VSigning numeric) {
|
||||
AstBasicDType* new1p = new AstBasicDType(fl, kwd, numeric, width, widthMin);
|
||||
AstBasicDType* newp = findInsertSameDType(new1p);
|
||||
AstBasicDType* const new1p = new AstBasicDType(fl, kwd, numeric, width, widthMin);
|
||||
AstBasicDType* const newp = findInsertSameDType(new1p);
|
||||
if (newp != new1p) {
|
||||
VL_DO_DANGLING(new1p->deleteTree(), new1p);
|
||||
} else {
|
||||
|
|
@ -968,8 +968,8 @@ AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kw
|
|||
AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd,
|
||||
const VNumRange& range, int widthMin,
|
||||
VSigning numeric) {
|
||||
AstBasicDType* new1p = new AstBasicDType(fl, kwd, numeric, range, widthMin);
|
||||
AstBasicDType* newp = findInsertSameDType(new1p);
|
||||
AstBasicDType* const new1p = new AstBasicDType(fl, kwd, numeric, range, widthMin);
|
||||
AstBasicDType* const newp = findInsertSameDType(new1p);
|
||||
if (newp != new1p) {
|
||||
VL_DO_DANGLING(new1p->deleteTree(), new1p);
|
||||
} else {
|
||||
|
|
@ -979,8 +979,8 @@ AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kw
|
|||
}
|
||||
|
||||
AstBasicDType* AstTypeTable::findInsertSameDType(AstBasicDType* nodep) {
|
||||
VBasicTypeKey key(nodep->width(), nodep->widthMin(), nodep->numeric(), nodep->keyword(),
|
||||
nodep->nrange());
|
||||
const VBasicTypeKey key(nodep->width(), nodep->widthMin(), nodep->numeric(), nodep->keyword(),
|
||||
nodep->nrange());
|
||||
DetailedMap& mapr = m_detailedMap;
|
||||
const auto it = mapr.find(key);
|
||||
if (it != mapr.end()) return it->second;
|
||||
|
|
@ -1037,14 +1037,14 @@ static bool sameInit(const AstInitArray* ap, const AstInitArray* bp) {
|
|||
}
|
||||
|
||||
AstVarScope* AstConstPool::findTable(AstInitArray* initp) {
|
||||
AstNode* const defaultp = initp->defaultp();
|
||||
const AstNode* const defaultp = initp->defaultp();
|
||||
// Verify initializer is well formed
|
||||
UASSERT_OBJ(VN_IS(initp->dtypep(), UnpackArrayDType), initp,
|
||||
"Const pool table must have AstUnpackArrayDType dtype");
|
||||
UASSERT_OBJ(!defaultp || VN_IS(defaultp, Const), initp,
|
||||
"Const pool table default must be Const");
|
||||
for (AstNode* nodep = initp->initsp(); nodep; nodep = nodep->nextp()) {
|
||||
AstNode* const valuep = VN_AS(nodep, InitItem)->valuep();
|
||||
const AstNode* const valuep = VN_AS(nodep, InitItem)->valuep();
|
||||
UASSERT_OBJ(VN_IS(valuep, Const), valuep, "Const pool table entry must be Const");
|
||||
}
|
||||
// Try to find an existing table with the same content
|
||||
|
|
@ -1192,7 +1192,7 @@ void AstNode::dump(std::ostream& str) const {
|
|||
} else {
|
||||
str << " @dt=" << nodeAddr(dtypep()) << "@";
|
||||
}
|
||||
if (AstNodeDType* dtp = dtypep()) dtp->dumpSmall(str);
|
||||
if (AstNodeDType* const dtp = dtypep()) dtp->dumpSmall(str);
|
||||
} else { // V3Broken will throw an error
|
||||
if (dtypep()) str << " %Error-dtype-exp=null,got=" << nodeAddr(dtypep());
|
||||
}
|
||||
|
|
@ -1285,7 +1285,7 @@ void AstClass::dump(std::ostream& str) const {
|
|||
if (isVirtual()) str << " [VIRT]";
|
||||
}
|
||||
AstClass* AstClassExtends::classp() const {
|
||||
AstClassRefDType* refp = VN_CAST(dtypep(), ClassRefDType);
|
||||
const AstClassRefDType* refp = VN_CAST(dtypep(), ClassRefDType);
|
||||
if (VL_UNLIKELY(!refp)) { // LinkDot uses this for 'super.'
|
||||
refp = VN_AS(childDTypep(), ClassRefDType);
|
||||
}
|
||||
|
|
@ -1474,7 +1474,7 @@ void AstNodeUOrStructDType::dump(std::ostream& str) const {
|
|||
void AstNodeDType::dump(std::ostream& str) const {
|
||||
this->AstNode::dump(str);
|
||||
if (generic()) str << " [GENERIC]";
|
||||
if (AstNodeDType* dtp = virtRefDTypep()) {
|
||||
if (AstNodeDType* const dtp = virtRefDTypep()) {
|
||||
str << " refdt=" << nodeAddr(dtp);
|
||||
dtp->dumpSmall(str);
|
||||
}
|
||||
|
|
@ -1488,7 +1488,7 @@ void AstNodeDType::dumpSmall(std::ostream& str) const {
|
|||
}
|
||||
void AstNodeArrayDType::dumpSmall(std::ostream& str) const {
|
||||
this->AstNodeDType::dumpSmall(str);
|
||||
if (auto* adtypep = VN_CAST(this, UnpackArrayDType)) {
|
||||
if (auto* const adtypep = VN_CAST(this, UnpackArrayDType)) {
|
||||
// uc = packed compound object, u = unpacked POD
|
||||
str << (adtypep->isCompound() ? "uc" : "u");
|
||||
} else {
|
||||
|
|
@ -1524,7 +1524,7 @@ std::vector<AstUnpackArrayDType*> AstUnpackArrayDType::unpackDimensions() {
|
|||
std::vector<AstUnpackArrayDType*> dims;
|
||||
for (AstUnpackArrayDType* unpackp = this; unpackp;) {
|
||||
dims.push_back(unpackp);
|
||||
if (AstNodeDType* subp = unpackp->subDTypep()) {
|
||||
if (AstNodeDType* const subp = unpackp->subDTypep()) {
|
||||
unpackp = VN_CAST(subp, UnpackArrayDType);
|
||||
} else {
|
||||
unpackp = nullptr;
|
||||
|
|
@ -1581,7 +1581,7 @@ void AstMTaskBody::dump(std::ostream& str) const {
|
|||
void AstTypeTable::dump(std::ostream& str) const {
|
||||
this->AstNode::dump(str);
|
||||
for (int i = 0; i < static_cast<int>(AstBasicDTypeKwd::_ENUM_MAX); ++i) {
|
||||
if (AstBasicDType* subnodep = m_basicps[i]) {
|
||||
if (AstBasicDType* const subnodep = m_basicps[i]) {
|
||||
str << '\n'; // Newline from caller, so newline first
|
||||
str << "\t\t" << std::setw(8) << AstBasicDTypeKwd(i).ascii();
|
||||
str << " -> ";
|
||||
|
|
@ -1591,7 +1591,7 @@ void AstTypeTable::dump(std::ostream& str) const {
|
|||
{
|
||||
const DetailedMap& mapr = m_detailedMap;
|
||||
for (const auto& itr : mapr) {
|
||||
AstBasicDType* dtypep = itr.second;
|
||||
AstBasicDType* const dtypep = itr.second;
|
||||
str << '\n'; // Newline from caller, so newline first
|
||||
str << "\t\tdetailed -> ";
|
||||
dtypep->dump(str);
|
||||
|
|
|
|||
111
src/V3AstNodes.h
111
src/V3AstNodes.h
|
|
@ -172,7 +172,7 @@ public:
|
|||
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
||||
virtual bool cleanOut() const override { return true; }
|
||||
virtual bool same(const AstNode* samep) const override {
|
||||
const AstConst* sp = static_cast<const AstConst*>(samep);
|
||||
const AstConst* const sp = static_cast<const AstConst*>(samep);
|
||||
return num().isCaseEq(sp->num());
|
||||
}
|
||||
virtual int instrCount() const override { return widthInstrs(); }
|
||||
|
|
@ -216,21 +216,21 @@ public:
|
|||
AstNode* leftp() const { return op2p(); }
|
||||
AstNode* rightp() const { return op3p(); }
|
||||
int leftConst() const {
|
||||
AstConst* constp = VN_CAST(leftp(), Const);
|
||||
AstConst* const constp = VN_CAST(leftp(), Const);
|
||||
return (constp ? constp->toSInt() : 0);
|
||||
}
|
||||
int rightConst() const {
|
||||
AstConst* constp = VN_CAST(rightp(), Const);
|
||||
AstConst* const constp = VN_CAST(rightp(), Const);
|
||||
return (constp ? constp->toSInt() : 0);
|
||||
}
|
||||
int hiConst() const {
|
||||
int l = leftConst();
|
||||
int r = rightConst();
|
||||
const int l = leftConst();
|
||||
const int r = rightConst();
|
||||
return l > r ? l : r;
|
||||
}
|
||||
int loConst() const {
|
||||
int l = leftConst();
|
||||
int r = rightConst();
|
||||
const int l = leftConst();
|
||||
const int r = rightConst();
|
||||
return l > r ? r : l;
|
||||
}
|
||||
int elementsConst() const { return hiConst() - loConst() + 1; }
|
||||
|
|
@ -375,7 +375,7 @@ class AstParamTypeDType final : public AstNodeDType {
|
|||
// Parents: MODULE
|
||||
// A parameter type statement; much like a var or typedef
|
||||
private:
|
||||
AstVarType m_varType; // Type of variable (for localparam vs. param)
|
||||
const AstVarType m_varType; // Type of variable (for localparam vs. param)
|
||||
string m_name; // Name of variable
|
||||
public:
|
||||
AstParamTypeDType(FileLine* fl, AstVarType type, const string& name, VFlagChildDType,
|
||||
|
|
@ -401,7 +401,7 @@ public:
|
|||
}
|
||||
virtual AstNodeDType* skipRefToEnump() const override { return subDTypep()->skipRefToEnump(); }
|
||||
virtual bool similarDType(AstNodeDType* samep) const override {
|
||||
const AstParamTypeDType* sp = static_cast<const AstParamTypeDType*>(samep);
|
||||
const AstParamTypeDType* const sp = static_cast<const AstParamTypeDType*>(samep);
|
||||
return type() == samep->type() && sp
|
||||
&& this->subDTypep()->skipRefp()->similarDType(sp->subDTypep()->skipRefp());
|
||||
}
|
||||
|
|
@ -494,7 +494,7 @@ public:
|
|||
ASTNODE_NODE_FUNCS(DefImplicitDType)
|
||||
int uniqueNum() const { return m_uniqueNum; }
|
||||
virtual bool same(const AstNode* samep) const override {
|
||||
const AstDefImplicitDType* sp = static_cast<const AstDefImplicitDType*>(samep);
|
||||
const AstDefImplicitDType* const sp = static_cast<const AstDefImplicitDType*>(samep);
|
||||
return uniqueNum() == sp->uniqueNum();
|
||||
}
|
||||
virtual bool similarDType(AstNodeDType* samep) const override {
|
||||
|
|
@ -551,13 +551,13 @@ public:
|
|||
if (m_keyDTypep && m_keyDTypep->clonep()) m_keyDTypep = m_keyDTypep->clonep();
|
||||
}
|
||||
virtual bool same(const AstNode* samep) const override {
|
||||
const AstAssocArrayDType* asamep = static_cast<const AstAssocArrayDType*>(samep);
|
||||
const AstAssocArrayDType* const asamep = static_cast<const AstAssocArrayDType*>(samep);
|
||||
if (!asamep->subDTypep()) return false;
|
||||
if (!asamep->keyDTypep()) return false;
|
||||
return (subDTypep() == asamep->subDTypep() && keyDTypep() == asamep->keyDTypep());
|
||||
}
|
||||
virtual bool similarDType(AstNodeDType* samep) const override {
|
||||
const AstAssocArrayDType* asamep = static_cast<const AstAssocArrayDType*>(samep);
|
||||
const AstAssocArrayDType* const asamep = static_cast<const AstAssocArrayDType*>(samep);
|
||||
return type() == samep->type() && asamep->subDTypep()
|
||||
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
|
||||
}
|
||||
|
|
@ -650,12 +650,12 @@ public:
|
|||
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
|
||||
}
|
||||
virtual bool same(const AstNode* samep) const override {
|
||||
const AstAssocArrayDType* asamep = static_cast<const AstAssocArrayDType*>(samep);
|
||||
const AstAssocArrayDType* const asamep = static_cast<const AstAssocArrayDType*>(samep);
|
||||
if (!asamep->subDTypep()) return false;
|
||||
return subDTypep() == asamep->subDTypep();
|
||||
}
|
||||
virtual bool similarDType(AstNodeDType* samep) const override {
|
||||
const AstAssocArrayDType* asamep = static_cast<const AstAssocArrayDType*>(samep);
|
||||
const AstAssocArrayDType* const asamep = static_cast<const AstAssocArrayDType*>(samep);
|
||||
return type() == samep->type() && asamep->subDTypep()
|
||||
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
|
||||
}
|
||||
|
|
@ -736,7 +736,7 @@ public:
|
|||
ASTNODE_NODE_FUNCS(UnpackArrayDType)
|
||||
virtual string prettyDTypeName() const override;
|
||||
virtual bool same(const AstNode* samep) const override {
|
||||
const AstUnpackArrayDType* sp = static_cast<const AstUnpackArrayDType*>(samep);
|
||||
const AstUnpackArrayDType* const sp = static_cast<const AstUnpackArrayDType*>(samep);
|
||||
return m_isCompound == sp->m_isCompound;
|
||||
}
|
||||
// Outer dimension comes first. The first element is this node.
|
||||
|
|
@ -767,12 +767,12 @@ public:
|
|||
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
|
||||
}
|
||||
virtual bool same(const AstNode* samep) const override {
|
||||
const AstNodeArrayDType* asamep = static_cast<const AstNodeArrayDType*>(samep);
|
||||
const AstNodeArrayDType* const asamep = static_cast<const AstNodeArrayDType*>(samep);
|
||||
if (!asamep->subDTypep()) return false;
|
||||
return (subDTypep() == asamep->subDTypep());
|
||||
}
|
||||
virtual bool similarDType(AstNodeDType* samep) const override {
|
||||
const AstNodeArrayDType* asamep = static_cast<const AstNodeArrayDType*>(samep);
|
||||
const AstNodeArrayDType* const asamep = static_cast<const AstNodeArrayDType*>(samep);
|
||||
return type() == samep->type() && asamep->subDTypep()
|
||||
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
|
||||
}
|
||||
|
|
@ -876,7 +876,7 @@ public:
|
|||
virtual void dump(std::ostream& str) const override;
|
||||
// width/widthMin/numeric compared elsewhere
|
||||
virtual bool same(const AstNode* samep) const override {
|
||||
const AstBasicDType* sp = static_cast<const AstBasicDType*>(samep);
|
||||
const AstBasicDType* const sp = static_cast<const AstBasicDType*>(samep);
|
||||
return m == sp->m;
|
||||
}
|
||||
virtual bool similarDType(AstNodeDType* samep) const override {
|
||||
|
|
@ -973,7 +973,7 @@ public:
|
|||
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
|
||||
}
|
||||
virtual bool same(const AstNode* samep) const override {
|
||||
const AstConstDType* sp = static_cast<const AstConstDType*>(samep);
|
||||
const AstConstDType* const sp = static_cast<const AstConstDType*>(samep);
|
||||
return (m_refDTypep == sp->m_refDTypep);
|
||||
}
|
||||
virtual bool similarDType(AstNodeDType* samep) const override {
|
||||
|
|
@ -1025,7 +1025,7 @@ public:
|
|||
if (m_classp && m_classp->clonep()) m_classp = m_classp->clonep();
|
||||
}
|
||||
virtual bool same(const AstNode* samep) const override {
|
||||
const AstClassRefDType* asamep = static_cast<const AstClassRefDType*>(samep);
|
||||
const AstClassRefDType* const asamep = static_cast<const AstClassRefDType*>(samep);
|
||||
return (m_classp == asamep->m_classp && m_classOrPackagep == asamep->m_classOrPackagep);
|
||||
}
|
||||
virtual bool similarDType(AstNodeDType* samep) const override {
|
||||
|
|
@ -1134,12 +1134,12 @@ public:
|
|||
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
|
||||
}
|
||||
virtual bool same(const AstNode* samep) const override {
|
||||
const AstQueueDType* asamep = static_cast<const AstQueueDType*>(samep);
|
||||
const AstQueueDType* const asamep = static_cast<const AstQueueDType*>(samep);
|
||||
if (!asamep->subDTypep()) return false;
|
||||
return (subDTypep() == asamep->subDTypep());
|
||||
}
|
||||
virtual bool similarDType(AstNodeDType* samep) const override {
|
||||
const AstQueueDType* asamep = static_cast<const AstQueueDType*>(samep);
|
||||
const AstQueueDType* const asamep = static_cast<const AstQueueDType*>(samep);
|
||||
return type() == samep->type() && asamep->subDTypep()
|
||||
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
|
||||
}
|
||||
|
|
@ -1156,7 +1156,7 @@ public:
|
|||
AstNode* boundp() const { return op2p(); } // op2 = Bound, nullptr = none
|
||||
void boundp(AstNode* nodep) { setNOp2p(nodep); }
|
||||
int boundConst() const {
|
||||
AstConst* constp = VN_CAST(boundp(), Const);
|
||||
AstConst* const constp = VN_CAST(boundp(), Const);
|
||||
return (constp ? constp->toSInt() : 0);
|
||||
}
|
||||
virtual AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
||||
|
|
@ -1210,7 +1210,7 @@ public:
|
|||
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
|
||||
}
|
||||
virtual bool same(const AstNode* samep) const override {
|
||||
const AstRefDType* asamep = static_cast<const AstRefDType*>(samep);
|
||||
const AstRefDType* const asamep = static_cast<const AstRefDType*>(samep);
|
||||
return (m_typedefp == asamep->m_typedefp && m_refDTypep == asamep->m_refDTypep
|
||||
&& m_name == asamep->m_name && m_classOrPackagep == asamep->m_classOrPackagep);
|
||||
}
|
||||
|
|
@ -1458,7 +1458,7 @@ public:
|
|||
if (m_itemp->clonep()) m_itemp = m_itemp->clonep();
|
||||
}
|
||||
virtual bool same(const AstNode* samep) const override {
|
||||
const AstEnumItemRef* sp = static_cast<const AstEnumItemRef*>(samep);
|
||||
const AstEnumItemRef* const sp = static_cast<const AstEnumItemRef*>(samep);
|
||||
return itemp() == sp->itemp();
|
||||
}
|
||||
AstEnumItem* itemp() const { return m_itemp; }
|
||||
|
|
@ -1498,7 +1498,7 @@ public:
|
|||
}
|
||||
int uniqueNum() const { return m_uniqueNum; }
|
||||
virtual bool same(const AstNode* samep) const override {
|
||||
const AstEnumDType* sp = static_cast<const AstEnumDType*>(samep);
|
||||
const AstEnumDType* const sp = static_cast<const AstEnumDType*>(samep);
|
||||
return uniqueNum() == sp->uniqueNum();
|
||||
}
|
||||
virtual bool similarDType(AstNodeDType* samep) const override { return this == samep; }
|
||||
|
|
@ -2572,7 +2572,7 @@ public:
|
|||
class AstModule final : public AstNodeModule {
|
||||
// A module declaration
|
||||
private:
|
||||
bool m_isProgram; // Module represents a program
|
||||
const bool m_isProgram; // Module represents a program
|
||||
public:
|
||||
AstModule(FileLine* fl, const string& name, bool program = false)
|
||||
: ASTGEN_SUPER_Module(fl, name)
|
||||
|
|
@ -2884,7 +2884,8 @@ class AstCellInline final : public AstNode {
|
|||
// Children: When 2 levels inlined, other CellInline under this
|
||||
private:
|
||||
string m_name; // Cell name, possibly {a}__DOT__{b}...
|
||||
string m_origModName; // Original name of the module, ignoring name() changes, for dot lookup
|
||||
const string
|
||||
m_origModName; // Original name of the module, ignoring name() changes, for dot lookup
|
||||
AstScope* m_scopep = nullptr; // The scope that the cell is inlined into
|
||||
VTimescale m_timeunit; // Parent module time unit
|
||||
public:
|
||||
|
|
@ -3022,7 +3023,7 @@ public:
|
|||
virtual void dump(std::ostream& str) const override;
|
||||
virtual string name() const override { return m_name; } // * = Var name
|
||||
virtual bool same(const AstNode* samep) const override {
|
||||
const AstParseRef* asamep = static_cast<const AstParseRef*>(samep);
|
||||
const AstParseRef* const asamep = static_cast<const AstParseRef*>(samep);
|
||||
return (expect() == asamep->expect() && m_name == asamep->m_name);
|
||||
}
|
||||
virtual void name(const string& name) override { m_name = name; }
|
||||
|
|
@ -3075,7 +3076,7 @@ public:
|
|||
class AstDot final : public AstNode {
|
||||
// A dot separating paths in an AstVarXRef, AstFuncRef or AstTaskRef
|
||||
// These are eliminated in the link stage
|
||||
bool m_colon; // Is a "::" instead of a "." (lhs must be package/class)
|
||||
const bool m_colon; // Is a "::" instead of a "." (lhs must be package/class)
|
||||
public:
|
||||
AstDot(FileLine* fl, bool colon, AstNode* lhsp, AstNode* rhsp)
|
||||
: ASTGEN_SUPER_Dot(fl)
|
||||
|
|
@ -3343,7 +3344,7 @@ public:
|
|||
};
|
||||
|
||||
class AstAlways final : public AstNodeProcedure {
|
||||
VAlwaysKwd m_keyword;
|
||||
const VAlwaysKwd m_keyword;
|
||||
|
||||
public:
|
||||
AstAlways(FileLine* fl, VAlwaysKwd keyword, AstSenTree* sensesp, AstNode* bodysp)
|
||||
|
|
@ -3447,10 +3448,10 @@ public:
|
|||
}
|
||||
virtual bool brokeLhsMustBeLvalue() const override { return true; }
|
||||
AstAlways* convertToAlways() {
|
||||
AstNode* lhs1p = lhsp()->unlinkFrBack();
|
||||
AstNode* rhs1p = rhsp()->unlinkFrBack();
|
||||
AstAlways* newp = new AstAlways(fileline(), VAlwaysKwd::ALWAYS, nullptr,
|
||||
new AstAssign(fileline(), lhs1p, rhs1p));
|
||||
AstNode* const lhs1p = lhsp()->unlinkFrBack();
|
||||
AstNode* const rhs1p = rhsp()->unlinkFrBack();
|
||||
AstAlways* const newp = new AstAlways(fileline(), VAlwaysKwd::ALWAYS, nullptr,
|
||||
new AstAssign(fileline(), lhs1p, rhs1p));
|
||||
replaceWith(newp); // User expected to then deleteTree();
|
||||
return newp;
|
||||
}
|
||||
|
|
@ -3552,8 +3553,8 @@ class AstComment final : public AstNodeStmt {
|
|||
// Parents: {statement list}
|
||||
// Children: none
|
||||
private:
|
||||
bool m_showAt; // Show "at <fileline>"
|
||||
string m_name; // Text of comment
|
||||
const bool m_showAt; // Show "at <fileline>"
|
||||
const string m_name; // Text of comment
|
||||
public:
|
||||
AstComment(FileLine* fl, const string& name, bool showAt = false)
|
||||
: ASTGEN_SUPER_Comment(fl)
|
||||
|
|
@ -3641,7 +3642,7 @@ public:
|
|||
void hier(const string& flag) { m_hier = flag; }
|
||||
void comment(const string& flag) { m_text = flag; }
|
||||
virtual bool same(const AstNode* samep) const override {
|
||||
const AstCoverDecl* asamep = static_cast<const AstCoverDecl*>(samep);
|
||||
const AstCoverDecl* const asamep = static_cast<const AstCoverDecl*>(samep);
|
||||
return (fileline() == asamep->fileline() && linescov() == asamep->linescov()
|
||||
&& hier() == asamep->hier() && comment() == asamep->comment());
|
||||
}
|
||||
|
|
@ -3798,9 +3799,9 @@ class AstSFormatF final : public AstNode {
|
|||
// Convert format to string, generally under an AstDisplay or AstSFormat
|
||||
// Also used as "real" function for /*verilator sformat*/ functions
|
||||
string m_text;
|
||||
bool m_hidden; // Under display, etc
|
||||
const bool m_hidden; // Under display, etc
|
||||
bool m_hasFormat; // Has format code
|
||||
char m_missingArgChar; // Format code when argument without format, 'h'/'o'/'b'
|
||||
const char m_missingArgChar; // Format code when argument without format, 'h'/'o'/'b'
|
||||
VTimescale m_timeunit; // Parent module time unit
|
||||
public:
|
||||
class NoFormat {};
|
||||
|
|
@ -3908,7 +3909,7 @@ class AstDumpCtl final : public AstNodeStmt {
|
|||
// $dumpon etc
|
||||
// Parents: expr
|
||||
// Child: expr based on type of control statement
|
||||
VDumpCtlType m_ctlType; // Type of operation
|
||||
const VDumpCtlType m_ctlType; // Type of operation
|
||||
public:
|
||||
AstDumpCtl(FileLine* fl, VDumpCtlType ctlType, AstNode* exprp = nullptr)
|
||||
: ASTGEN_SUPER_DumpCtl(fl)
|
||||
|
|
@ -4305,7 +4306,7 @@ public:
|
|||
|
||||
class AstNodeReadWriteMem VL_NOT_FINAL : public AstNodeStmt {
|
||||
private:
|
||||
bool m_isHex; // readmemh, not readmemb
|
||||
const bool m_isHex; // readmemh, not readmemb
|
||||
public:
|
||||
AstNodeReadWriteMem(AstType t, FileLine* fl, bool hex, AstNode* filenamep, AstNode* memp,
|
||||
AstNode* lsbp, AstNode* msbp)
|
||||
|
|
@ -4353,7 +4354,7 @@ public:
|
|||
};
|
||||
|
||||
class AstMonitorOff final : public AstNodeStmt {
|
||||
bool m_off; // Monitor off. Using 0=on allows faster init and comparison
|
||||
const bool m_off; // Monitor off. Using 0=on allows faster init and comparison
|
||||
|
||||
public:
|
||||
AstMonitorOff(FileLine* fl, bool off)
|
||||
|
|
@ -4857,7 +4858,7 @@ class AstBegin final : public AstNodeBlock {
|
|||
// Children: statements
|
||||
private:
|
||||
bool m_generate; // Underneath a generate
|
||||
bool m_implied; // Not inserted by user
|
||||
const bool m_implied; // Not inserted by user
|
||||
public:
|
||||
// Node that simply puts name into the output stream
|
||||
AstBegin(FileLine* fl, const string& name, AstNode* stmtsp, bool generate = false,
|
||||
|
|
@ -4994,7 +4995,7 @@ public:
|
|||
oldp = it->second->valuep();
|
||||
it->second->valuep(newp);
|
||||
} else {
|
||||
AstInitItem* itemp = new AstInitItem(fileline(), newp);
|
||||
AstInitItem* const itemp = new AstInitItem(fileline(), newp);
|
||||
m_map.emplace(index, itemp);
|
||||
addOp2p(itemp);
|
||||
}
|
||||
|
|
@ -5072,7 +5073,7 @@ public:
|
|||
|
||||
class AstPragma final : public AstNode {
|
||||
private:
|
||||
AstPragmaType m_pragType; // Type of pragma
|
||||
const AstPragmaType m_pragType; // Type of pragma
|
||||
public:
|
||||
// Pragmas don't result in any output code, they're just flags that affect
|
||||
// other processing in verilator.
|
||||
|
|
@ -5443,8 +5444,8 @@ class AstRand final : public AstNodeMath {
|
|||
// $random/$random(seed) or $urandom/$urandom(seed)
|
||||
// Return a random number, based upon width()
|
||||
private:
|
||||
bool m_urandom = false; // $urandom vs $random
|
||||
bool m_reset = false; // Random reset, versus always random
|
||||
const bool m_urandom = false; // $urandom vs $random
|
||||
const bool m_reset = false; // Random reset, versus always random
|
||||
public:
|
||||
class Reset {};
|
||||
AstRand(FileLine* fl, Reset, AstNodeDType* dtp, bool reset)
|
||||
|
|
@ -5642,7 +5643,7 @@ public:
|
|||
virtual string emitC() override { return "VL_REDXOR_%lq(%lW, %P, %li)"; }
|
||||
virtual bool cleanOut() const override { return false; }
|
||||
virtual bool cleanLhs() const override {
|
||||
int w = lhsp()->width();
|
||||
const int w = lhsp()->width();
|
||||
return (w != 1 && w != 2 && w != 4 && w != 8 && w != 16);
|
||||
}
|
||||
virtual bool sizeMattersLhs() const override { return false; }
|
||||
|
|
@ -6527,7 +6528,7 @@ public:
|
|||
enum FmtType { ATOI = 10, ATOHEX = 16, ATOOCT = 8, ATOBIN = 2, ATOREAL = -1 };
|
||||
|
||||
private:
|
||||
FmtType m_fmt; // Operation type
|
||||
const FmtType m_fmt; // Operation type
|
||||
public:
|
||||
AstAtoN(FileLine* fl, AstNode* lhsp, FmtType fmt)
|
||||
: ASTGEN_SUPER_AtoN(fl, lhsp)
|
||||
|
|
@ -7965,7 +7966,7 @@ public:
|
|||
AstReplicate(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
||||
: ASTGEN_SUPER_Replicate(fl, lhsp, rhsp) {
|
||||
if (lhsp) {
|
||||
if (const AstConst* constp = VN_CAST(rhsp, Const)) {
|
||||
if (const AstConst* const constp = VN_CAST(rhsp, Const)) {
|
||||
dtypeSetLogicSized(lhsp->width() * constp->toUInt(), VSigning::UNSIGNED);
|
||||
}
|
||||
}
|
||||
|
|
@ -8255,7 +8256,7 @@ public:
|
|||
class AstCompareNN final : public AstNodeBiop {
|
||||
// Verilog str.compare() and str.icompare()
|
||||
private:
|
||||
bool m_ignoreCase; // True for str.icompare()
|
||||
const bool m_ignoreCase; // True for str.icompare()
|
||||
public:
|
||||
AstCompareNN(FileLine* fl, AstNode* lhsp, AstNode* rhsp, bool ignoreCase)
|
||||
: ASTGEN_SUPER_CompareNN(fl, lhsp, rhsp)
|
||||
|
|
@ -8510,7 +8511,7 @@ class AstNodeCoverOrAssert VL_NOT_FINAL : public AstNodeStmt {
|
|||
// Parents: {statement list}
|
||||
// Children: expression, report string
|
||||
private:
|
||||
bool m_immediate; // Immediate assertion/cover
|
||||
const bool m_immediate; // Immediate assertion/cover
|
||||
string m_name; // Name to report
|
||||
public:
|
||||
AstNodeCoverOrAssert(AstType t, FileLine* fl, AstNode* propp, AstNode* passsp, bool immediate,
|
||||
|
|
@ -8816,7 +8817,7 @@ public:
|
|||
virtual bool maybePointedTo() const override { return true; }
|
||||
virtual void dump(std::ostream& str = std::cout) const override;
|
||||
virtual bool same(const AstNode* samep) const override {
|
||||
const AstCFunc* asamep = static_cast<const AstCFunc*>(samep);
|
||||
const AstCFunc* const asamep = static_cast<const AstCFunc*>(samep);
|
||||
return ((isTrace() == asamep->isTrace()) && (rtnTypeVoid() == asamep->rtnTypeVoid())
|
||||
&& (argTypes() == asamep->argTypes()) && (ctorInits() == asamep->ctorInits())
|
||||
&& isLoose() == asamep->isLoose()
|
||||
|
|
@ -8969,7 +8970,7 @@ public:
|
|||
|
||||
class AstCMath final : public AstNodeMath {
|
||||
private:
|
||||
bool m_cleanOut;
|
||||
const bool m_cleanOut;
|
||||
bool m_pure; // Pure optimizable
|
||||
public:
|
||||
// Emit C textual math function (like AstUCFunc)
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ public:
|
|||
|
||||
// Get a reference to the user data
|
||||
T_Data& operator()(const T_Node* nodep) {
|
||||
T_Data* userp = getUserp(nodep);
|
||||
T_Data* const userp = getUserp(nodep);
|
||||
UASSERT_OBJ(userp, nodep, "Missing User data on const AstNode");
|
||||
return *userp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ private:
|
|||
// STATE
|
||||
BeginState* const m_statep; // Current global state
|
||||
AstNodeModule* m_modp = nullptr; // Current module
|
||||
AstNodeFTask* m_ftaskp = nullptr; // Current function/task
|
||||
const AstNodeFTask* m_ftaskp = nullptr; // Current function/task
|
||||
AstNode* m_liftedp = nullptr; // Local nodes we are lifting into m_ftaskp
|
||||
string m_namedScope; // Name of begin blocks above us
|
||||
string m_unnamedScope; // Name of begin blocks, including unnamed blocks
|
||||
|
|
@ -149,7 +149,7 @@ private:
|
|||
m_unnamedScope = dot(m_unnamedScope, ident);
|
||||
// Create CellInline for dotted var resolution
|
||||
if (!m_ftaskp) {
|
||||
AstCellInline* inlinep = new AstCellInline(
|
||||
AstCellInline* const inlinep = new AstCellInline(
|
||||
nodep->fileline(), m_unnamedScope, "__BEGIN__", m_modp->timeunit());
|
||||
m_modp->addInlinesp(inlinep); // Must be parsed before any AstCells
|
||||
}
|
||||
|
|
@ -162,7 +162,7 @@ private:
|
|||
|
||||
// Cleanup
|
||||
AstNode* addsp = nullptr;
|
||||
if (AstNode* stmtsp = nodep->stmtsp()) {
|
||||
if (AstNode* const stmtsp = nodep->stmtsp()) {
|
||||
stmtsp->unlinkFrBackWithNext();
|
||||
if (addsp) {
|
||||
addsp = addsp->addNextNull(stmtsp);
|
||||
|
|
@ -222,7 +222,7 @@ private:
|
|||
if (nodep->user1SetOnce()) return; // Don't double-add text's
|
||||
if (m_namedScope != "") {
|
||||
// To keep correct visual order, must add before other Text's
|
||||
AstNode* afterp = nodep->scopeAttrp();
|
||||
AstNode* const afterp = nodep->scopeAttrp();
|
||||
if (afterp) afterp->unlinkFrBackWithNext();
|
||||
nodep->scopeAttrp(new AstText(nodep->fileline(), string("__DOT__") + m_namedScope));
|
||||
if (afterp) nodep->scopeAttrp(afterp);
|
||||
|
|
|
|||
|
|
@ -343,8 +343,8 @@ void V3Broken::brokenAll(AstNetlist* nodep) {
|
|||
UINFO(1, "Broken called under broken, skipping recursion.\n"); // LCOV_EXCL_LINE
|
||||
} else {
|
||||
inBroken = true;
|
||||
BrokenMarkVisitor mvisitor{nodep};
|
||||
BrokenCheckVisitor cvisitor{nodep};
|
||||
const BrokenMarkVisitor mvisitor{nodep};
|
||||
const BrokenCheckVisitor cvisitor{nodep};
|
||||
s_allocTable.checkForLeaks();
|
||||
s_linkableTable.clear();
|
||||
s_brokenCntGlobal.inc();
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public:
|
|||
enum en : uint8_t { MODULE, CLASS, COVERAGE };
|
||||
|
||||
private:
|
||||
enum en m_e;
|
||||
const enum en m_e;
|
||||
|
||||
public:
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
|
|
@ -139,7 +139,8 @@ 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 (const AstBasicDType* basicp = VN_CAST(varp->dtypeSkipRefp(), BasicDType)) {
|
||||
if (const AstBasicDType* const basicp
|
||||
= VN_CAST(varp->dtypeSkipRefp(), BasicDType)) {
|
||||
const int storedWidth = basicp->widthAlignBytes() * 8;
|
||||
const int lastWordWidth = varp->width() % storedWidth;
|
||||
if (lastWordWidth != 0) {
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
|
||||
class CaseLintVisitor final : public AstNVisitor {
|
||||
private:
|
||||
AstNodeCase* m_caseExprp
|
||||
const AstNodeCase* m_caseExprp
|
||||
= nullptr; // Under a CASE value node, if so the relevant case statement
|
||||
|
||||
// METHODS
|
||||
|
|
@ -127,7 +127,7 @@ private:
|
|||
// STATE
|
||||
VDouble0 m_statCaseFast; // Statistic tracking
|
||||
VDouble0 m_statCaseSlow; // Statistic tracking
|
||||
AstNode* m_alwaysp = nullptr; // Always in which case is located
|
||||
const AstNode* m_alwaysp = nullptr; // Always in which case is located
|
||||
|
||||
// Per-CASE
|
||||
int m_caseWidth = 0; // Width of valueItems
|
||||
|
|
@ -159,7 +159,7 @@ private:
|
|||
return false; // Too wide for analysis
|
||||
}
|
||||
UINFO(8, "Simple case statement: " << nodep << endl);
|
||||
uint32_t numCases = 1UL << m_caseWidth;
|
||||
const uint32_t numCases = 1UL << m_caseWidth;
|
||||
// Zero list of items for each value
|
||||
for (uint32_t i = 0; i < numCases; ++i) m_valueItem[i] = nullptr;
|
||||
// Now pick up the values for each assignment
|
||||
|
|
@ -177,10 +177,10 @@ private:
|
|||
} else {
|
||||
V3Number nummask(itemp, iconstp->width());
|
||||
nummask.opBitsNonX(iconstp->num());
|
||||
uint32_t mask = nummask.toUInt();
|
||||
const uint32_t mask = nummask.toUInt();
|
||||
V3Number numval(itemp, iconstp->width());
|
||||
numval.opBitsOne(iconstp->num());
|
||||
uint32_t val = numval.toUInt();
|
||||
const uint32_t val = numval.toUInt();
|
||||
|
||||
uint32_t firstOverlap = 0;
|
||||
bool foundOverlap = false;
|
||||
|
|
@ -364,7 +364,7 @@ private:
|
|||
// For simplicity, make expression that is not equal, and let later
|
||||
// optimizations remove it
|
||||
condp = new AstConst(itemp->fileline(), AstConst::BitFalse());
|
||||
} else if (AstInsideRange* irangep = VN_CAST(icondp, InsideRange)) {
|
||||
} else if (AstInsideRange* const irangep = VN_CAST(icondp, InsideRange)) {
|
||||
// Similar logic in V3Width::visit(AstInside)
|
||||
condp = irangep->newAndFromInside(cexprp, irangep->lhsp()->unlinkFrBack(),
|
||||
irangep->rhsp()->unlinkFrBack());
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ private:
|
|||
V3Graph m_graph; // Scoreboard of var usages/dependencies
|
||||
CdcLogicVertex* m_logicVertexp = nullptr; // Current statement being tracked, nullptr=ignored
|
||||
AstScope* m_scopep = nullptr; // Current scope being processed
|
||||
AstNodeModule* m_modp = nullptr; // Current module
|
||||
const AstNodeModule* m_modp = nullptr; // Current module
|
||||
AstSenTree* m_domainp = nullptr; // Current sentree
|
||||
bool m_inDly = false; // In delayed assign
|
||||
int m_inSenItem = 0; // Number of senitems
|
||||
|
|
@ -337,7 +337,7 @@ private:
|
|||
|
||||
int filelineWidth() {
|
||||
if (!m_filelineWidth) {
|
||||
CdcWidthVisitor visitor{v3Global.rootp()};
|
||||
const CdcWidthVisitor visitor{v3Global.rootp()};
|
||||
m_filelineWidth = visitor.maxWidth();
|
||||
}
|
||||
return m_filelineWidth;
|
||||
|
|
@ -385,7 +385,7 @@ private:
|
|||
// 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
|
||||
} else if (CdcVarVertex* vvertexp = dynamic_cast<CdcVarVertex*>(vertexp)) {
|
||||
} else if (CdcVarVertex* const vvertexp = dynamic_cast<CdcVarVertex*>(vertexp)) {
|
||||
if (mark) vvertexp->asyncPath(true);
|
||||
// If primary I/O, it's ok here back
|
||||
if (vvertexp->varScp()->varp()->isPrimaryInish()) {
|
||||
|
|
@ -461,7 +461,7 @@ private:
|
|||
// Dump single variable/logic block
|
||||
// See also OrderGraph::loopsVertexCb(V3GraphVertex* vertexp)
|
||||
AstNode* const nodep = vertexp->nodep();
|
||||
string front
|
||||
const string front
|
||||
= pad(filelineWidth(), nodep->fileline()->ascii() + ":") + " " + prefix + " +- ";
|
||||
if (VN_IS(nodep, VarScope)) {
|
||||
*m_ofp << front << "Variable: " << nodep->prettyName() << '\n';
|
||||
|
|
@ -562,7 +562,7 @@ private:
|
|||
std::set<AstSenTree*> senouts; // List of all sensitivities for new signal
|
||||
if (const CdcLogicVertex* const vvertexp = dynamic_cast<CdcLogicVertex*>(vertexp)) {
|
||||
if (vvertexp) {} // Unused
|
||||
} else if (CdcVarVertex* vvertexp = dynamic_cast<CdcVarVertex*>(vertexp)) {
|
||||
} else if (const CdcVarVertex* const vvertexp = dynamic_cast<CdcVarVertex*>(vertexp)) {
|
||||
// If primary I/O, give it domain of the input
|
||||
const AstVar* const varp = vvertexp->varScp()->varp();
|
||||
if (varp->isPrimaryIO() && varp->isNonOutput() && !traceDests) {
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ private:
|
|||
|
||||
// Later code will expand words which adds to GCC compile time,
|
||||
// so add penalty based on word width also
|
||||
EmitCBaseCounterVisitor visitor{initp};
|
||||
const EmitCBaseCounterVisitor visitor{initp};
|
||||
m_statep->m_numStmts += visitor.count() + m_varEqnp->widthWords();
|
||||
}
|
||||
|
||||
|
|
@ -214,8 +214,8 @@ public:
|
|||
m_detects = 0;
|
||||
{
|
||||
AstVar* const varp = m_vscp->varp();
|
||||
string newvarname{"__Vchglast__" + m_vscp->scopep()->nameDotless() + "__"
|
||||
+ varp->shortName()};
|
||||
const string newvarname{"__Vchglast__" + m_vscp->scopep()->nameDotless() + "__"
|
||||
+ varp->shortName()};
|
||||
// Create: VARREF(_last)
|
||||
// ASSIGN(VARREF(_last), VARREF(var))
|
||||
// ...
|
||||
|
|
@ -250,7 +250,7 @@ private:
|
|||
const AstUser1InUse m_inuser1;
|
||||
|
||||
// STATE
|
||||
ChangedState* m_statep; // Shared state across visitors
|
||||
ChangedState* const m_statep; // Shared state across visitors
|
||||
|
||||
// METHODS
|
||||
VL_DEBUG_FUNC; // Declare debug()
|
||||
|
|
|
|||
|
|
@ -34,9 +34,9 @@ private:
|
|||
// MEMBERS
|
||||
const AstUser1InUse m_inuser1;
|
||||
string m_prefix; // String prefix to add to name based on hier
|
||||
AstScope* m_classScopep = nullptr; // Package moving scopes into
|
||||
const AstScope* m_classScopep = nullptr; // Package moving scopes into
|
||||
AstScope* m_packageScopep = nullptr; // Class package scope
|
||||
AstNodeFTask* m_ftaskp = nullptr; // Current task
|
||||
const AstNodeFTask* m_ftaskp = nullptr; // Current task
|
||||
std::vector<std::pair<AstNode*, AstScope*>> m_moves;
|
||||
|
||||
// NODE STATE
|
||||
|
|
@ -67,7 +67,7 @@ private:
|
|||
v3Global.rootp()->topModulep()->addStmtp(cellp);
|
||||
// Find class's scope
|
||||
// Alternative would be to move this and related to V3Scope
|
||||
AstScope* classScopep = nullptr;
|
||||
const AstScope* classScopep = nullptr;
|
||||
for (AstNode* itp = nodep->stmtsp(); itp; itp = itp->nextp()) {
|
||||
if ((classScopep = VN_CAST(itp, Scope))) break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ private:
|
|||
enum CleanState : uint8_t { CS_UNKNOWN, CS_CLEAN, CS_DIRTY };
|
||||
|
||||
// STATE
|
||||
AstNodeModule* m_modp = nullptr;
|
||||
const AstNodeModule* m_modp = nullptr;
|
||||
|
||||
// METHODS
|
||||
VL_DEBUG_FUNC; // Declare debug()
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ private:
|
|||
|
||||
// STATE
|
||||
AstNodeModule* m_modp = nullptr; // Current module
|
||||
AstTopScope* m_topScopep = nullptr; // Current top scope
|
||||
const AstTopScope* m_topScopep = nullptr; // Current top scope
|
||||
AstScope* m_scopep = nullptr; // Current scope
|
||||
AstCFunc* m_evalFuncp = nullptr; // Top eval function we are creating
|
||||
AstCFunc* m_initFuncp = nullptr; // Top initial function we are creating
|
||||
|
|
@ -97,7 +97,7 @@ private:
|
|||
varp->v3warn(E_UNSUPPORTED, "Unsupported: Clock edge on non-single bit signal: "
|
||||
<< varp->prettyNameQ());
|
||||
}
|
||||
string newvarname
|
||||
const string newvarname
|
||||
= (string("__Vclklast__") + vscp->scopep()->nameDotless() + "__" + varp->name());
|
||||
AstVar* const newvarp = new AstVar(vscp->fileline(), AstVarType::MODULETEMP, newvarname,
|
||||
VFlagLogicPacked(), 1);
|
||||
|
|
@ -184,9 +184,9 @@ private:
|
|||
return senEqnp;
|
||||
}
|
||||
AstIf* makeActiveIf(AstSenTree* sensesp) {
|
||||
AstNode* senEqnp = createSenseEquation(sensesp->sensesp());
|
||||
AstNode* const senEqnp = createSenseEquation(sensesp->sensesp());
|
||||
UASSERT_OBJ(senEqnp, sensesp, "No sense equation, shouldn't be in sequent activation.");
|
||||
AstIf* newifp = new AstIf(sensesp->fileline(), senEqnp, nullptr, nullptr);
|
||||
AstIf* const newifp = new AstIf(sensesp->fileline(), senEqnp, nullptr, nullptr);
|
||||
return newifp;
|
||||
}
|
||||
void clearLastSen() {
|
||||
|
|
@ -215,11 +215,11 @@ private:
|
|||
AstCFunc* funcp = nullptr;
|
||||
|
||||
// Unlink all statements, then add item by item to new sub-functions
|
||||
AstBegin* tempp = new AstBegin{ofuncp->fileline(), "[EditWrapper]",
|
||||
ofuncp->stmtsp()->unlinkFrBackWithNext()};
|
||||
AstBegin* const tempp = new AstBegin{ofuncp->fileline(), "[EditWrapper]",
|
||||
ofuncp->stmtsp()->unlinkFrBackWithNext()};
|
||||
if (ofuncp->finalsp()) tempp->addStmtsp(ofuncp->finalsp()->unlinkFrBackWithNext());
|
||||
while (tempp->stmtsp()) {
|
||||
AstNode* itemp = tempp->stmtsp()->unlinkFrBack();
|
||||
AstNode* const itemp = tempp->stmtsp()->unlinkFrBack();
|
||||
const int stmts = EmitCBaseCounterVisitor(itemp).count();
|
||||
if (!funcp || (func_stmts + stmts) > v3Global.opt.outputSplitCFuncs()) {
|
||||
// Make a new function
|
||||
|
|
@ -231,7 +231,7 @@ private:
|
|||
funcp->slow(ofuncp->slow());
|
||||
m_topScopep->scopep()->addActivep(funcp);
|
||||
//
|
||||
AstCCall* callp = new AstCCall{funcp->fileline(), funcp};
|
||||
AstCCall* const callp = new AstCCall{funcp->fileline(), funcp};
|
||||
ofuncp->addStmtsp(callp);
|
||||
func_stmts = 0;
|
||||
}
|
||||
|
|
@ -289,7 +289,7 @@ private:
|
|||
// UINFO(4, " SCOPE " << nodep << endl);
|
||||
m_scopep = nodep;
|
||||
iterateChildren(nodep);
|
||||
if (AstNode* movep = nodep->finalClksp()) {
|
||||
if (AstNode* const movep = nodep->finalClksp()) {
|
||||
UASSERT_OBJ(m_topScopep, nodep, "Final clocks under non-top scope");
|
||||
movep->unlinkFrBackWithNext();
|
||||
m_evalFuncp->addFinalsp(movep);
|
||||
|
|
@ -297,7 +297,7 @@ private:
|
|||
m_scopep = nullptr;
|
||||
}
|
||||
virtual void visit(AstNodeProcedure* nodep) override {
|
||||
if (AstNode* stmtsp = nodep->bodysp()) {
|
||||
if (AstNode* const stmtsp = nodep->bodysp()) {
|
||||
stmtsp->unlinkFrBackWithNext();
|
||||
nodep->addNextHere(stmtsp);
|
||||
}
|
||||
|
|
@ -307,12 +307,12 @@ private:
|
|||
// nodep->dumpTree(cout, "ct:");
|
||||
// COVERTOGGLE(INC, ORIG, CHANGE) ->
|
||||
// IF(ORIG ^ CHANGE) { INC; CHANGE = ORIG; }
|
||||
AstNode* incp = nodep->incp()->unlinkFrBack();
|
||||
AstNode* origp = nodep->origp()->unlinkFrBack();
|
||||
AstNode* changeWrp = nodep->changep()->unlinkFrBack();
|
||||
AstNode* changeRdp = ConvertWriteRefsToRead::main(changeWrp->cloneTree(false));
|
||||
AstIf* newp = new AstIf(nodep->fileline(), new AstXor(nodep->fileline(), origp, changeRdp),
|
||||
incp, nullptr);
|
||||
AstNode* const incp = nodep->incp()->unlinkFrBack();
|
||||
AstNode* const origp = nodep->origp()->unlinkFrBack();
|
||||
AstNode* const changeWrp = nodep->changep()->unlinkFrBack();
|
||||
AstNode* const changeRdp = ConvertWriteRefsToRead::main(changeWrp->cloneTree(false));
|
||||
AstIf* const newp = new AstIf(
|
||||
nodep->fileline(), new AstXor(nodep->fileline(), origp, changeRdp), incp, nullptr);
|
||||
// We could add another IF to detect posedges, and only increment if so.
|
||||
// It's another whole branch though versus a potential memory miss.
|
||||
// We'll go with the miss.
|
||||
|
|
@ -325,7 +325,7 @@ private:
|
|||
// Link to global function
|
||||
if (nodep->formCallTree()) {
|
||||
UINFO(4, " formCallTree " << nodep << endl);
|
||||
AstCCall* callp = new AstCCall(nodep->fileline(), nodep);
|
||||
AstCCall* const callp = new AstCCall(nodep->fileline(), nodep);
|
||||
m_finalFuncp->addStmtsp(callp);
|
||||
}
|
||||
}
|
||||
|
|
@ -353,7 +353,7 @@ private:
|
|||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
} else if (m_mtaskBodyp) {
|
||||
UINFO(4, " TR ACTIVE " << nodep << endl);
|
||||
AstNode* stmtsp = nodep->stmtsp()->unlinkFrBackWithNext();
|
||||
AstNode* const stmtsp = nodep->stmtsp()->unlinkFrBackWithNext();
|
||||
if (nodep->hasClocked()) {
|
||||
UASSERT_OBJ(!nodep->hasInitial(), nodep,
|
||||
"Initial block should not have clock sensitivity");
|
||||
|
|
@ -378,7 +378,7 @@ private:
|
|||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
} else {
|
||||
UINFO(4, " ACTIVE " << nodep << endl);
|
||||
AstNode* stmtsp = nodep->stmtsp()->unlinkFrBackWithNext();
|
||||
AstNode* const stmtsp = nodep->stmtsp()->unlinkFrBackWithNext();
|
||||
if (nodep->hasClocked()) {
|
||||
// Remember the latest sensitivity so we can compare it next time
|
||||
UASSERT_OBJ(!nodep->hasInitial(), nodep,
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ public:
|
|||
|
||||
void apply(AstNodeModule* modp) {
|
||||
if (m_inline) {
|
||||
AstPragmaType type
|
||||
const AstPragmaType type
|
||||
= m_inlineValue ? AstPragmaType::INLINE_MODULE : AstPragmaType::NO_INLINE_MODULE;
|
||||
AstNode* const nodep = new AstPragma(modp->fileline(), type);
|
||||
modp->addStmtp(nodep);
|
||||
|
|
@ -223,9 +223,9 @@ using V3ConfigModuleResolver = V3ConfigWildcardResolver<V3ConfigModule>;
|
|||
// lint/coverage/tracing on/off
|
||||
class V3ConfigIgnoresLine final {
|
||||
public:
|
||||
int m_lineno; // Line number to make change at
|
||||
V3ErrorCode m_code; // Error code
|
||||
bool m_on; // True to enable message
|
||||
const int m_lineno; // Line number to make change at
|
||||
const V3ErrorCode m_code; // Error code
|
||||
const bool m_on; // True to enable message
|
||||
V3ConfigIgnoresLine(V3ErrorCode code, int lineno, bool on)
|
||||
: m_lineno{lineno}
|
||||
, m_code{code}
|
||||
|
|
@ -502,7 +502,7 @@ void V3Config::applyFTask(AstNodeModule* modulep, AstNodeFTask* ftaskp) {
|
|||
const string& modname = modulep->name();
|
||||
V3ConfigModule* modp = V3ConfigResolver::s().modules().resolve(modname);
|
||||
if (!modp) return;
|
||||
V3ConfigFTask* ftp = modp->ftasks().resolve(ftaskp->name());
|
||||
const V3ConfigFTask* const ftp = modp->ftasks().resolve(ftaskp->name());
|
||||
if (ftp) ftp->apply(ftaskp);
|
||||
}
|
||||
|
||||
|
|
|
|||
573
src/V3Const.cpp
573
src/V3Const.cpp
File diff suppressed because it is too large
Load Diff
|
|
@ -43,7 +43,7 @@ private:
|
|||
using LinenoSet = std::set<int>;
|
||||
|
||||
struct ToggleEnt {
|
||||
string m_comment; // Comment for coverage dump
|
||||
const string m_comment; // Comment for coverage dump
|
||||
AstNode* m_varRefp; // How to get to this element
|
||||
AstNode* m_chgRefp; // How to get to this element
|
||||
ToggleEnt(const string& comment, AstNode* vp, AstNode* cp)
|
||||
|
|
@ -209,7 +209,7 @@ private:
|
|||
|
||||
// VISITORS - BOTH
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
AstNodeModule* const origModp = m_modp;
|
||||
const AstNodeModule* const origModp = m_modp;
|
||||
VL_RESTORER(m_modp);
|
||||
VL_RESTORER(m_state);
|
||||
{
|
||||
|
|
@ -245,9 +245,9 @@ private:
|
|||
linesCov(m_state, nodep), 0, traceNameForLine(nodep, "block"));
|
||||
if (AstNodeProcedure* const itemp = VN_CAST(nodep, NodeProcedure)) {
|
||||
itemp->addStmtp(newp);
|
||||
} else if (AstNodeFTask* itemp = VN_CAST(nodep, NodeFTask)) {
|
||||
} else if (AstNodeFTask* const itemp = VN_CAST(nodep, NodeFTask)) {
|
||||
itemp->addStmtsp(newp);
|
||||
} else if (AstWhile* itemp = VN_CAST(nodep, While)) {
|
||||
} else if (AstWhile* const itemp = VN_CAST(nodep, While)) {
|
||||
itemp->addBodysp(newp);
|
||||
} else {
|
||||
nodep->v3fatalSrc("Bad node type");
|
||||
|
|
@ -324,7 +324,7 @@ private:
|
|||
} else {
|
||||
toggleVarBottom(above, varp);
|
||||
}
|
||||
} else if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||
} else if (const AstUnpackArrayDType* const adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||
for (int index_docs = adtypep->lo(); index_docs <= adtypep->hi(); ++index_docs) {
|
||||
const int index_code = index_docs - adtypep->lo();
|
||||
ToggleEnt newent(above.m_comment + string("[") + cvtToStr(index_docs) + "]",
|
||||
|
|
@ -336,9 +336,9 @@ private:
|
|||
chgVarp);
|
||||
newent.cleanup();
|
||||
}
|
||||
} else if (AstPackArrayDType* adtypep = VN_CAST(dtypep, PackArrayDType)) {
|
||||
} else if (const AstPackArrayDType* const adtypep = VN_CAST(dtypep, PackArrayDType)) {
|
||||
for (int index_docs = adtypep->lo(); index_docs <= adtypep->hi(); ++index_docs) {
|
||||
AstNodeDType* const subtypep = adtypep->subDTypep()->skipRefp();
|
||||
const 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),
|
||||
|
|
@ -349,7 +349,7 @@ private:
|
|||
chgVarp);
|
||||
newent.cleanup();
|
||||
}
|
||||
} else if (AstStructDType* adtypep = VN_CAST(dtypep, StructDType)) {
|
||||
} else if (const AstStructDType* const adtypep = VN_CAST(dtypep, StructDType)) {
|
||||
// For now it's packed, so similar to array
|
||||
for (AstMemberDType* itemp = adtypep->membersp(); itemp;
|
||||
itemp = VN_AS(itemp->nextp(), MemberDType)) {
|
||||
|
|
@ -363,9 +363,9 @@ private:
|
|||
toggleVarRecurse(subtypep, depth + 1, newent, varp, chgVarp);
|
||||
newent.cleanup();
|
||||
}
|
||||
} else if (AstUnionDType* adtypep = VN_CAST(dtypep, UnionDType)) {
|
||||
} else if (const AstUnionDType* const adtypep = VN_CAST(dtypep, UnionDType)) {
|
||||
// Arbitrarily handle only the first member of the union
|
||||
if (AstMemberDType* const itemp = adtypep->membersp()) {
|
||||
if (const AstMemberDType* const itemp = adtypep->membersp()) {
|
||||
AstNodeDType* const subtypep = itemp->subDTypep()->skipRefp();
|
||||
ToggleEnt newent(above.m_comment + string(".") + itemp->name(),
|
||||
above.m_varRefp->cloneTree(true),
|
||||
|
|
|
|||
|
|
@ -382,7 +382,7 @@ private:
|
|||
for (AstVarScope* vscp : m_vscsp) {
|
||||
if (vscp->user1() == 0) {
|
||||
UINFO(4, " Dead " << vscp << endl);
|
||||
std::pair<AssignMap::iterator, AssignMap::iterator> eqrange
|
||||
const std::pair<AssignMap::iterator, AssignMap::iterator> eqrange
|
||||
= m_assignMap.equal_range(vscp);
|
||||
for (AssignMap::iterator itr = eqrange.first; itr != eqrange.second; ++itr) {
|
||||
AstNodeAssign* const assp = itr->second;
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ private:
|
|||
|
||||
// STATE
|
||||
AstActive* m_activep = nullptr; // Current activate
|
||||
AstCFunc* m_cfuncp = nullptr; // Current public C Function
|
||||
const AstCFunc* m_cfuncp = nullptr; // Current public C Function
|
||||
AstAssignDly* m_nextDlyp = nullptr; // Next delayed assignment in a list of assignments
|
||||
bool m_inDly = false; // True in delayed assignments
|
||||
bool m_inLoop = false; // True in for loops
|
||||
|
|
@ -106,7 +106,7 @@ private:
|
|||
if (blocking) nodep->user5(true);
|
||||
AstVarScope* const vscp = nodep->varScopep();
|
||||
// UINFO(4, " MVU " << blocking << " " << nodep << endl);
|
||||
AstNode* const lastrefp = vscp->user5p();
|
||||
const AstNode* const lastrefp = vscp->user5p();
|
||||
if (!lastrefp) {
|
||||
vscp->user5p(nodep);
|
||||
} else {
|
||||
|
|
@ -275,7 +275,7 @@ private:
|
|||
// vval = constant, can just push constant into where we use it
|
||||
valreadp = nodep->rhsp()->unlinkFrBack();
|
||||
} else {
|
||||
string valvarname
|
||||
const string valvarname
|
||||
= (string("__Vdlyvval__") + oldvarp->shortName() + "__v" + cvtToStr(modVecNum));
|
||||
AstVarScope* const valvscp
|
||||
= createVarSc(varrefp->varScopep(), valvarname, 0, nodep->rhsp()->dtypep());
|
||||
|
|
@ -295,7 +295,7 @@ private:
|
|||
setvscp = VN_AS(nodep->user3p(), VarScope);
|
||||
++m_statSharedSet;
|
||||
} else { // Create new one
|
||||
string setvarname
|
||||
const string setvarname
|
||||
= (string("__Vdlyvset__") + oldvarp->shortName() + "__v" + cvtToStr(modVecNum));
|
||||
setvscp = createVarSc(varrefp->varScopep(), setvarname, 1, nullptr);
|
||||
setinitp = new AstAssignPre(nodep->fileline(),
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ private:
|
|||
// NODE STATE
|
||||
|
||||
// STATE
|
||||
AstNodeModule* m_modp = nullptr; // Current module
|
||||
AstCFunc* m_cfuncp = nullptr; // Current function
|
||||
const AstNodeModule* m_modp = nullptr; // Current module
|
||||
const AstCFunc* m_cfuncp = nullptr; // Current function
|
||||
int m_depth = 0; // How deep in an expression
|
||||
int m_deepNum = 0; // How many functions made
|
||||
|
||||
|
|
@ -94,9 +94,9 @@ private:
|
|||
if (m_depth > v3Global.opt.compLimitBlocks()
|
||||
&& !VN_IS(nodep, NodeCCall)) { // Already done
|
||||
UINFO(4, "DeepBlocks " << m_depth << " " << nodep << endl);
|
||||
const AstNode* backp = nodep->backp(); // Only for debug
|
||||
const AstNode* const backp = nodep->backp(); // Only for debug
|
||||
if (debug() >= 9) backp->dumpTree(cout, "- pre : ");
|
||||
AstCFunc* funcp = createDeepFunc(nodep);
|
||||
AstCFunc* const funcp = createDeepFunc(nodep);
|
||||
iterate(funcp);
|
||||
if (debug() >= 9) backp->dumpTree(cout, "- post: ");
|
||||
if (debug() >= 9) funcp->dumpTree(cout, "- func: ");
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ private:
|
|||
AstCFunc* const topFuncp = it->second;
|
||||
auto nextIt1 = it;
|
||||
++nextIt1;
|
||||
bool moreOfSame1 = (nextIt1 != m_modFuncs.end() && nextIt1->first == name);
|
||||
const 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");
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ void EmitCBaseVisitor::emitVarDecl(const AstVar* nodep, bool asRef) {
|
|||
void EmitCBaseVisitor::emitModCUse(const AstNodeModule* modp, VUseType useType) {
|
||||
string nl;
|
||||
for (AstNode* itemp = modp->stmtsp(); itemp; itemp = itemp->nextp()) {
|
||||
if (AstCUse* usep = VN_CAST(itemp, CUse)) {
|
||||
if (AstCUse* const usep = VN_CAST(itemp, CUse)) {
|
||||
if (usep->useType() == useType) {
|
||||
if (usep->useType().isInclude()) {
|
||||
puts("#include \"" + prefixNameProtect(usep) + ".h\"\n");
|
||||
|
|
@ -238,7 +238,7 @@ void EmitCBaseVisitor::emitModCUse(const AstNodeModule* modp, VUseType useType)
|
|||
void EmitCBaseVisitor::emitTextSection(const AstNodeModule* modp, AstType type) {
|
||||
int last_line = -999;
|
||||
for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (const AstNodeText* textp = VN_CAST(nodep, NodeText)) {
|
||||
if (const AstNodeText* const textp = VN_CAST(nodep, NodeText)) {
|
||||
if (nodep->type() == type) {
|
||||
if (last_line != nodep->fileline()->lineno()) {
|
||||
if (last_line < 0) {
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ protected:
|
|||
virtual void visit(AstConst* nodep) override {
|
||||
const V3Number& num = nodep->num();
|
||||
UASSERT_OBJ(!num.isFourState(), nodep, "4-state value in constant pool");
|
||||
AstNodeDType* const dtypep = nodep->dtypep();
|
||||
const AstNodeDType* const dtypep = nodep->dtypep();
|
||||
if (num.isString()) {
|
||||
// Note: putsQuoted does not track indentation, so we use this instead
|
||||
puts("\"");
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ void EmitCFunc::displayEmit(AstNode* nodep, bool isScan) {
|
|||
puts("VL_FSCANF_IX(");
|
||||
iterate(dispp->filep());
|
||||
puts(",");
|
||||
} else if (const AstSScanF* dispp = VN_CAST(nodep, SScanF)) {
|
||||
} else if (const AstSScanF* const dispp = VN_CAST(nodep, SScanF)) {
|
||||
isStmt = false;
|
||||
checkMaxWords(dispp->fromp());
|
||||
puts("VL_SSCANF_I");
|
||||
|
|
@ -212,7 +212,7 @@ void EmitCFunc::displayEmit(AstNode* nodep, bool isScan) {
|
|||
puts(",");
|
||||
iterate(dispp->fromp());
|
||||
puts(",");
|
||||
} else if (const AstDisplay* dispp = VN_CAST(nodep, Display)) {
|
||||
} else if (const AstDisplay* const dispp = VN_CAST(nodep, Display)) {
|
||||
isStmt = true;
|
||||
if (dispp->filep()) {
|
||||
puts("VL_FWRITEF(");
|
||||
|
|
@ -221,7 +221,7 @@ void EmitCFunc::displayEmit(AstNode* nodep, bool isScan) {
|
|||
} else {
|
||||
puts("VL_WRITEF(");
|
||||
}
|
||||
} else if (const AstSFormat* dispp = VN_CAST(nodep, SFormat)) {
|
||||
} else if (const AstSFormat* const dispp = VN_CAST(nodep, SFormat)) {
|
||||
isStmt = true;
|
||||
puts("VL_SFORMAT_X(");
|
||||
puts(cvtToStr(dispp->lhsp()->widthMin()));
|
||||
|
|
@ -315,13 +315,14 @@ void EmitCFunc::displayArg(AstNode* dispp, AstNode** elistp, bool isScan, const
|
|||
}
|
||||
emitDispState.pushArg(fmtLetter, argp, "");
|
||||
if (fmtLetter == 't' || fmtLetter == '^') {
|
||||
AstSFormatF* fmtp = nullptr;
|
||||
if (AstDisplay* const nodep = VN_CAST(dispp, Display))
|
||||
const AstSFormatF* fmtp = nullptr;
|
||||
if (const AstDisplay* const nodep = VN_CAST(dispp, Display)) {
|
||||
fmtp = nodep->fmtp();
|
||||
else if (AstSFormat* nodep = VN_CAST(dispp, SFormat))
|
||||
} else if (const AstSFormat* const nodep = VN_CAST(dispp, SFormat)) {
|
||||
fmtp = nodep->fmtp();
|
||||
else
|
||||
} else {
|
||||
fmtp = VN_CAST(dispp, SFormatF);
|
||||
}
|
||||
UASSERT_OBJ(fmtp, dispp,
|
||||
"Use of %t must be under AstDisplay, AstSFormat, or AstSFormatF");
|
||||
UASSERT_OBJ(!fmtp->timeunit().isNone(), fmtp, "timenunit must be set");
|
||||
|
|
@ -580,14 +581,14 @@ void EmitCFunc::emitConstant(AstConst* nodep, AstVarRef* assigntop, const string
|
|||
ofp()->printf("%.17e", nodep->num().toDouble());
|
||||
}
|
||||
} else if (nodep->isQuad()) {
|
||||
vluint64_t num = nodep->toUQuad();
|
||||
const vluint64_t num = nodep->toUQuad();
|
||||
if (num < 10) {
|
||||
ofp()->printf("%" VL_PRI64 "uULL", num);
|
||||
} else {
|
||||
ofp()->printf("0x%" VL_PRI64 "xULL", num);
|
||||
}
|
||||
} else {
|
||||
uint32_t num = nodep->toUInt();
|
||||
const uint32_t num = nodep->toUInt();
|
||||
// Only 32 bits - llx + long long here just to appease CPP format warning
|
||||
if (num < 10) {
|
||||
puts(cvtToStr(num));
|
||||
|
|
@ -620,8 +621,8 @@ void EmitCFunc::emitVarReset(AstVar* varp) {
|
|||
// If a simple CONST value we initialize it using an enum
|
||||
// If an ARRAYINIT we initialize it using an initial block similar to a signal
|
||||
// puts("// parameter "+varp->nameProtect()+" = "+varp->valuep()->name()+"\n");
|
||||
} else if (AstInitArray* initarp = VN_CAST(varp->valuep(), InitArray)) {
|
||||
if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||
} else if (const AstInitArray* const initarp = VN_CAST(varp->valuep(), InitArray)) {
|
||||
if (AstUnpackArrayDType* const adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||
if (initarp->defaultp()) {
|
||||
puts("for (int __Vi=0; __Vi<" + cvtToStr(adtypep->elementsConst()));
|
||||
puts("; ++__Vi) {\n");
|
||||
|
|
@ -630,7 +631,7 @@ void EmitCFunc::emitVarReset(AstVar* varp) {
|
|||
}
|
||||
const AstInitArray::KeyItemMap& mapr = initarp->map();
|
||||
for (const auto& itr : mapr) {
|
||||
AstNode* valuep = itr.second->valuep();
|
||||
AstNode* const valuep = itr.second->valuep();
|
||||
emitSetVarConstant(varNameProtected + "[" + cvtToStr(itr.first) + "]",
|
||||
VN_AS(valuep, Const));
|
||||
}
|
||||
|
|
@ -645,26 +646,26 @@ void EmitCFunc::emitVarReset(AstVar* varp) {
|
|||
string EmitCFunc::emitVarResetRecurse(const AstVar* varp, const string& varNameProtected,
|
||||
AstNodeDType* dtypep, int depth, const string& suffix) {
|
||||
dtypep = dtypep->skipRefp();
|
||||
AstBasicDType* basicp = dtypep->basicp();
|
||||
AstBasicDType* const basicp = dtypep->basicp();
|
||||
// Returns string to do resetting, empty to do nothing (which caller should handle)
|
||||
if (AstAssocArrayDType* adtypep = VN_CAST(dtypep, AssocArrayDType)) {
|
||||
if (AstAssocArrayDType* const adtypep = VN_CAST(dtypep, AssocArrayDType)) {
|
||||
// Access std::array as C array
|
||||
const string cvtarray = (adtypep->subDTypep()->isWide() ? ".data()" : "");
|
||||
return emitVarResetRecurse(varp, varNameProtected, adtypep->subDTypep(), depth + 1,
|
||||
suffix + ".atDefault()" + cvtarray);
|
||||
} else if (VN_IS(dtypep, ClassRefDType)) {
|
||||
return ""; // Constructor does it
|
||||
} else if (AstDynArrayDType* adtypep = VN_CAST(dtypep, DynArrayDType)) {
|
||||
} else if (const AstDynArrayDType* const adtypep = VN_CAST(dtypep, DynArrayDType)) {
|
||||
// Access std::array as C array
|
||||
const string cvtarray = (adtypep->subDTypep()->isWide() ? ".data()" : "");
|
||||
return emitVarResetRecurse(varp, varNameProtected, adtypep->subDTypep(), depth + 1,
|
||||
suffix + ".atDefault()" + cvtarray);
|
||||
} else if (AstQueueDType* adtypep = VN_CAST(dtypep, QueueDType)) {
|
||||
} else if (const AstQueueDType* const adtypep = VN_CAST(dtypep, QueueDType)) {
|
||||
// Access std::array as C array
|
||||
const string cvtarray = (adtypep->subDTypep()->isWide() ? ".data()" : "");
|
||||
return emitVarResetRecurse(varp, varNameProtected, adtypep->subDTypep(), depth + 1,
|
||||
suffix + ".atDefault()" + cvtarray);
|
||||
} else if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||
} else if (const AstUnpackArrayDType* const adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||
UASSERT_OBJ(adtypep->hi() >= adtypep->lo(), varp,
|
||||
"Should have swapped msb & lsb earlier.");
|
||||
const string ivar = string("__Vi") + cvtToStr(depth);
|
||||
|
|
@ -678,7 +679,7 @@ string EmitCFunc::emitVarResetRecurse(const AstVar* varp, const string& varNameP
|
|||
// String's constructor deals with it
|
||||
return "";
|
||||
} else if (basicp) {
|
||||
bool zeroit
|
||||
const bool zeroit
|
||||
= (varp->attrFileDescr() // Zero so we don't do file IO if never $fopen
|
||||
|| (basicp && basicp->isZeroInit())
|
||||
|| (v3Global.opt.underlineZero() && !varp->name().empty() && varp->name()[0] == '_')
|
||||
|
|
@ -687,7 +688,7 @@ string EmitCFunc::emitVarResetRecurse(const AstVar* varp, const string& varNameP
|
|||
if (dtypep->isWide()) { // Handle unpacked; not basicp->isWide
|
||||
string out;
|
||||
if (varp->valuep()) {
|
||||
AstConst* const constp = VN_AS(varp->valuep(), Const);
|
||||
const AstConst* const constp = VN_AS(varp->valuep(), Const);
|
||||
if (!constp) varp->v3fatalSrc("non-const initializer for variable");
|
||||
for (int w = 0; w < varp->widthWords(); ++w) {
|
||||
out += varNameProtected + suffix + "[" + cvtToStr(w) + "] = ";
|
||||
|
|
@ -732,8 +733,8 @@ void EmitCFunc::doubleOrDetect(AstChangeDet* changep, bool& gotOne) {
|
|||
}
|
||||
iterateAndNextNull(changep->lhsp());
|
||||
} else {
|
||||
AstNode* lhsp = changep->lhsp();
|
||||
AstNode* rhsp = changep->rhsp();
|
||||
AstNode* const lhsp = changep->lhsp();
|
||||
AstNode* const rhsp = changep->rhsp();
|
||||
UASSERT_OBJ(VN_IS(lhsp, VarRef) || VN_IS(lhsp, ArraySel), changep, "Not ref?");
|
||||
UASSERT_OBJ(VN_IS(rhsp, VarRef) || VN_IS(rhsp, ArraySel), changep, "Not ref?");
|
||||
for (int word = 0; word < (changep->lhsp()->isWide() ? changep->lhsp()->widthWords() : 1);
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ protected:
|
|||
EmitCLazyDecls m_lazyDecls; // Visitor for emitting lazy declarations
|
||||
bool m_useSelfForThis = false; // Replace "this" with "vlSelf"
|
||||
const AstNodeModule* m_modp = nullptr; // Current module being emitted
|
||||
AstCFunc* m_cfuncp = nullptr; // Current function being emitted
|
||||
const AstCFunc* m_cfuncp = nullptr; // Current function being emitted
|
||||
|
||||
public:
|
||||
// METHODS
|
||||
|
|
@ -229,7 +229,7 @@ public:
|
|||
puts(nodep->nameProtect() + "\\n\"); );\n");
|
||||
|
||||
for (AstNode* subnodep = nodep->argsp(); subnodep; subnodep = subnodep->nextp()) {
|
||||
if (AstVar* varp = VN_CAST(subnodep, Var)) {
|
||||
if (AstVar* const varp = VN_CAST(subnodep, Var)) {
|
||||
if (varp->isFuncReturn()) emitVarDecl(varp);
|
||||
}
|
||||
}
|
||||
|
|
@ -265,7 +265,7 @@ public:
|
|||
virtual void visit(AstNodeAssign* nodep) override {
|
||||
bool paren = true;
|
||||
bool decind = false;
|
||||
if (AstSel* selp = VN_CAST(nodep->lhsp(), Sel)) {
|
||||
if (AstSel* const selp = VN_CAST(nodep->lhsp(), Sel)) {
|
||||
if (selp->widthMin() == 1) {
|
||||
putbs("VL_ASSIGNBIT_");
|
||||
emitIQW(selp->fromp());
|
||||
|
|
@ -292,7 +292,7 @@ public:
|
|||
iterateAndNextNull(selp->fromp());
|
||||
puts(", ");
|
||||
}
|
||||
} else if (AstGetcRefN* selp = VN_CAST(nodep->lhsp(), GetcRefN)) {
|
||||
} else if (const AstGetcRefN* const selp = VN_CAST(nodep->lhsp(), GetcRefN)) {
|
||||
iterateAndNextNull(selp->lhsp());
|
||||
puts(" = ");
|
||||
putbs("VL_PUTC_N(");
|
||||
|
|
@ -300,7 +300,7 @@ public:
|
|||
puts(", ");
|
||||
iterateAndNextNull(selp->rhsp());
|
||||
puts(", ");
|
||||
} else if (AstVar* varp = AstVar::scVarRecurse(nodep->lhsp())) {
|
||||
} else if (AstVar* const varp = AstVar::scVarRecurse(nodep->lhsp())) {
|
||||
putbs("VL_ASSIGN_"); // Set a systemC variable
|
||||
emitScIQW(varp);
|
||||
emitIQW(nodep);
|
||||
|
|
@ -308,7 +308,7 @@ public:
|
|||
puts(cvtToStr(nodep->widthMin()) + ",");
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
puts(", ");
|
||||
} else if (AstVar* varp = AstVar::scVarRecurse(nodep->rhsp())) {
|
||||
} else if (AstVar* const varp = AstVar::scVarRecurse(nodep->rhsp())) {
|
||||
putbs("VL_ASSIGN_"); // Get a systemC variable
|
||||
emitIQW(nodep);
|
||||
emitScIQW(varp);
|
||||
|
|
@ -348,7 +348,7 @@ public:
|
|||
virtual void visit(AstAssocSel* nodep) override {
|
||||
iterateAndNextNull(nodep->fromp());
|
||||
putbs(".at(");
|
||||
AstAssocArrayDType* adtypep = VN_AS(nodep->fromp()->dtypep(), AssocArrayDType);
|
||||
AstAssocArrayDType* const adtypep = VN_AS(nodep->fromp()->dtypep(), AssocArrayDType);
|
||||
UASSERT_OBJ(adtypep, nodep, "Associative select on non-associative type");
|
||||
if (adtypep->keyDTypep()->isWide()) {
|
||||
emitCvtWideArray(nodep->bitp(), nodep->fromp());
|
||||
|
|
@ -429,11 +429,11 @@ public:
|
|||
virtual void visit(AstWith* nodep) override {
|
||||
// With uses a C++11 lambda
|
||||
putbs("[=](");
|
||||
if (auto* argrefp = nodep->indexArgRefp()) {
|
||||
if (auto* const argrefp = nodep->indexArgRefp()) {
|
||||
putbs(argrefp->dtypep()->cType(argrefp->nameProtect(), false, false));
|
||||
puts(",");
|
||||
}
|
||||
if (auto* argrefp = nodep->valueArgRefp()) {
|
||||
if (auto* const argrefp = nodep->valueArgRefp()) {
|
||||
putbs(argrefp->dtypep()->cType(argrefp->nameProtect(), false, false));
|
||||
}
|
||||
// Probably fragile, V3Task may need to convert to a AstCReturn
|
||||
|
|
@ -632,12 +632,12 @@ public:
|
|||
puts(cvtToStr(nodep->memp()->dtypep()->subDTypep()->widthMin()));
|
||||
uint32_t array_lo = 0;
|
||||
{
|
||||
const AstVarRef* varrefp = VN_CAST(nodep->memp(), VarRef);
|
||||
const AstVarRef* const varrefp = VN_CAST(nodep->memp(), VarRef);
|
||||
if (!varrefp) {
|
||||
nodep->v3error(nodep->verilogKwd() << " loading non-variable");
|
||||
} else if (VN_IS(varrefp->varp()->dtypeSkipRefp(), AssocArrayDType)) {
|
||||
// nodep->memp() below will when verilated code is compiled create a C++ template
|
||||
} else if (const AstUnpackArrayDType* adtypep
|
||||
} else if (const AstUnpackArrayDType* const adtypep
|
||||
= VN_CAST(varrefp->varp()->dtypeSkipRefp(), UnpackArrayDType)) {
|
||||
putbs(", ");
|
||||
puts(cvtToStr(varrefp->varp()->dtypep()->arrayUnpackedElements()));
|
||||
|
|
@ -716,11 +716,11 @@ public:
|
|||
uint32_t array_lo = 0;
|
||||
uint32_t array_size = 0;
|
||||
{
|
||||
const AstVarRef* varrefp = VN_CAST(nodep->memp(), VarRef);
|
||||
const AstVarRef* const varrefp = VN_CAST(nodep->memp(), VarRef);
|
||||
if (!varrefp) {
|
||||
nodep->v3error(nodep->verilogKwd() << " loading non-variable");
|
||||
} else if (VN_CAST(varrefp->varp()->dtypeSkipRefp(), BasicDType)) {
|
||||
} else if (const AstUnpackArrayDType* adtypep
|
||||
} else if (const AstUnpackArrayDType* const adtypep
|
||||
= VN_CAST(varrefp->varp()->dtypeSkipRefp(), UnpackArrayDType)) {
|
||||
array_lo = adtypep->lo();
|
||||
array_size = adtypep->elementsConst();
|
||||
|
|
@ -980,7 +980,7 @@ public:
|
|||
if (nodep->lhsp()->isWide()) {
|
||||
visit(static_cast<AstNodeUniop*>(nodep));
|
||||
} else {
|
||||
AstVarRef* const vrefp = VN_CAST(nodep->lhsp(), VarRef);
|
||||
const AstVarRef* const vrefp = VN_CAST(nodep->lhsp(), VarRef);
|
||||
const int widthPow2 = vrefp ? vrefp->varp()->dtypep()->widthPow2()
|
||||
: nodep->lhsp()->dtypep()->widthPow2();
|
||||
UASSERT_OBJ(widthPow2 > 1, nodep,
|
||||
|
|
@ -1064,8 +1064,8 @@ public:
|
|||
virtual void visit(AstStreamL* nodep) override {
|
||||
// Attempt to use a "fast" stream function for slice size = power of 2
|
||||
if (!nodep->isWide()) {
|
||||
uint32_t isPow2 = VN_AS(nodep->rhsp(), Const)->num().countOnes() == 1;
|
||||
uint32_t sliceSize = VN_AS(nodep->rhsp(), Const)->toUInt();
|
||||
const uint32_t isPow2 = VN_AS(nodep->rhsp(), Const)->num().countOnes() == 1;
|
||||
const uint32_t sliceSize = VN_AS(nodep->rhsp(), Const)->toUInt();
|
||||
if (isPow2 && sliceSize <= (nodep->isQuad() ? sizeof(uint64_t) : sizeof(uint32_t))) {
|
||||
puts("VL_STREAML_FAST_");
|
||||
emitIQW(nodep);
|
||||
|
|
@ -1077,7 +1077,7 @@ public:
|
|||
puts(",");
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
puts(", ");
|
||||
uint32_t rd_log2 = V3Number::log2b(VN_AS(nodep->rhsp(), Const)->toUInt());
|
||||
const uint32_t rd_log2 = V3Number::log2b(VN_AS(nodep->rhsp(), Const)->toUInt());
|
||||
puts(cvtToStr(rd_log2) + ")");
|
||||
return;
|
||||
}
|
||||
|
|
@ -1133,7 +1133,7 @@ public:
|
|||
}
|
||||
virtual void visit(AstAddrOfCFunc* nodep) override {
|
||||
// Note: Can be thought to handle more, but this is all that is needed right now
|
||||
AstCFunc* const funcp = nodep->funcp();
|
||||
const AstCFunc* const funcp = nodep->funcp();
|
||||
UASSERT_OBJ(funcp->isLoose(), nodep, "Cannot take address of non-loose method");
|
||||
puts("&");
|
||||
puts(funcNameProtect(funcp));
|
||||
|
|
@ -1205,7 +1205,7 @@ public:
|
|||
}
|
||||
}
|
||||
virtual void visit(AstCReset* nodep) override {
|
||||
AstVar* varp = nodep->varrefp()->varp();
|
||||
AstVar* const varp = nodep->varrefp()->varp();
|
||||
emitVarReset(varp);
|
||||
}
|
||||
virtual void visit(AstExecGraph* nodep) override {
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ class EmitCGatherDependencies final : AstNVisitor {
|
|||
|
||||
public:
|
||||
static const std::set<std::string> gather(AstCFunc* cfuncp) {
|
||||
EmitCGatherDependencies visitor{cfuncp};
|
||||
const EmitCGatherDependencies visitor{cfuncp};
|
||||
return std::move(visitor.m_dependencies);
|
||||
}
|
||||
};
|
||||
|
|
@ -348,7 +348,7 @@ class EmitCImp final : EmitCFunc {
|
|||
// just looking for loading the wrong model
|
||||
VHashSha256 hash;
|
||||
for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (const AstVar* varp = VN_CAST(nodep, Var)) {
|
||||
if (const AstVar* const varp = VN_CAST(nodep, Var)) {
|
||||
hash.insert(varp->name());
|
||||
hash.insert(varp->dtypep()->width());
|
||||
}
|
||||
|
|
@ -369,7 +369,7 @@ class EmitCImp final : EmitCFunc {
|
|||
|
||||
// Save all members
|
||||
for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (const AstVar* varp = VN_CAST(nodep, Var)) {
|
||||
if (const AstVar* const varp = VN_CAST(nodep, Var)) {
|
||||
if (varp->isIO() && modp->isTop() && optSystemC()) {
|
||||
// System C top I/O doesn't need loading, as the
|
||||
// lower level subinst code does it.
|
||||
|
|
@ -576,7 +576,7 @@ class EmitCTrace final : EmitCFunc {
|
|||
if (m_slow) filename += "__Slow";
|
||||
filename += ".cpp";
|
||||
|
||||
AstCFile* cfilep = newCFile(filename, m_slow, true /*source*/);
|
||||
AstCFile* const cfilep = newCFile(filename, m_slow, true /*source*/);
|
||||
cfilep->support(true);
|
||||
|
||||
if (optSystemC()) {
|
||||
|
|
@ -595,23 +595,23 @@ class EmitCTrace final : EmitCFunc {
|
|||
}
|
||||
|
||||
bool emitTraceIsScBv(AstTraceInc* nodep) {
|
||||
const AstVarRef* varrefp = VN_CAST(nodep->declp()->valuep(), VarRef);
|
||||
const AstVarRef* const varrefp = VN_CAST(nodep->declp()->valuep(), VarRef);
|
||||
if (!varrefp) return false;
|
||||
AstVar* varp = varrefp->varp();
|
||||
AstVar* const varp = varrefp->varp();
|
||||
return varp->isSc() && varp->isScBv();
|
||||
}
|
||||
|
||||
bool emitTraceIsScBigUint(AstTraceInc* nodep) {
|
||||
const AstVarRef* varrefp = VN_CAST(nodep->declp()->valuep(), VarRef);
|
||||
const AstVarRef* const varrefp = VN_CAST(nodep->declp()->valuep(), VarRef);
|
||||
if (!varrefp) return false;
|
||||
AstVar* varp = varrefp->varp();
|
||||
AstVar* const varp = varrefp->varp();
|
||||
return varp->isSc() && varp->isScBigUint();
|
||||
}
|
||||
|
||||
bool emitTraceIsScUint(AstTraceInc* nodep) {
|
||||
const AstVarRef* varrefp = VN_CAST(nodep->declp()->valuep(), VarRef);
|
||||
const AstVarRef* const varrefp = VN_CAST(nodep->declp()->valuep(), VarRef);
|
||||
if (!varrefp) return false;
|
||||
AstVar* varp = varrefp->varp();
|
||||
AstVar* const varp = varrefp->varp();
|
||||
return varp->isSc() && varp->isScUint();
|
||||
}
|
||||
|
||||
|
|
@ -714,7 +714,7 @@ class EmitCTrace final : EmitCFunc {
|
|||
if (v3Global.opt.traceFormat().fst()) {
|
||||
// Skip over refs-to-refs, but stop before final ref so can get data type name
|
||||
// Alternatively back in V3Width we could push enum names from upper typedefs
|
||||
if (AstEnumDType* enump = VN_CAST(nodep->skipRefToEnump(), EnumDType)) {
|
||||
if (AstEnumDType* const enump = VN_CAST(nodep->skipRefToEnump(), EnumDType)) {
|
||||
int enumNum = enump->user1();
|
||||
if (!enumNum) {
|
||||
enumNum = ++m_enumNum;
|
||||
|
|
@ -734,7 +734,7 @@ class EmitCTrace final : EmitCFunc {
|
|||
puts("= {");
|
||||
for (AstEnumItem* itemp = enump->itemsp(); itemp;
|
||||
itemp = VN_AS(itemp->nextp(), EnumItem)) {
|
||||
AstConst* constp = VN_AS(itemp->valuep(), Const);
|
||||
AstConst* const constp = VN_AS(itemp->valuep(), Const);
|
||||
if (++nvals > 1) puts(", ");
|
||||
putbs("\"" + constp->num().displayed(nodep, "%0b") + "\"");
|
||||
}
|
||||
|
|
@ -785,7 +785,7 @@ class EmitCTrace final : EmitCFunc {
|
|||
|
||||
void emitTraceValue(AstTraceInc* nodep, int arrayindex) {
|
||||
if (AstVarRef* const varrefp = VN_CAST(nodep->valuep(), VarRef)) {
|
||||
AstVar* varp = varrefp->varp();
|
||||
AstVar* const varp = varrefp->varp();
|
||||
puts("(");
|
||||
if (emitTraceIsScBigUint(nodep)) {
|
||||
puts("(vluint32_t*)");
|
||||
|
|
@ -882,7 +882,7 @@ public:
|
|||
void V3EmitC::emitcImp() {
|
||||
UINFO(2, __FUNCTION__ << ": " << endl);
|
||||
// Make parent module pointers available.
|
||||
EmitCParentModule emitCParentModule;
|
||||
const EmitCParentModule emitCParentModule;
|
||||
|
||||
// Process each module in turn
|
||||
for (const AstNode* nodep = v3Global.rootp()->modulesp(); nodep; nodep = nodep->nextp()) {
|
||||
|
|
@ -903,12 +903,12 @@ void V3EmitC::emitcFiles() {
|
|||
UINFO(2, __FUNCTION__ << ": " << endl);
|
||||
for (AstNodeFile* filep = v3Global.rootp()->filesp(); filep;
|
||||
filep = VN_AS(filep->nextp(), NodeFile)) {
|
||||
AstCFile* cfilep = VN_CAST(filep, CFile);
|
||||
AstCFile* const cfilep = VN_CAST(filep, CFile);
|
||||
if (cfilep && cfilep->tblockp()) {
|
||||
V3OutCFile of(cfilep->name());
|
||||
of.puts("// DESCR"
|
||||
"IPTION: Verilator generated C++\n");
|
||||
EmitCFunc visitor(cfilep->tblockp(), &of, true);
|
||||
const EmitCFunc visitor(cfilep->tblockp(), &of, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ class CMakeEmitter final {
|
|||
|
||||
*of << "# User .cpp files (from .cpp's on Verilator command line)\n";
|
||||
cmake_set_raw(*of, name + "_USER_CLASSES", deslash(cmake_list(v3Global.opt.cppFiles())));
|
||||
if (const V3HierBlockPlan* planp = v3Global.hierPlanp()) {
|
||||
if (const V3HierBlockPlan* const planp = v3Global.hierPlanp()) {
|
||||
*of << "# Verilate hierarchical blocks\n";
|
||||
// Sorted hierarchical blocks in order of leaf-first.
|
||||
const V3HierBlockPlan::HierVector& hierBlocks = planp->hierBlocksSorted();
|
||||
|
|
@ -260,5 +260,5 @@ public:
|
|||
|
||||
void V3EmitCMake::emit() {
|
||||
UINFO(2, __FUNCTION__ << ": " << endl);
|
||||
CMakeEmitter emitter;
|
||||
const CMakeEmitter emitter;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ class EmitCModel final : public EmitCFunc {
|
|||
puts("\n");
|
||||
ofp()->putsPrivate(false); // public:
|
||||
puts("// API METHODS\n");
|
||||
string callEvalEndStep
|
||||
const string callEvalEndStep
|
||||
= (v3Global.needTraceDumper() && !optSystemC()) ? "eval_end_step(); " : "";
|
||||
if (optSystemC()) {
|
||||
ofp()->putsPrivate(true); ///< eval() is invoked by our sensitive() calls.
|
||||
|
|
@ -190,7 +190,7 @@ class EmitCModel final : public EmitCFunc {
|
|||
std::vector<const AstCFunc*> funcps;
|
||||
|
||||
for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (const AstCFunc* funcp = VN_CAST(nodep, CFunc)) {
|
||||
if (const AstCFunc* const funcp = VN_CAST(nodep, CFunc)) {
|
||||
if (!funcp->dpiExportDispatcher()) continue;
|
||||
funcps.push_back(funcp);
|
||||
}
|
||||
|
|
@ -422,7 +422,7 @@ class EmitCModel final : public EmitCFunc {
|
|||
+ "(vlSymsp);\n");
|
||||
|
||||
if (v3Global.opt.threads() == 1) {
|
||||
uint32_t mtaskId = 0;
|
||||
const uint32_t mtaskId = 0;
|
||||
putsDecoration("// MTask " + cvtToStr(mtaskId) + " start\n");
|
||||
puts("VL_DEBUG_IF(VL_DBG_MSGF(\"MTask" + cvtToStr(mtaskId) + " starting\\n\"););\n");
|
||||
puts("Verilated::mtaskId(" + cvtToStr(mtaskId) + ");\n");
|
||||
|
|
|
|||
|
|
@ -38,9 +38,9 @@ class EmitCSyms final : EmitCBaseVisitor {
|
|||
|
||||
// TYPES
|
||||
struct ScopeData {
|
||||
string m_symName;
|
||||
string m_prettyName;
|
||||
int m_timeunit;
|
||||
const string m_symName;
|
||||
const string m_prettyName;
|
||||
const int m_timeunit;
|
||||
string m_type;
|
||||
ScopeData(const string& symName, const string& prettyName, int timeunit,
|
||||
const string& type)
|
||||
|
|
@ -59,13 +59,13 @@ class EmitCSyms final : EmitCBaseVisitor {
|
|||
, m_modp{modp} {}
|
||||
};
|
||||
struct ScopeVarData {
|
||||
string m_scopeName;
|
||||
string m_varBasePretty;
|
||||
const string m_scopeName;
|
||||
const string m_varBasePretty;
|
||||
AstVar* const m_varp;
|
||||
AstNodeModule* const m_modp;
|
||||
const AstNodeModule* const m_modp;
|
||||
AstScope* const m_scopep;
|
||||
ScopeVarData(const string& scopeName, const string& varBasePretty, AstVar* varp,
|
||||
AstNodeModule* modp, AstScope* scopep)
|
||||
const AstNodeModule* modp, AstScope* scopep)
|
||||
: m_scopeName{scopeName}
|
||||
, m_varBasePretty{varBasePretty}
|
||||
, m_varp{varp}
|
||||
|
|
@ -104,7 +104,7 @@ class EmitCSyms final : EmitCBaseVisitor {
|
|||
ScopeNames m_vpiScopeCandidates; // All scopes for VPI
|
||||
ScopeNameHierarchy m_vpiScopeHierarchy; // The actual hierarchy of scopes
|
||||
int m_coverBins = 0; // Coverage bin number
|
||||
bool m_dpiHdrOnly; // Only emit the DPI header
|
||||
const bool m_dpiHdrOnly; // Only emit the DPI header
|
||||
int m_numStmts = 0; // Number of statements output
|
||||
int m_funcNum = 0; // CFunc split function number
|
||||
V3OutCFile* m_ofpBase = nullptr; // Base (not split) C file
|
||||
|
|
@ -197,7 +197,7 @@ class EmitCSyms final : EmitCBaseVisitor {
|
|||
const AstNodeModule* const smodp = itsc->second;
|
||||
for (std::vector<ModVarPair>::iterator it = m_modVars.begin(); it != m_modVars.end();
|
||||
++it) {
|
||||
AstNodeModule* const modp = it->first;
|
||||
const AstNodeModule* const modp = it->first;
|
||||
AstVar* const varp = it->second;
|
||||
if (modp == smodp) {
|
||||
// Need to split the module + var name into the
|
||||
|
|
@ -208,7 +208,7 @@ class EmitCSyms final : EmitCBaseVisitor {
|
|||
string scpName;
|
||||
string varBase;
|
||||
if (whole.substr(0, 10) == "__DOT__TOP") whole.replace(0, 10, "");
|
||||
string::size_type dpos = whole.rfind("__DOT__");
|
||||
const string::size_type dpos = whole.rfind("__DOT__");
|
||||
if (dpos != string::npos) {
|
||||
scpName = whole.substr(0, dpos);
|
||||
varBase = whole.substr(dpos + strlen("__DOT__"));
|
||||
|
|
@ -245,7 +245,7 @@ class EmitCSyms final : EmitCBaseVisitor {
|
|||
if (above.substr(0, 4) == "TOP.") above.replace(0, 4, "");
|
||||
|
||||
while (!above.empty()) {
|
||||
string::size_type pos = above.rfind("__");
|
||||
const string::size_type pos = above.rfind("__");
|
||||
if (pos == string::npos) break;
|
||||
above.resize(pos);
|
||||
if (m_vpiScopeHierarchy.find(above) != m_vpiScopeHierarchy.end()) {
|
||||
|
|
@ -552,7 +552,7 @@ void EmitCSyms::checkSplit(bool usesVfinal) {
|
|||
v3Global.useParallelBuild(true);
|
||||
|
||||
m_numStmts = 0;
|
||||
string filename
|
||||
const string filename
|
||||
= v3Global.opt.makeDir() + "/" + symClassName() + "__" + cvtToStr(++m_funcNum) + ".cpp";
|
||||
AstCFile* const cfilep = newCFile(filename, true /*slow*/, true /*source*/);
|
||||
cfilep->support(true);
|
||||
|
|
@ -637,7 +637,7 @@ void EmitCSyms::emitScopeHier(bool destroy) {
|
|||
void EmitCSyms::emitSymImp() {
|
||||
UINFO(6, __FUNCTION__ << ": " << endl);
|
||||
const string filename = v3Global.opt.makeDir() + "/" + symClassName() + ".cpp";
|
||||
AstCFile* cfilep = newCFile(filename, true /*slow*/, true /*source*/);
|
||||
AstCFile* const cfilep = newCFile(filename, true /*slow*/, true /*source*/);
|
||||
cfilep->support(true);
|
||||
|
||||
if (v3Global.opt.systemC()) {
|
||||
|
|
@ -747,7 +747,7 @@ void EmitCSyms::emitSymImp() {
|
|||
for (const V3GraphVertex* vxp
|
||||
= v3Global.rootp()->execGraphp()->depGraphp()->verticesBeginp();
|
||||
vxp; vxp = vxp->verticesNextp()) {
|
||||
ExecMTask* mtp = dynamic_cast<ExecMTask*>(const_cast<V3GraphVertex*>(vxp));
|
||||
ExecMTask* const mtp = dynamic_cast<ExecMTask*>(const_cast<V3GraphVertex*>(vxp));
|
||||
puts("_vm_profiler.addCounter(" + cvtToStr(mtp->profilerId()) + ", \""
|
||||
+ mtp->hashName() + "\");\n");
|
||||
}
|
||||
|
|
@ -789,8 +789,8 @@ void EmitCSyms::emitSymImp() {
|
|||
|
||||
puts("// Setup each module's pointer back to symbol table (for public functions)\n");
|
||||
for (const auto& i : m_scopes) {
|
||||
AstScope* scopep = i.first;
|
||||
AstNodeModule* modp = i.second;
|
||||
AstScope* const scopep = i.first;
|
||||
AstNodeModule* const modp = i.second;
|
||||
checkSplit(false);
|
||||
// first is used by AstCoverDecl's call to __vlCoverInsert
|
||||
const bool first = !modp->user1();
|
||||
|
|
@ -824,9 +824,9 @@ void EmitCSyms::emitSymImp() {
|
|||
m_ofpBase->puts("// Setup export functions\n");
|
||||
m_ofpBase->puts("for (int __Vfinal=0; __Vfinal<2; __Vfinal++) {\n");
|
||||
for (auto it = m_scopeFuncs.begin(); it != m_scopeFuncs.end(); ++it) {
|
||||
AstScopeName* scopep = it->second.m_scopep;
|
||||
AstCFunc* funcp = it->second.m_cfuncp;
|
||||
AstNodeModule* modp = it->second.m_modp;
|
||||
AstScopeName* const scopep = it->second.m_scopep;
|
||||
AstCFunc* const funcp = it->second.m_cfuncp;
|
||||
AstNodeModule* const modp = it->second.m_modp;
|
||||
if (funcp->dpiExportImpl()) {
|
||||
checkSplit(true);
|
||||
puts(protect("__Vscope_" + scopep->scopeSymName()) + ".exportInsert(__Vfinal, ");
|
||||
|
|
@ -843,14 +843,14 @@ void EmitCSyms::emitSymImp() {
|
|||
// Someday. For now public isn't common.
|
||||
for (auto it = m_scopeVars.begin(); it != m_scopeVars.end(); ++it) {
|
||||
checkSplit(true);
|
||||
AstScope* scopep = it->second.m_scopep;
|
||||
AstVar* varp = it->second.m_varp;
|
||||
AstScope* const scopep = it->second.m_scopep;
|
||||
AstVar* const varp = it->second.m_varp;
|
||||
//
|
||||
int pwidth = 1;
|
||||
int pdim = 0;
|
||||
int udim = 0;
|
||||
string bounds;
|
||||
if (AstBasicDType* basicp = varp->basicp()) {
|
||||
if (AstBasicDType* const basicp = varp->basicp()) {
|
||||
// Range is always first, it's not in "C" order
|
||||
if (basicp->isRanged()) {
|
||||
bounds += " ,";
|
||||
|
|
@ -863,7 +863,7 @@ void EmitCSyms::emitSymImp() {
|
|||
for (AstNodeDType* dtypep = varp->dtypep(); dtypep;) {
|
||||
dtypep
|
||||
= dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
||||
if (const AstNodeArrayDType* adtypep = VN_CAST(dtypep, NodeArrayDType)) {
|
||||
if (const AstNodeArrayDType* const adtypep = VN_CAST(dtypep, NodeArrayDType)) {
|
||||
bounds += " ,";
|
||||
bounds += cvtToStr(adtypep->left());
|
||||
bounds += ",";
|
||||
|
|
@ -965,7 +965,7 @@ void EmitCSyms::emitSymImp() {
|
|||
void EmitCSyms::emitDpiHdr() {
|
||||
UINFO(6, __FUNCTION__ << ": " << endl);
|
||||
const string filename = v3Global.opt.makeDir() + "/" + topClassName() + "__Dpi.h";
|
||||
AstCFile* cfilep = newCFile(filename, false /*slow*/, false /*source*/);
|
||||
AstCFile* const cfilep = newCFile(filename, false /*slow*/, false /*source*/);
|
||||
cfilep->support(true);
|
||||
V3OutCFile hf(filename);
|
||||
m_ofp = &hf;
|
||||
|
|
@ -1019,7 +1019,7 @@ void EmitCSyms::emitDpiHdr() {
|
|||
void EmitCSyms::emitDpiImp() {
|
||||
UINFO(6, __FUNCTION__ << ": " << endl);
|
||||
const string filename = v3Global.opt.makeDir() + "/" + topClassName() + "__Dpi.cpp";
|
||||
AstCFile* cfilep = newCFile(filename, false /*slow*/, true /*source*/);
|
||||
AstCFile* const cfilep = newCFile(filename, false /*slow*/, true /*source*/);
|
||||
cfilep->support(true);
|
||||
V3OutCFile hf(filename);
|
||||
m_ofp = &hf;
|
||||
|
|
@ -1053,7 +1053,7 @@ void EmitCSyms::emitDpiImp() {
|
|||
puts("return " + topClassName() + "::" + nodep->name() + "(");
|
||||
string args;
|
||||
for (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 += ", ";
|
||||
args += portp->name();
|
||||
|
|
|
|||
|
|
@ -407,7 +407,7 @@ public:
|
|||
|
||||
void V3EmitMk::emitmk() {
|
||||
UINFO(2, __FUNCTION__ << ": " << endl);
|
||||
EmitMk emitter;
|
||||
const EmitMk emitter;
|
||||
}
|
||||
|
||||
void V3EmitMk::emitHierVerilation(const V3HierBlockPlan* planp) {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
// MEMBERS
|
||||
bool m_suppressSemi = false;
|
||||
bool m_suppressUnknown = false;
|
||||
const bool m_suppressUnknown = false;
|
||||
AstSenTree* m_sensesp; // Domain for printing one a ALWAYS under a ACTIVE
|
||||
|
||||
// METHODS
|
||||
|
|
@ -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* const unpackp = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||
if (const AstUnpackArrayDType* const unpackp = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||
unpackps.push_back(unpackp);
|
||||
dtypep = unpackp->subDTypep();
|
||||
} else {
|
||||
|
|
@ -752,8 +752,8 @@ public:
|
|||
|
||||
class EmitVPrefixedFormatter final : public V3OutFormatter {
|
||||
std::ostream& m_os;
|
||||
string m_prefix; // What to print at beginning of each line
|
||||
int m_flWidth; // Padding of fileline
|
||||
const string m_prefix; // What to print at beginning of each line
|
||||
const int m_flWidth; // Padding of fileline
|
||||
int m_column; // Rough location; need just zero or non-zero
|
||||
FileLine* m_prefixFl;
|
||||
// METHODS
|
||||
|
|
|
|||
|
|
@ -409,7 +409,7 @@ private:
|
|||
<< nodep->fileline()->xmlDetailedLocation() << " name=\"" << nodep->name() << "\""
|
||||
<< " submodname=\"" << nodep->modName() << "\""
|
||||
<< " hier=\"" << m_hier + nodep->name() << "\"";
|
||||
std::string hier = m_hier;
|
||||
const std::string hier = m_hier;
|
||||
m_hier += nodep->name() + ".";
|
||||
m_hasChildren = false;
|
||||
iterateChildren(nodep->modp());
|
||||
|
|
@ -455,10 +455,10 @@ void V3EmitXml::emitxml() {
|
|||
}
|
||||
{
|
||||
std::stringstream sstr;
|
||||
ModuleFilesXmlVisitor moduleFilesVisitor{v3Global.rootp(), sstr};
|
||||
HierCellsXmlVisitor cellsVisitor{v3Global.rootp(), sstr};
|
||||
const ModuleFilesXmlVisitor moduleFilesVisitor{v3Global.rootp(), sstr};
|
||||
const HierCellsXmlVisitor cellsVisitor{v3Global.rootp(), sstr};
|
||||
of.puts(sstr.str());
|
||||
}
|
||||
EmitXmlFileVisitor visitor{v3Global.rootp(), &of};
|
||||
const EmitXmlFileVisitor visitor{v3Global.rootp(), &of};
|
||||
of.puts("</verilator_xml>\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ v3errorIniter v3errorInit;
|
|||
V3ErrorCode::V3ErrorCode(const char* msgp) {
|
||||
// Return error encoding for given string, or ERROR, which is a bad code
|
||||
for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) {
|
||||
V3ErrorCode code = V3ErrorCode(codei);
|
||||
const V3ErrorCode code = V3ErrorCode(codei);
|
||||
if (0 == VL_STRCASECMP(msgp, code.ascii())) {
|
||||
m_e = code;
|
||||
return;
|
||||
|
|
@ -131,7 +131,7 @@ bool V3Error::isError(V3ErrorCode code, bool supp) {
|
|||
}
|
||||
|
||||
string V3Error::msgPrefix() {
|
||||
V3ErrorCode code = s_errorCode;
|
||||
const V3ErrorCode code = s_errorCode;
|
||||
const bool supp = s_errorSuppressed;
|
||||
if (supp) {
|
||||
return "-arning-suppressed: ";
|
||||
|
|
|
|||
|
|
@ -678,10 +678,10 @@ private:
|
|||
newp = new AstNegate{fl, lhsp};
|
||||
} else {
|
||||
UINFO(8, " REPLICATE " << nodep << endl);
|
||||
const AstConst* constp = VN_AS(nodep->rhsp(), Const);
|
||||
const AstConst* const constp = VN_AS(nodep->rhsp(), Const);
|
||||
UASSERT_OBJ(constp, nodep,
|
||||
"Replication value isn't a constant. Checked earlier!");
|
||||
uint32_t times = constp->toUInt();
|
||||
const uint32_t times = constp->toUInt();
|
||||
if (nodep->isQuad() && !lhsp->isQuad()) { lhsp = new AstCCast{fl, lhsp, nodep}; }
|
||||
newp = lhsp->cloneTree(true);
|
||||
for (unsigned repnum = 1; repnum < times; repnum++) {
|
||||
|
|
|
|||
|
|
@ -66,9 +66,9 @@ class V3FileDependImp final {
|
|||
// TYPES
|
||||
class DependFile final {
|
||||
// A single file
|
||||
bool m_target; // True if write, else read
|
||||
const bool m_target; // True if write, else read
|
||||
bool m_exists = true;
|
||||
string m_filename; // Filename
|
||||
const string m_filename; // Filename
|
||||
struct stat m_stat; // Stat information
|
||||
public:
|
||||
DependFile(const string& filename, bool target)
|
||||
|
|
@ -335,7 +335,7 @@ class VInFilterImp final {
|
|||
#ifdef INFILTER_PIPE
|
||||
pid_t m_pid = 0; // fork() process id
|
||||
#else
|
||||
int m_pid = 0; // fork() process id - always zero as disabled
|
||||
const int m_pid = 0; // fork() process id - always zero as disabled
|
||||
#endif
|
||||
bool m_pidExited = false;
|
||||
int m_pidStatus = 0;
|
||||
|
|
@ -632,7 +632,7 @@ string V3OutFormatter::indentSpaces(int num) {
|
|||
--num;
|
||||
}
|
||||
*cp++ = '\0';
|
||||
string st(str);
|
||||
string st{str}; // No const, move optimization
|
||||
return st;
|
||||
}
|
||||
|
||||
|
|
@ -1053,7 +1053,7 @@ public:
|
|||
private:
|
||||
void trySep(const string& old, string::size_type start, const string& trySep,
|
||||
string::size_type& posr, string& separatorr) {
|
||||
string::size_type trypos = old.find(trySep, start);
|
||||
const string::size_type trypos = old.find(trySep, start);
|
||||
if (trypos != string::npos) {
|
||||
if (posr == string::npos || (posr > trypos)) {
|
||||
posr = trypos;
|
||||
|
|
|
|||
|
|
@ -113,8 +113,8 @@ public:
|
|||
|
||||
private:
|
||||
// MEMBERS
|
||||
string m_filename;
|
||||
Language m_lang; // Indenting Verilog code
|
||||
const string m_filename;
|
||||
const Language m_lang; // Indenting Verilog code
|
||||
int m_blockIndent; // Characters per block indent
|
||||
int m_commaWidth; // Width after which to break at ,'s
|
||||
int m_lineno = 1;
|
||||
|
|
|
|||
|
|
@ -101,9 +101,9 @@ void VFileContent::pushText(const string& text) {
|
|||
// Insert line-by-line
|
||||
string::size_type line_start = 0;
|
||||
while (true) {
|
||||
string::size_type line_end = leftover.find('\n', line_start);
|
||||
const string::size_type line_end = leftover.find('\n', line_start);
|
||||
if (line_end != string::npos) {
|
||||
string oneline(leftover, line_start, line_end - line_start + 1);
|
||||
const string oneline(leftover, line_start, line_end - line_start + 1);
|
||||
m_lines.push_back(oneline); // Keeps newline
|
||||
UINFO(9, "PushStream[ct" << m_id << "+" << (m_lines.size() - 1) << "]: " << oneline);
|
||||
line_start = line_end + 1;
|
||||
|
|
@ -148,7 +148,7 @@ FileLine::FileLine(FileLine::EmptySecret) {
|
|||
|
||||
m_warnOn = 0;
|
||||
for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) {
|
||||
V3ErrorCode code = V3ErrorCode(codei);
|
||||
const V3ErrorCode code = V3ErrorCode(codei);
|
||||
warnOff(code, code.defaultsOff());
|
||||
}
|
||||
}
|
||||
|
|
@ -264,8 +264,8 @@ string FileLine::filebasenameNoExt() const {
|
|||
}
|
||||
|
||||
string FileLine::firstColumnLetters() const {
|
||||
char a = ((firstColumn() / 26) % 26) + 'a';
|
||||
char b = (firstColumn() % 26) + 'a';
|
||||
const char a = ((firstColumn() / 26) % 26) + 'a';
|
||||
const char b = (firstColumn() % 26) + 'a';
|
||||
return string(1, a) + string(1, b);
|
||||
}
|
||||
|
||||
|
|
@ -297,7 +297,7 @@ std::ostream& operator<<(std::ostream& os, FileLine* fileline) {
|
|||
}
|
||||
|
||||
bool FileLine::warnOff(const string& msg, bool flag) {
|
||||
V3ErrorCode code(msg.c_str());
|
||||
const V3ErrorCode code(msg.c_str());
|
||||
if (code < V3ErrorCode::EC_FIRST_WARN) {
|
||||
return false;
|
||||
} else {
|
||||
|
|
@ -308,14 +308,14 @@ bool FileLine::warnOff(const string& msg, bool flag) {
|
|||
|
||||
void FileLine::warnLintOff(bool flag) {
|
||||
for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) {
|
||||
V3ErrorCode code = V3ErrorCode(codei);
|
||||
const V3ErrorCode code = V3ErrorCode(codei);
|
||||
if (code.lintError()) warnOff(code, flag);
|
||||
}
|
||||
}
|
||||
|
||||
void FileLine::warnStyleOff(bool flag) {
|
||||
for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) {
|
||||
V3ErrorCode code = V3ErrorCode(codei);
|
||||
const V3ErrorCode code = V3ErrorCode(codei);
|
||||
if (code.styleError()) warnOff(code, flag);
|
||||
}
|
||||
}
|
||||
|
|
@ -334,7 +334,7 @@ bool FileLine::warnIsOff(V3ErrorCode code) const {
|
|||
void FileLine::modifyStateInherit(const FileLine* fromp) {
|
||||
// Any warnings that are off in "from", become off in "this".
|
||||
for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) {
|
||||
V3ErrorCode code = V3ErrorCode(codei);
|
||||
const V3ErrorCode code = V3ErrorCode(codei);
|
||||
if (fromp->warnIsOff(code)) warnOff(code, true);
|
||||
}
|
||||
}
|
||||
|
|
@ -388,7 +388,7 @@ string FileLine::source() const {
|
|||
string FileLine::prettySource() const {
|
||||
string out = source();
|
||||
// Drop ignore trailing newline
|
||||
string::size_type pos = out.find('\n');
|
||||
const string::size_type pos = out.find('\n');
|
||||
if (pos != string::npos) out = string(out, 0, pos);
|
||||
// Column tracking counts tabs = 1, so match that when print source
|
||||
return VString::spaceUnprintable(out);
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ public:
|
|||
class GateLogicVertex final : public GateEitherVertex {
|
||||
AstNode* const m_nodep;
|
||||
AstActive* const m_activep; // Under what active; nullptr is ok (under cfunc or such)
|
||||
bool m_slow; // In slow block
|
||||
const bool m_slow; // In slow block
|
||||
public:
|
||||
GateLogicVertex(V3Graph* graphp, AstScope* scopep, AstNode* nodep, AstActive* activep,
|
||||
bool slow)
|
||||
|
|
@ -200,7 +200,8 @@ private:
|
|||
AstNode* m_substTreep = nullptr; // What to replace the variable with
|
||||
// STATE
|
||||
bool m_buffersOnly; // Set when we only allow simple buffering, no equations (for clocks)
|
||||
AstNodeVarRef* m_lhsVarRef = nullptr; // VarRef on lhs of assignment (what we're replacing)
|
||||
const AstNodeVarRef* m_lhsVarRef
|
||||
= nullptr; // VarRef on lhs of assignment (what we're replacing)
|
||||
bool m_dedupe; // Set when we use isGateDedupable instead of isGateOptimizable
|
||||
int m_ops = 0; // Operation count
|
||||
|
||||
|
|
@ -315,7 +316,7 @@ private:
|
|||
V3Graph m_graph; // Scoreboard of var usages/dependencies
|
||||
GateLogicVertex* m_logicVertexp = nullptr; // Current statement being tracked, nullptr=ignored
|
||||
AstScope* m_scopep = nullptr; // Current scope being processed
|
||||
AstNodeModule* m_modp = nullptr; // Current module
|
||||
const AstNodeModule* m_modp = nullptr; // Current module
|
||||
AstActive* m_activep = nullptr; // Current active
|
||||
bool m_activeReducible = true; // Is activation block reducible?
|
||||
bool m_inSenItem = false; // Underneath AstSenItem; any varrefs are clocks
|
||||
|
|
@ -568,7 +569,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
|
|||
AstNode* logicp = logicVertexp->nodep();
|
||||
if (logicVertexp->reducible()) {
|
||||
// Can we eliminate?
|
||||
GateOkVisitor okVisitor{logicp, vvertexp->isClock(), false};
|
||||
const GateOkVisitor okVisitor{logicp, vvertexp->isClock(), false};
|
||||
const bool multiInputs = okVisitor.rhsVarRefs().size() > 1;
|
||||
// Was it ok?
|
||||
bool doit = okVisitor.isSimple();
|
||||
|
|
@ -651,7 +652,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
|
|||
}
|
||||
if (removedAllUsages) {
|
||||
// Remove input links
|
||||
while (V3GraphEdge* edgep = vvertexp->inBeginp()) {
|
||||
while (V3GraphEdge* const edgep = vvertexp->inBeginp()) {
|
||||
VL_DO_DANGLING(edgep->unlinkDelete(), edgep);
|
||||
}
|
||||
// Clone tree so we remember it for tracing, and keep the pointer
|
||||
|
|
@ -825,7 +826,7 @@ class GateElimVisitor final : public GateBaseVisitor {
|
|||
private:
|
||||
// NODE STATE
|
||||
// STATE
|
||||
AstVarScope* m_elimVarScp; // Variable being eliminated
|
||||
const AstVarScope* m_elimVarScp; // Variable being eliminated
|
||||
AstNode* m_replaceTreep; // What to replace the variable with
|
||||
bool m_didReplace; // Did we do any replacements
|
||||
GateDedupeVarVisitor* m_varVisp; // Callback to keep hash up to date
|
||||
|
|
@ -881,7 +882,7 @@ public:
|
|||
|
||||
void GateVisitor::optimizeElimVar(AstVarScope* varscp, AstNode* substp, AstNode* consumerp) {
|
||||
if (debug() >= 5) consumerp->dumpTree(cout, " elimUsePre: ");
|
||||
GateElimVisitor elimVisitor{consumerp, varscp, substp, nullptr};
|
||||
const GateElimVisitor elimVisitor{consumerp, varscp, substp, nullptr};
|
||||
if (elimVisitor.didReplace()) {
|
||||
if (debug() >= 9) consumerp->dumpTree(cout, " elimUseCns: ");
|
||||
// Caution: Can't let V3Const change our handle to consumerp, such as by
|
||||
|
|
@ -978,7 +979,8 @@ public:
|
|||
&& node1p->user2p()->type() == node2p->user2p()->type();
|
||||
}
|
||||
|
||||
AstNodeAssign* hashAndFindDupe(AstNodeAssign* assignp, AstNode* extra1p, AstNode* extra2p) {
|
||||
const 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* const rhsp = assignp->rhsp();
|
||||
|
|
@ -1094,7 +1096,7 @@ public:
|
|||
m_dedupable = true;
|
||||
iterate(nodep);
|
||||
if (m_dedupable && m_assignp) {
|
||||
AstNode* const lhsp = m_assignp->lhsp();
|
||||
const AstNode* const lhsp = m_assignp->lhsp();
|
||||
// Possible todo, handle more complex lhs expressions
|
||||
if (const AstNodeVarRef* const lhsVarRefp = VN_CAST(lhsp, NodeVarRef)) {
|
||||
UASSERT_OBJ(lhsVarRefp->varScopep() == consumerVarScopep, consumerVarScopep,
|
||||
|
|
@ -1141,12 +1143,12 @@ private:
|
|||
AstNodeVarRef* const dupVarRefp = static_cast<AstNodeVarRef*>(
|
||||
vvertexp->iterateInEdges(*this, VNUser(vvertexp)).toNodep());
|
||||
if (dupVarRefp) { // visit(GateLogicVertex*...) returned match
|
||||
V3GraphEdge* edgep = vvertexp->inBeginp();
|
||||
const V3GraphEdge* edgep = vvertexp->inBeginp();
|
||||
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};
|
||||
const GateOkVisitor okVisitor{lvertexp->nodep(), false, true};
|
||||
if (okVisitor.isSimple()) {
|
||||
const AstVarScope* const dupVarScopep = dupVarRefp->varScopep();
|
||||
GateVarVertex* const dupVvertexp
|
||||
|
|
@ -1169,15 +1171,15 @@ private:
|
|||
if (lvertexp == consumeVertexp) {
|
||||
UINFO(9, "skipping as self-recirculates\n");
|
||||
} else {
|
||||
GateElimVisitor elimVisitor(consumerp, vvertexp->varScp(), dupVarRefp,
|
||||
&m_varVisitor);
|
||||
const GateElimVisitor elimVisitor(consumerp, vvertexp->varScp(),
|
||||
dupVarRefp, &m_varVisitor);
|
||||
}
|
||||
outedgep = outedgep->relinkFromp(dupVvertexp);
|
||||
}
|
||||
// Propagate attributes
|
||||
dupVvertexp->propagateAttrClocksFrom(vvertexp);
|
||||
// Remove inputs links
|
||||
while (V3GraphEdge* inedgep = vvertexp->inBeginp()) {
|
||||
while (V3GraphEdge* const inedgep = vvertexp->inBeginp()) {
|
||||
VL_DO_DANGLING(inedgep->unlinkDelete(), inedgep);
|
||||
}
|
||||
// replaceAssigns() does the deleteTree on lvertexNodep in a later step
|
||||
|
|
@ -1252,7 +1254,7 @@ class GateMergeAssignsGraphVisitor final : public GateGraphBaseVisitor {
|
|||
private:
|
||||
// NODE STATE
|
||||
AstNodeAssign* m_assignp = nullptr;
|
||||
AstActive* m_activep = nullptr;
|
||||
const AstActive* m_activep = nullptr;
|
||||
GateLogicVertex* m_logicvp = nullptr;
|
||||
VDouble0 m_numMergedAssigns; // Statistic tracking
|
||||
|
||||
|
|
@ -1382,7 +1384,7 @@ void GateVisitor::mergeAssigns() {
|
|||
class GateConcatVisitor final : public GateBaseVisitor {
|
||||
private:
|
||||
// STATE
|
||||
AstVarScope* m_vscp = nullptr; // Varscope we're trying to find
|
||||
const AstVarScope* m_vscp = nullptr; // Varscope we're trying to find
|
||||
int m_offset = 0; // Current offset of varscope
|
||||
int m_found_offset = 0; // Found offset of varscope
|
||||
bool m_found = false; // Offset found
|
||||
|
|
@ -1432,7 +1434,7 @@ public:
|
|||
|
||||
class GateClkDecompState final {
|
||||
public:
|
||||
int m_offset;
|
||||
const int m_offset;
|
||||
AstVarScope* const m_last_vsp;
|
||||
GateClkDecompState(int offset, AstVarScope* vsp)
|
||||
: m_offset{offset}
|
||||
|
|
@ -1460,7 +1462,7 @@ private:
|
|||
m_seen_clk_vectors++;
|
||||
m_total_seen_clk_vectors++;
|
||||
}
|
||||
GateClkDecompState* const currState = reinterpret_cast<GateClkDecompState*>(vu.c());
|
||||
const 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;
|
||||
|
|
@ -1469,13 +1471,13 @@ private:
|
|||
}
|
||||
|
||||
virtual VNUser visit(GateLogicVertex* lvertexp, VNUser vu) override {
|
||||
GateClkDecompState* const currState = reinterpret_cast<GateClkDecompState*>(vu.c());
|
||||
const GateClkDecompState* const currState = reinterpret_cast<GateClkDecompState*>(vu.c());
|
||||
int clk_offset = currState->m_offset;
|
||||
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* const rselp = VN_CAST(assignp->rhsp(), Sel)) {
|
||||
if (const 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() << " : "
|
||||
|
|
@ -1487,7 +1489,7 @@ private:
|
|||
} else {
|
||||
return VNUser(0);
|
||||
}
|
||||
} else if (AstConcat* catp = VN_CAST(assignp->rhsp(), Concat)) {
|
||||
} else if (AstConcat* const catp = VN_CAST(assignp->rhsp(), Concat)) {
|
||||
UINFO(9, "CLK DECOMP Concat searching - " << assignp->lhsp() << endl);
|
||||
int concat_offset;
|
||||
if (!m_concat_visitor.concatOffset(catp, currState->m_last_vsp,
|
||||
|
|
@ -1507,7 +1509,7 @@ private:
|
|||
} else {
|
||||
return VNUser(0);
|
||||
}
|
||||
} else if (const AstVarRef* vrp = VN_CAST(assignp->lhsp(), VarRef)) {
|
||||
} else if (const AstVarRef* const vrp = VN_CAST(assignp->lhsp(), VarRef)) {
|
||||
if (vrp->dtypep()->width() == 1 && m_seen_clk_vectors) {
|
||||
if (clk_offset != 0) {
|
||||
UINFO(9, "Should only make it here with clk_offset = 0" << endl);
|
||||
|
|
@ -1517,7 +1519,7 @@ private:
|
|||
UINFO(9, " to - " << m_clk_vsp << endl);
|
||||
AstNode* const rhsp = assignp->rhsp();
|
||||
rhsp->replaceWith(new AstVarRef(rhsp->fileline(), m_clk_vsp, VAccess::READ));
|
||||
while (V3GraphEdge* edgep = lvertexp->inBeginp()) {
|
||||
while (V3GraphEdge* const edgep = lvertexp->inBeginp()) {
|
||||
VL_DO_DANGLING(edgep->unlinkDelete(), edgep);
|
||||
}
|
||||
new V3GraphEdge(m_graphp, m_clk_vvertexp, lvertexp, 1);
|
||||
|
|
@ -1556,7 +1558,7 @@ void GateVisitor::decomposeClkVectors() {
|
|||
GateClkDecompGraphVisitor decomposer{&m_graph};
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (GateVarVertex* const vertp = dynamic_cast<GateVarVertex*>(itp)) {
|
||||
AstVarScope* const vsp = vertp->varScp();
|
||||
const 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);
|
||||
|
|
@ -1601,7 +1603,7 @@ public:
|
|||
void V3Gate::gateAll(AstNetlist* nodep) {
|
||||
UINFO(2, __FUNCTION__ << ": " << endl);
|
||||
{
|
||||
GateVisitor visitor{nodep};
|
||||
const GateVisitor visitor{nodep};
|
||||
GateDeassignVisitor{nodep};
|
||||
} // Destruct before checking
|
||||
V3Global::dumpCheckGlobalTree("gate", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ private:
|
|||
const AstUser3InUse m_inuser3;
|
||||
|
||||
// STATE
|
||||
AstActive* m_activep = nullptr; // Inside activate statement
|
||||
const AstActive* m_activep = nullptr; // Inside activate statement
|
||||
AstNodeModule* const m_topModp; // Top module
|
||||
AstScope* const m_scopetopp = v3Global.rootp()->topScopep()->scopep(); // The top AstScope
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ private:
|
|||
UASSERT_OBJ(vscp != v3Global.rootp()->dpiExportTriggerp(), vscp,
|
||||
"DPI export trigger should not need __VinpClk");
|
||||
AstVar* const varp = vscp->varp();
|
||||
string newvarname
|
||||
const string newvarname
|
||||
= "__VinpClk__" + vscp->scopep()->nameDotless() + "__" + varp->name();
|
||||
// Create: VARREF(inpclk)
|
||||
// ...
|
||||
|
|
@ -145,8 +145,8 @@ private:
|
|||
|
||||
// STATE
|
||||
bool m_tracingCall = false; // Iterating into a call to a cfunc
|
||||
AstActive* m_activep = nullptr; // Inside activate statement
|
||||
AstNodeAssign* m_assignp = nullptr; // Inside assigndly statement
|
||||
const AstActive* m_activep = nullptr; // Inside activate statement
|
||||
const AstNodeAssign* m_assignp = nullptr; // Inside assigndly statement
|
||||
AstNodeModule* m_topModp = nullptr; // Top module
|
||||
|
||||
// VISITORS
|
||||
|
|
|
|||
|
|
@ -327,7 +327,7 @@ void V3Graph::dumpDotFile(const string& filename, bool colorAsSubgraph) const {
|
|||
// List of all possible subgraphs
|
||||
std::multimap<std::string, V3GraphVertex*> subgraphs;
|
||||
for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp = vertexp->verticesNextp()) {
|
||||
string vertexSubgraph
|
||||
const string vertexSubgraph
|
||||
= (colorAsSubgraph && vertexp->color()) ? cvtToStr(vertexp->color()) : "";
|
||||
subgraphs.emplace(vertexSubgraph, vertexp);
|
||||
}
|
||||
|
|
@ -341,7 +341,7 @@ void V3Graph::dumpDotFile(const string& filename, bool colorAsSubgraph) const {
|
|||
string subgr;
|
||||
for (auto it = subgraphs.cbegin(); it != subgraphs.cend(); ++it) {
|
||||
const string vertexSubgraph = it->first;
|
||||
V3GraphVertex* vertexp = it->second;
|
||||
const V3GraphVertex* vertexp = it->second;
|
||||
numMap[vertexp] = n;
|
||||
if (subgr != vertexSubgraph) {
|
||||
if (subgr != "") *logp << "\t};\n";
|
||||
|
|
|
|||
|
|
@ -102,7 +102,8 @@ private:
|
|||
V3Graph m_breakGraph; // Graph with only breakable edges represented
|
||||
V3List<GraphAcycVertex*> m_work; // List of vertices with optimization work left
|
||||
std::vector<OrigEdgeList*> m_origEdgeDelp; // List of deletions to do when done
|
||||
V3EdgeFuncP m_origEdgeFuncp; // Function that says we follow this edge (in original graph)
|
||||
const V3EdgeFuncP
|
||||
m_origEdgeFuncp; // Function that says we follow this edge (in original graph)
|
||||
uint32_t m_placeStep = 0; // Number that user() must be equal to to indicate processing
|
||||
|
||||
static int debug() { return V3Graph::debug(); }
|
||||
|
|
@ -223,7 +224,7 @@ void GraphAcyc::buildGraphIterate(V3GraphVertex* overtexp, GraphAcycVertex* aver
|
|||
// Make new edges
|
||||
for (V3GraphEdge* edgep = overtexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||
if (origFollowEdge(edgep)) { // not cut
|
||||
V3GraphVertex* toVertexp = edgep->top();
|
||||
const V3GraphVertex* toVertexp = edgep->top();
|
||||
if (toVertexp->color()) {
|
||||
GraphAcycVertex* const toAVertexp
|
||||
= static_cast<GraphAcycVertex*>(toVertexp->userp());
|
||||
|
|
@ -282,13 +283,13 @@ void GraphAcyc::simplifyNone(GraphAcycVertex* avertexp) {
|
|||
UINFO(9, " SimplifyNoneRemove " << avertexp << endl);
|
||||
avertexp->setDelete(); // Mark so we won't delete it twice
|
||||
// Remove edges
|
||||
while (V3GraphEdge* edgep = avertexp->outBeginp()) {
|
||||
while (V3GraphEdge* const edgep = avertexp->outBeginp()) {
|
||||
V3GraphVertex* otherVertexp = edgep->top();
|
||||
// UINFO(9, " out " << otherVertexp << endl);
|
||||
VL_DO_DANGLING(edgep->unlinkDelete(), edgep);
|
||||
workPush(otherVertexp);
|
||||
}
|
||||
while (V3GraphEdge* edgep = avertexp->inBeginp()) {
|
||||
while (V3GraphEdge* const edgep = avertexp->inBeginp()) {
|
||||
V3GraphVertex* otherVertexp = edgep->fromp();
|
||||
// UINFO(9, " in " << otherVertexp << endl);
|
||||
VL_DO_DANGLING(edgep->unlinkDelete(), edgep);
|
||||
|
|
@ -484,7 +485,7 @@ void GraphAcyc::placeTryEdge(V3GraphEdge* edgep) {
|
|||
// Vertex::m_user begin: number indicates this edge was completed
|
||||
// Try to assign ranks, presuming this edge is in place
|
||||
// If we come across user()==placestep, we've detected a loop and must back out
|
||||
bool loop
|
||||
const bool loop
|
||||
= placeIterate(static_cast<GraphAcycVertex*>(edgep->top()), edgep->fromp()->rank() + 1);
|
||||
if (!loop) {
|
||||
// No loop, we can keep it as uncutable
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
// Algorithms - weakly connected components
|
||||
|
||||
class GraphRemoveRedundant final : GraphAlg<> {
|
||||
bool m_sumWeights; ///< Sum, rather then maximize weights
|
||||
const bool m_sumWeights; ///< Sum, rather then maximize weights
|
||||
private:
|
||||
void main() {
|
||||
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp;
|
||||
|
|
@ -213,7 +213,7 @@ private:
|
|||
}
|
||||
|
||||
void vertexIterate(V3GraphVertex* vertexp) {
|
||||
uint32_t thisDfsNum = m_currentDfs++;
|
||||
const uint32_t thisDfsNum = m_currentDfs++;
|
||||
vertexp->user(thisDfsNum);
|
||||
vertexp->color(0);
|
||||
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@
|
|||
template <class T_Graph = V3Graph> // Or sometimes const V3Graph
|
||||
class GraphAlg VL_NOT_FINAL {
|
||||
protected:
|
||||
T_Graph* m_graphp; // Graph we're operating upon
|
||||
V3EdgeFuncP m_edgeFuncp; // Function that says we follow this edge
|
||||
T_Graph* const m_graphp; // Graph we're operating upon
|
||||
const V3EdgeFuncP m_edgeFuncp; // Function that says we follow this edge
|
||||
// CONSTRUCTORS
|
||||
GraphAlg(T_Graph* graphp, V3EdgeFuncP edgeFuncp)
|
||||
: m_graphp{graphp}
|
||||
|
|
|
|||
|
|
@ -74,12 +74,12 @@ GraphPathChecker::~GraphPathChecker() {
|
|||
void GraphPathChecker::initHalfCriticalPaths(GraphWay way, bool checkOnly) {
|
||||
GraphStreamUnordered order(m_graphp, way);
|
||||
const GraphWay rev = way.invert();
|
||||
while (const V3GraphVertex* vertexp = order.nextp()) {
|
||||
while (const V3GraphVertex* const vertexp = order.nextp()) {
|
||||
unsigned critPathCost = 0;
|
||||
for (V3GraphEdge* edgep = vertexp->beginp(rev); edgep; edgep = edgep->nextp(rev)) {
|
||||
if (!m_edgeFuncp(edgep)) continue;
|
||||
|
||||
V3GraphVertex* wrelativep = edgep->furtherp(rev);
|
||||
const V3GraphVertex* wrelativep = edgep->furtherp(rev);
|
||||
const GraphPCNode* const wrelUserp = static_cast<GraphPCNode*>(wrelativep->userp());
|
||||
critPathCost = std::max(critPathCost, wrelUserp->m_cp[way] + 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ private:
|
|||
public:
|
||||
// MEMBERS
|
||||
const V3GraphVertex* m_vxp; // [mtask] Vertex
|
||||
uint32_t m_pos; // Sort position
|
||||
const uint32_t m_pos; // Sort position
|
||||
uint32_t m_numBlockingEdges; // Number of blocking edges
|
||||
// CONSTRUCTORS
|
||||
VxHolder(const V3GraphVertex* vxp, uint32_t pos, uint32_t numBlockingEdges)
|
||||
|
|
@ -65,7 +65,7 @@ private:
|
|||
class VxHolderCmp final {
|
||||
public:
|
||||
// MEMBERS
|
||||
T_Compare m_lessThan; // Sorting functor
|
||||
const T_Compare m_lessThan; // Sorting functor
|
||||
// CONSTRUCTORS
|
||||
explicit VxHolderCmp(const T_Compare& lessThan)
|
||||
: m_lessThan{lessThan} {}
|
||||
|
|
@ -87,7 +87,7 @@ private:
|
|||
ReadyVertices m_readyVertices; // List of ready vertices
|
||||
std::map<const V3GraphVertex*, VxHolder> m_waitingVertices; // List of waiting vertices
|
||||
typename ReadyVertices::iterator m_last; // Previously returned element
|
||||
GraphWay m_way; // FORWARD or REVERSE order of traversal
|
||||
const GraphWay m_way; // FORWARD or REVERSE order of traversal
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
@ -106,26 +106,26 @@ public:
|
|||
// Every vertex initially is waiting, or ready.
|
||||
if (way == GraphWay::FORWARD) {
|
||||
if (vxp->inEmpty()) {
|
||||
VxHolder newVx(vxp, pos++, 0);
|
||||
const VxHolder newVx(vxp, pos++, 0);
|
||||
m_readyVertices.insert(newVx);
|
||||
} else {
|
||||
uint32_t depCount = 0;
|
||||
for (V3GraphEdge* depp = vxp->inBeginp(); depp; depp = depp->inNextp()) {
|
||||
++depCount;
|
||||
}
|
||||
VxHolder newVx(vxp, pos++, depCount);
|
||||
const VxHolder newVx(vxp, pos++, depCount);
|
||||
m_waitingVertices.emplace(vxp, newVx);
|
||||
}
|
||||
} else { // REVERSE
|
||||
if (vxp->outEmpty()) {
|
||||
VxHolder newVx(vxp, pos++, 0);
|
||||
const VxHolder newVx(vxp, pos++, 0);
|
||||
m_readyVertices.insert(newVx);
|
||||
} else {
|
||||
uint32_t depCount = 0;
|
||||
for (V3GraphEdge* depp = vxp->outBeginp(); depp; depp = depp->outNextp()) {
|
||||
++depCount;
|
||||
}
|
||||
VxHolder newVx(vxp, pos++, depCount);
|
||||
const VxHolder newVx(vxp, pos++, depCount);
|
||||
m_waitingVertices.emplace(vxp, newVx);
|
||||
}
|
||||
}
|
||||
|
|
@ -194,7 +194,7 @@ private:
|
|||
void unblockDeps(const V3GraphVertex* vertexp) {
|
||||
if (m_way == GraphWay::FORWARD) {
|
||||
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||
V3GraphVertex* const toVertexp = edgep->top();
|
||||
const V3GraphVertex* const toVertexp = edgep->top();
|
||||
|
||||
const auto it = m_waitingVertices.find(toVertexp);
|
||||
UASSERT_OBJ(it != m_waitingVertices.end(), toVertexp,
|
||||
|
|
@ -206,7 +206,7 @@ private:
|
|||
}
|
||||
} else {
|
||||
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
V3GraphVertex* const fromVertexp = edgep->fromp();
|
||||
const V3GraphVertex* const fromVertexp = edgep->fromp();
|
||||
|
||||
const auto it = m_waitingVertices.find(fromVertexp);
|
||||
UASSERT_OBJ(it != m_waitingVertices.end(), fromVertexp,
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ public:
|
|||
// Vertices and nodes
|
||||
|
||||
class V3GraphTestVertex VL_NOT_FINAL : public V3GraphVertex {
|
||||
string m_name;
|
||||
const string m_name;
|
||||
|
||||
public:
|
||||
V3GraphTestVertex(V3Graph* graphp, const string& name)
|
||||
|
|
|
|||
|
|
@ -496,6 +496,6 @@ V3Hash V3Hasher::operator()(AstNode* nodep) const {
|
|||
}
|
||||
|
||||
V3Hash V3Hasher::uncachedHash(const AstNode* nodep) {
|
||||
HasherVisitor visitor{nodep};
|
||||
const HasherVisitor visitor{nodep};
|
||||
return visitor.finalHash();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ string V3HierBlock::vFileIfNecessary() const {
|
|||
}
|
||||
|
||||
void V3HierBlock::writeCommandArgsFile(bool forCMake) const {
|
||||
std::unique_ptr<std::ofstream> of{V3File::new_ofstream(commandArgsFileName(forCMake))};
|
||||
const std::unique_ptr<std::ofstream> of{V3File::new_ofstream(commandArgsFileName(forCMake))};
|
||||
*of << "--cc\n";
|
||||
|
||||
if (!forCMake) {
|
||||
|
|
@ -279,7 +279,7 @@ class HierBlockUsageCollectVisitor final : public AstNVisitor {
|
|||
virtual void visit(AstCell* nodep) override {
|
||||
// Visit used module here to know that the module is hier_block or not.
|
||||
// This visitor behaves almost depth first search
|
||||
if (AstModule* modp = VN_CAST(nodep->modp(), Module)) {
|
||||
if (AstModule* const modp = VN_CAST(nodep->modp(), Module)) {
|
||||
iterate(modp);
|
||||
m_referred.insert(modp);
|
||||
}
|
||||
|
|
@ -336,7 +336,7 @@ void V3HierBlockPlan::createPlan(AstNetlist* nodep) {
|
|||
// When processing a hierarchical block, no need to create a plan anymore.
|
||||
if (v3Global.opt.hierChild()) return;
|
||||
|
||||
AstNodeModule* modp = nodep->topModulep();
|
||||
AstNodeModule* const modp = nodep->topModulep();
|
||||
if (modp->hierBlock()) {
|
||||
modp->v3warn(HIERBLOCK,
|
||||
"Top module illegally marked hierarchical block, ignoring marking\n"
|
||||
|
|
@ -400,7 +400,8 @@ void V3HierBlockPlan::writeCommandArgsFiles(bool forCMake) const {
|
|||
it->second->writeCommandArgsFile(forCMake);
|
||||
}
|
||||
// For the top module
|
||||
std::unique_ptr<std::ofstream> of{V3File::new_ofstream(topCommandArgsFileName(forCMake))};
|
||||
const std::unique_ptr<std::ofstream> of{
|
||||
V3File::new_ofstream(topCommandArgsFileName(forCMake))};
|
||||
if (!forCMake) {
|
||||
// Load wrappers first not to be overwritten by the original HDL
|
||||
for (const_iterator it = begin(); it != end(); ++it) {
|
||||
|
|
|
|||
|
|
@ -49,13 +49,13 @@ private:
|
|||
using StrGParams = std::vector<std::pair<std::string, std::string>>;
|
||||
|
||||
// MEMBERS
|
||||
const AstNodeModule* m_modp; // Hierarchical block module
|
||||
const AstNodeModule* const m_modp; // Hierarchical block module
|
||||
// Hierarchical blocks that directly or indirectly instantiate this block
|
||||
HierBlockSet m_parents;
|
||||
// Hierarchical blocks that this block directly or indirectly instantiates
|
||||
HierBlockSet m_children;
|
||||
// Parameters that are overridden by #(.param(value)) syntax.
|
||||
GParams m_gparams;
|
||||
const GParams m_gparams;
|
||||
|
||||
// METHODS
|
||||
VL_UNCOPYABLE(V3HierBlock);
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ private:
|
|||
// STATE
|
||||
std::unordered_set<std::string> m_renamedInterfaces; // Name of renamed interface variables
|
||||
AstNodeModule* const m_modp; // Current module
|
||||
AstCell* const m_cellp; // Cell being cloned
|
||||
const AstCell* const m_cellp; // Cell being cloned
|
||||
|
||||
// METHODS
|
||||
VL_DEBUG_FUNC; // Declare debug()
|
||||
|
|
@ -423,7 +423,7 @@ private:
|
|||
break;
|
||||
}
|
||||
// If foo.bar, and foo is an interface, then need to search again for foo
|
||||
string::size_type pos = tryname.rfind('.');
|
||||
const string::size_type pos = tryname.rfind('.');
|
||||
if (pos == string::npos || pos == 0) {
|
||||
break;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ class InstDeVisitor final : public AstNVisitor {
|
|||
private:
|
||||
// STATE
|
||||
// Range for arrayed instantiations, nullptr for normal instantiations
|
||||
AstRange* m_cellRangep = nullptr;
|
||||
const AstRange* m_cellRangep = nullptr;
|
||||
int m_instSelNum = 0; // Current instantiation count 0..N-1
|
||||
InstDeModVarVisitor m_deModVars; // State of variables for current cell module
|
||||
|
||||
|
|
@ -322,8 +322,10 @@ private:
|
|||
UINFO(4, " PIN " << nodep << endl);
|
||||
const int pinwidth = nodep->modVarp()->width();
|
||||
const int expwidth = nodep->exprp()->width();
|
||||
std::pair<uint32_t, uint32_t> pinDim = nodep->modVarp()->dtypep()->dimensions(false);
|
||||
std::pair<uint32_t, uint32_t> expDim = nodep->exprp()->dtypep()->dimensions(false);
|
||||
const std::pair<uint32_t, uint32_t> pinDim
|
||||
= nodep->modVarp()->dtypep()->dimensions(false);
|
||||
const std::pair<uint32_t, uint32_t> expDim
|
||||
= nodep->exprp()->dtypep()->dimensions(false);
|
||||
UINFO(4, " PINVAR " << nodep->modVarp() << endl);
|
||||
UINFO(4, " EXP " << nodep->exprp() << endl);
|
||||
UINFO(4, " pinwidth ew=" << expwidth << " pw=" << pinwidth << " ed=" << expDim.first
|
||||
|
|
@ -331,7 +333,7 @@ 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* const rangep
|
||||
const AstRange* const rangep
|
||||
= VN_AS(nodep->exprp()->dtypep(), UnpackArrayDType)->rangep();
|
||||
const int arraySelNum = rangep->littleEndian()
|
||||
? (rangep->elementsConst() - 1 - m_instSelNum)
|
||||
|
|
@ -366,8 +368,8 @@ private:
|
|||
nodep->v3fatalSrc("Width mismatch; V3Width should have errored out.");
|
||||
}
|
||||
} // end expanding ranged cell
|
||||
else if (AstArraySel* arrselp = VN_CAST(nodep->exprp(), ArraySel)) {
|
||||
if (AstUnpackArrayDType* const arrp
|
||||
else if (AstArraySel* const arrselp = VN_CAST(nodep->exprp(), ArraySel)) {
|
||||
if (const 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
|
||||
|
|
@ -382,7 +384,7 @@ private:
|
|||
const string index = AstNode::encodeNumber(constp->toSInt());
|
||||
if (VN_IS(arrselp->lhsp(), SliceSel))
|
||||
arrselp->lhsp()->v3error("Unsupported: interface slices");
|
||||
AstVarRef* const varrefp = VN_CAST(arrselp->lhsp(), VarRef);
|
||||
const AstVarRef* const varrefp = VN_CAST(arrselp->lhsp(), VarRef);
|
||||
UASSERT_OBJ(varrefp, arrselp, "No interface varref under array");
|
||||
AstVarXRef* const newp = new AstVarXRef(
|
||||
nodep->fileline(), varrefp->name() + "__BRA__" + index + "__KET__", "",
|
||||
|
|
@ -394,7 +396,8 @@ private:
|
|||
}
|
||||
} else {
|
||||
AstVar* const pinVarp = nodep->modVarp();
|
||||
AstUnpackArrayDType* const pinArrp = VN_CAST(pinVarp->dtypep(), UnpackArrayDType);
|
||||
const 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;
|
||||
|
|
@ -402,7 +405,7 @@ private:
|
|||
// Clone the var referenced by the pin, and clone each var referenced by the varref
|
||||
// Clone pin varp:
|
||||
for (int in = 0; in < pinArrp->elementsConst(); ++in) { // 0 = leftmost
|
||||
int i = pinArrp->left() + in * pinArrp->declRange().leftToRightInc();
|
||||
const int i = pinArrp->left() + in * pinArrp->declRange().leftToRightInc();
|
||||
const string varNewName = pinVarp->name() + "__BRA__" + cvtToStr(i) + "__KET__";
|
||||
AstVar* varNewp = nullptr;
|
||||
|
||||
|
|
@ -437,17 +440,18 @@ private:
|
|||
// And replace exprp with a new varxref
|
||||
const AstVarRef* varrefp = VN_CAST(newp->exprp(), VarRef); // Maybe null
|
||||
int expr_i = i;
|
||||
if (AstSliceSel* const slicep = VN_CAST(newp->exprp(), SliceSel)) {
|
||||
if (const 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
|
||||
const int slice_index
|
||||
= slicep->declRange().left() + in * slicep->declRange().leftToRightInc();
|
||||
auto* const exprArrp = VN_AS(varrefp->dtypep(), UnpackArrayDType);
|
||||
const 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) {
|
||||
newp->exprp()->v3error("Unexpected connection to arrayed port");
|
||||
} else if (auto* exprArrp = VN_CAST(varrefp->dtypep(), UnpackArrayDType)) {
|
||||
} else if (const auto* const exprArrp
|
||||
= VN_CAST(varrefp->dtypep(), UnpackArrayDType)) {
|
||||
expr_i = exprArrp->left() + in * exprArrp->declRange().leftToRightInc();
|
||||
}
|
||||
|
||||
|
|
@ -526,10 +530,11 @@ public:
|
|||
return 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;
|
||||
const AstVarRef* const connectRefp = VN_CAST(pinp->exprp(), VarRef);
|
||||
const AstVarXRef* const connectXRefp = VN_CAST(pinp->exprp(), VarXRef);
|
||||
const AstBasicDType* const pinBasicp
|
||||
= VN_CAST(pinVarp->dtypep(), BasicDType); // Maybe nullptr
|
||||
const AstBasicDType* connBasicp = nullptr;
|
||||
AstAssignW* assignp = nullptr;
|
||||
if (connectRefp) connBasicp = VN_CAST(connectRefp->varp()->dtypep(), BasicDType);
|
||||
//
|
||||
|
|
@ -554,7 +559,7 @@ public:
|
|||
// if (1 || debug() >= 9) pinp->dumpTree(cout, "-in_pin:");
|
||||
V3Inst::checkOutputShort(pinp);
|
||||
AstNode* const pinexprp = pinp->exprp()->unlinkFrBack();
|
||||
string newvarname
|
||||
const string newvarname
|
||||
= (string(pinVarp->isWritable() ? "__Vcellout" : "__Vcellinp")
|
||||
// Prevent name conflict if both tri & non-tri add signals
|
||||
+ (forTristate ? "t" : "") + "__" + cellp->name() + "__" + pinp->name());
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ private:
|
|||
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
|
||||
std::ostream* m_osp; // Dump file
|
||||
const bool m_assertNoDups; // Check for duplicates
|
||||
const std::ostream* m_osp; // Dump file
|
||||
|
||||
// TYPES
|
||||
// Little class to cleanly call startVisitBase/endVisitBase
|
||||
|
|
@ -102,7 +102,7 @@ private:
|
|||
// Save the count, and add it back in during ~VisitBase This allows
|
||||
// debug prints to show local cost of each subtree, so we can see a
|
||||
// hierarchical view of the cost when in debug mode.
|
||||
uint32_t savedCount = m_instrCount;
|
||||
const uint32_t savedCount = m_instrCount;
|
||||
m_instrCount = nodep->instrCount();
|
||||
return savedCount;
|
||||
}
|
||||
|
|
@ -124,7 +124,7 @@ private:
|
|||
//
|
||||
// Hence, exclude the child of the AstWordSel from the computation,
|
||||
// whose cost scales with the size of the entire (maybe large) vector.
|
||||
VisitBase vb(this, nodep);
|
||||
const VisitBase vb{this, nodep};
|
||||
iterateAndNextNull(nodep->bitp());
|
||||
}
|
||||
virtual void visit(AstSel* nodep) override {
|
||||
|
|
@ -132,7 +132,7 @@ private:
|
|||
// is not expensive. Count the cost of the AstSel itself (scales with
|
||||
// its width) and the cost of the lsbp() and widthp() nodes, but not
|
||||
// the fromp() node which could be disproportionately large.
|
||||
VisitBase vb(this, nodep);
|
||||
const VisitBase vb{this, nodep};
|
||||
iterateAndNextNull(nodep->lsbp());
|
||||
iterateAndNextNull(nodep->widthp());
|
||||
}
|
||||
|
|
@ -163,9 +163,9 @@ private:
|
|||
markCost(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeIf* nodep) override {
|
||||
VisitBase vb(this, nodep);
|
||||
const VisitBase vb{this, nodep};
|
||||
iterateAndNextNull(nodep->condp());
|
||||
uint32_t savedCount = m_instrCount;
|
||||
const uint32_t savedCount = m_instrCount;
|
||||
|
||||
UINFO(8, "ifsp:\n");
|
||||
m_instrCount = 0;
|
||||
|
|
@ -190,19 +190,19 @@ private:
|
|||
virtual void visit(AstNodeCond* nodep) override {
|
||||
// Just like if/else above, the ternary operator only evaluates
|
||||
// one of the two expressions, so only count the max.
|
||||
VisitBase vb(this, nodep);
|
||||
const VisitBase vb{this, nodep};
|
||||
iterateAndNextNull(nodep->condp());
|
||||
uint32_t savedCount = m_instrCount;
|
||||
const uint32_t savedCount = m_instrCount;
|
||||
|
||||
UINFO(8, "?\n");
|
||||
m_instrCount = 0;
|
||||
iterateAndNextNull(nodep->expr1p());
|
||||
uint32_t ifCount = m_instrCount;
|
||||
const uint32_t ifCount = m_instrCount;
|
||||
|
||||
UINFO(8, ":\n");
|
||||
m_instrCount = 0;
|
||||
iterateAndNextNull(nodep->expr2p());
|
||||
uint32_t elseCount = m_instrCount;
|
||||
const uint32_t elseCount = m_instrCount;
|
||||
|
||||
if (ifCount < elseCount) {
|
||||
m_instrCount = savedCount + elseCount;
|
||||
|
|
@ -229,7 +229,7 @@ private:
|
|||
UASSERT_OBJ(nodep == m_startNodep, nodep, "Multiple actives, or not start node");
|
||||
}
|
||||
virtual void visit(AstNodeCCall* nodep) override {
|
||||
VisitBase vb(this, nodep);
|
||||
const VisitBase vb{this, nodep};
|
||||
iterateChildren(nodep);
|
||||
m_tracingCall = true;
|
||||
iterate(nodep->funcp());
|
||||
|
|
@ -244,12 +244,12 @@ private:
|
|||
VL_RESTORER(m_inCFunc);
|
||||
{
|
||||
m_inCFunc = true;
|
||||
VisitBase vb(this, nodep);
|
||||
const VisitBase vb{this, nodep};
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
VisitBase vb(this, nodep);
|
||||
const VisitBase vb{this, nodep};
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
|
|
@ -294,7 +294,7 @@ private:
|
|||
};
|
||||
|
||||
uint32_t V3InstrCount::count(AstNode* nodep, bool assertNoDups, std::ostream* osp) {
|
||||
InstrCountVisitor visitor{nodep, assertNoDups, osp};
|
||||
const InstrCountVisitor visitor{nodep, assertNoDups, osp};
|
||||
if (osp) InstrCountDumpVisitor dumper(nodep, osp);
|
||||
return visitor.instrCount();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -303,7 +303,7 @@ private:
|
|||
virtual void visit(AstNodeAssign* nodep) override {
|
||||
// Collect any used variables first, as lhs may also be on rhs
|
||||
// Similar code in V3Dead
|
||||
vluint64_t lastEdit = AstNode::editCountGbl(); // When it was last edited
|
||||
const vluint64_t lastEdit = AstNode::editCountGbl(); // When it was last edited
|
||||
m_sideEffect = false;
|
||||
iterateAndNextNull(nodep->rhsp());
|
||||
if (lastEdit != AstNode::editCountGbl()) {
|
||||
|
|
|
|||
|
|
@ -186,9 +186,9 @@ private:
|
|||
}
|
||||
void squashAssignposts() {
|
||||
for (auto& itr : m_assignposts) {
|
||||
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
|
||||
const LifePostLocation* const app = &itr.second;
|
||||
const AstVarRef* const lhsp = VN_AS(app->nodep->lhsp(), VarRef); // original var
|
||||
const AstVarRef* const rhsp = VN_AS(app->nodep->rhsp(), VarRef); // dly var
|
||||
AstVarScope* const dlyVarp = rhsp->varScopep();
|
||||
AstVarScope* const origVarp = lhsp->varScopep();
|
||||
|
||||
|
|
@ -275,10 +275,10 @@ private:
|
|||
}
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
// Consumption/generation of a variable,
|
||||
AstVarScope* const vscp = nodep->varScopep();
|
||||
const AstVarScope* const vscp = nodep->varScopep();
|
||||
UASSERT_OBJ(vscp, nodep, "Scope not assigned");
|
||||
|
||||
LifeLocation loc(m_execMTaskp, ++m_sequence);
|
||||
const LifeLocation loc(m_execMTaskp, ++m_sequence);
|
||||
if (nodep->access().isWriteOrRW()) m_writes[vscp].insert(loc);
|
||||
if (nodep->access().isReadOrRW()) m_reads[vscp].insert(loc);
|
||||
}
|
||||
|
|
@ -292,12 +292,12 @@ private:
|
|||
virtual void visit(AstAssignPost* nodep) override {
|
||||
// Don't record ASSIGNPOST in the read/write maps, record them in a
|
||||
// separate map
|
||||
if (AstVarRef* const rhsp = VN_CAST(nodep->rhsp(), VarRef)) {
|
||||
if (const AstVarRef* const rhsp = VN_CAST(nodep->rhsp(), VarRef)) {
|
||||
// rhsp is the dly var
|
||||
AstVarScope* const dlyVarp = rhsp->varScopep();
|
||||
const 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);
|
||||
const LifeLocation loc(m_execMTaskp, ++m_sequence);
|
||||
m_assignposts[dlyVarp] = LifePostLocation(loc, nodep);
|
||||
}
|
||||
}
|
||||
|
|
@ -318,7 +318,7 @@ private:
|
|||
m_mtasksGraphp = nodep->depGraphp();
|
||||
for (V3GraphVertex* mtaskVxp = m_mtasksGraphp->verticesBeginp(); mtaskVxp;
|
||||
mtaskVxp = mtaskVxp->verticesNextp()) {
|
||||
ExecMTask* const mtaskp = dynamic_cast<ExecMTask*>(mtaskVxp);
|
||||
const ExecMTask* const mtaskp = dynamic_cast<ExecMTask*>(mtaskVxp);
|
||||
m_execMTaskp = mtaskp;
|
||||
m_sequence = 0;
|
||||
iterate(mtaskp->bodyp());
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ private:
|
|||
VSymGraph m_mods; // Symbol table of all module names
|
||||
LinkCellsGraph m_graph; // Linked graph of all cell interconnects
|
||||
LibraryVertex* m_libVertexp = nullptr; // Vertex at root of all libraries
|
||||
V3GraphVertex* m_topVertexp = nullptr; // Vertex of top module
|
||||
const V3GraphVertex* m_topVertexp = nullptr; // Vertex of top module
|
||||
std::unordered_set<string> m_declfnWarned; // Files we issued DECLFILENAME on
|
||||
string m_origTopModuleName; // original name of the top module
|
||||
|
||||
|
|
@ -474,7 +474,7 @@ private:
|
|||
nodep->name(hierIt->first); // Change name of this module to be mangled name
|
||||
// considering parameter
|
||||
}
|
||||
AstNodeModule* const foundp = findModuleSym(nodep->name());
|
||||
const AstNodeModule* const foundp = findModuleSym(nodep->name());
|
||||
if (foundp && foundp != nodep) {
|
||||
if (!(foundp->fileline()->warnIsOff(V3ErrorCode::MODDUP)
|
||||
|| nodep->fileline()->warnIsOff(V3ErrorCode::MODDUP)
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ 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* const foundp = lookupSymp->findIdFlat(name);
|
||||
const VSymEnt* const foundp = lookupSymp->findIdFlat(name);
|
||||
AstNode* const fnodep = foundp ? foundp->nodep() : nullptr;
|
||||
if (!fnodep) {
|
||||
// Not found, will add in a moment.
|
||||
|
|
@ -431,9 +431,9 @@ public:
|
|||
static AstIfaceRefDType* ifaceRefFromArray(AstNodeDType* nodep) {
|
||||
AstIfaceRefDType* ifacerefp = VN_CAST(nodep, IfaceRefDType);
|
||||
if (!ifacerefp) {
|
||||
if (AstBracketArrayDType* const arrp = VN_CAST(nodep, BracketArrayDType)) {
|
||||
if (const AstBracketArrayDType* const arrp = VN_CAST(nodep, BracketArrayDType)) {
|
||||
ifacerefp = VN_CAST(arrp->subDTypep(), IfaceRefDType);
|
||||
} else if (AstUnpackArrayDType* arrp = VN_CAST(nodep, UnpackArrayDType)) {
|
||||
} else if (const AstUnpackArrayDType* const arrp = VN_CAST(nodep, UnpackArrayDType)) {
|
||||
ifacerefp = VN_CAST(arrp->subDTypep(), IfaceRefDType);
|
||||
}
|
||||
}
|
||||
|
|
@ -441,7 +441,7 @@ public:
|
|||
}
|
||||
void computeIfaceVarSyms() {
|
||||
for (VSymEnt* varSymp : m_ifaceVarSyms) {
|
||||
AstVar* const varp = varSymp ? VN_AS(varSymp->nodep(), Var) : nullptr;
|
||||
const AstVar* const varp = varSymp ? VN_AS(varSymp->nodep(), Var) : nullptr;
|
||||
UINFO(9, " insAllIface se" << cvtToHex(varSymp) << " " << varp << endl);
|
||||
AstIfaceRefDType* const ifacerefp = ifaceRefFromArray(varp->subDTypep());
|
||||
UASSERT_OBJ(ifacerefp, varp, "Non-ifacerefs on list!");
|
||||
|
|
@ -578,10 +578,11 @@ public:
|
|||
// then look up (inst name or modname)
|
||||
if (firstId) {
|
||||
// Check this module - subcellnames
|
||||
AstCell* cellp = lookupSymp ? VN_CAST(lookupSymp->nodep(), Cell)
|
||||
: nullptr; // Replicated below
|
||||
AstCellInline* inlinep = lookupSymp ? VN_CAST(lookupSymp->nodep(), CellInline)
|
||||
: nullptr; // Replicated below
|
||||
const AstCell* cellp = lookupSymp ? VN_CAST(lookupSymp->nodep(), Cell)
|
||||
: nullptr; // Replicated below
|
||||
const AstCellInline* inlinep = lookupSymp
|
||||
? VN_CAST(lookupSymp->nodep(), CellInline)
|
||||
: nullptr; // Replicated below
|
||||
if (VSymEnt* const findSymp = findWithAltFallback(lookupSymp, ident, altIdent)) {
|
||||
lookupSymp = findSymp;
|
||||
}
|
||||
|
|
@ -613,7 +614,7 @@ public:
|
|||
if ((cellp && cellp->modp()->origName() == ident)
|
||||
|| (inlinep && inlinep->origModName() == ident)) {
|
||||
break;
|
||||
} else if (VSymEnt* findSymp
|
||||
} else if (VSymEnt* const findSymp
|
||||
= findWithAltFallback(lookupSymp, ident, altIdent)) {
|
||||
lookupSymp = findSymp;
|
||||
if (crossedCell && VN_IS(lookupSymp->nodep(), Var)) {
|
||||
|
|
@ -636,8 +637,8 @@ public:
|
|||
}
|
||||
}
|
||||
if (lookupSymp) {
|
||||
if (AstCell* const cellp = VN_CAST(lookupSymp->nodep(), Cell)) {
|
||||
if (AstNodeModule* const modp = cellp->modp()) {
|
||||
if (const AstCell* const cellp = VN_CAST(lookupSymp->nodep(), Cell)) {
|
||||
if (const AstNodeModule* const modp = cellp->modp()) {
|
||||
if (modp->hierBlock()) {
|
||||
refLocationp->v3error("Cannot access inside hierarchical block");
|
||||
} else if (VN_IS(modp, NotFoundModule)) {
|
||||
|
|
@ -713,8 +714,8 @@ class LinkDotFindVisitor final : public AstNVisitor {
|
|||
VSymEnt* m_modSymp = nullptr; // Symbol Entry for current module
|
||||
VSymEnt* m_curSymp = nullptr; // Symbol Entry for current table, where to lookup/insert
|
||||
string m_scope; // Scope text
|
||||
AstNodeBlock* m_blockp = nullptr; // Current Begin/end block
|
||||
AstNodeFTask* m_ftaskp = nullptr; // Current function/task
|
||||
const AstNodeBlock* m_blockp = nullptr; // Current Begin/end block
|
||||
const AstNodeFTask* m_ftaskp = nullptr; // Current function/task
|
||||
bool m_inRecursion = false; // Inside a recursive module
|
||||
int m_paramNum = 0; // Parameter number, for position based connection
|
||||
bool m_explicitNew = false; // Hit a "new" function
|
||||
|
|
@ -975,13 +976,13 @@ class LinkDotFindVisitor final : public AstNVisitor {
|
|||
{
|
||||
// Change to appropriate package if extern declaration (vs definition)
|
||||
if (nodep->classOrPackagep()) {
|
||||
AstClassOrPackageRef* cpackagerefp
|
||||
AstClassOrPackageRef* const cpackagerefp
|
||||
= VN_CAST(nodep->classOrPackagep(), ClassOrPackageRef);
|
||||
if (!cpackagerefp) {
|
||||
nodep->v3warn(E_UNSUPPORTED,
|
||||
"Unsupported: extern function definition with class-in-class");
|
||||
} else {
|
||||
AstClass* classp = VN_CAST(cpackagerefp->classOrPackagep(), Class);
|
||||
AstClass* const classp = VN_CAST(cpackagerefp->classOrPackagep(), Class);
|
||||
if (!classp) {
|
||||
nodep->v3error("Extern declaration's scope is not a defined class");
|
||||
} else {
|
||||
|
|
@ -1017,8 +1018,9 @@ class LinkDotFindVisitor final : public AstNVisitor {
|
|||
} else {
|
||||
dtypep = new AstBasicDType(nodep->fileline(), AstBasicDTypeKwd::LOGIC);
|
||||
}
|
||||
AstVar* newvarp = new AstVar(nodep->fileline(), AstVarType::VAR, nodep->name(),
|
||||
VFlagChildDType(), dtypep); // Not dtype resolved yet
|
||||
AstVar* const newvarp
|
||||
= new AstVar(nodep->fileline(), AstVarType::VAR, nodep->name(),
|
||||
VFlagChildDType(), dtypep); // Not dtype resolved yet
|
||||
newvarp->direction(VDirection::OUTPUT);
|
||||
newvarp->lifetime(VLifetime::AUTOMATIC);
|
||||
newvarp->funcReturn(true);
|
||||
|
|
@ -1045,11 +1047,11 @@ class LinkDotFindVisitor final : public AstNVisitor {
|
|||
}
|
||||
if (!m_statep->forScopeCreation()) {
|
||||
// Find under either a task or the module's vars
|
||||
VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name());
|
||||
const VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name());
|
||||
if (!foundp && m_modSymp && nodep->name() == m_modSymp->nodep()->name()) {
|
||||
foundp = m_modSymp; // Conflicts with modname?
|
||||
}
|
||||
AstVar* findvarp = foundp ? VN_CAST(foundp->nodep(), Var) : nullptr;
|
||||
AstVar* const findvarp = foundp ? VN_CAST(foundp->nodep(), Var) : nullptr;
|
||||
bool ins = false;
|
||||
if (!foundp) {
|
||||
ins = true;
|
||||
|
|
@ -1063,7 +1065,7 @@ class LinkDotFindVisitor final : public AstNVisitor {
|
|||
<< cvtToHex(foundp->parentp()) << endl);
|
||||
if (foundp->parentp() == m_curSymp // Only when on same level
|
||||
&& !foundp->imported()) { // and not from package
|
||||
bool nansiBad
|
||||
const bool nansiBad
|
||||
= ((findvarp->isDeclTyped() && nodep->isDeclTyped())
|
||||
|| (findvarp->isIO() && nodep->isIO())); // e.g. !(output && output)
|
||||
const bool ansiBad
|
||||
|
|
@ -1091,11 +1093,12 @@ class LinkDotFindVisitor final : public AstNVisitor {
|
|||
} else {
|
||||
findvarp->combineType(nodep);
|
||||
findvarp->fileline()->modifyStateInherit(nodep->fileline());
|
||||
AstBasicDType* bdtypep = VN_CAST(findvarp->childDTypep(), BasicDType);
|
||||
AstBasicDType* const bdtypep
|
||||
= VN_CAST(findvarp->childDTypep(), BasicDType);
|
||||
if (bdtypep && bdtypep->implicit()) {
|
||||
// Then have "input foo" and "real foo" so the
|
||||
// dtype comes from the other side.
|
||||
AstNodeDType* newdtypep = nodep->subDTypep();
|
||||
AstNodeDType* const newdtypep = nodep->subDTypep();
|
||||
UASSERT_OBJ(newdtypep && nodep->childDTypep(), findvarp,
|
||||
"No child type?");
|
||||
VL_DO_DANGLING(bdtypep->unlinkFrBack()->deleteTree(), bdtypep);
|
||||
|
|
@ -1129,12 +1132,12 @@ class LinkDotFindVisitor final : public AstNVisitor {
|
|||
// We first search if the parameter is overwritten and then replace it with a
|
||||
// new value. It will keep the same FileLine information.
|
||||
if (v3Global.opt.hasParameter(nodep->name())) {
|
||||
AstVar* newp
|
||||
AstVar* const newp
|
||||
= new AstVar(nodep->fileline(), AstVarType(AstVarType::GPARAM),
|
||||
nodep->name(), nodep);
|
||||
newp->combineType(nodep);
|
||||
const string svalue = v3Global.opt.parameter(nodep->name());
|
||||
if (AstNode* valuep
|
||||
if (AstNode* const valuep
|
||||
= AstConst::parseParamLiteral(nodep->fileline(), svalue)) {
|
||||
newp->valuep(valuep);
|
||||
UINFO(9, " replace parameter " << nodep << endl);
|
||||
|
|
@ -1145,16 +1148,17 @@ class LinkDotFindVisitor final : public AstNVisitor {
|
|||
}
|
||||
}
|
||||
}
|
||||
VSymEnt* insp
|
||||
VSymEnt* const insp
|
||||
= m_statep->insertSym(m_curSymp, nodep->name(), nodep, m_classOrPackagep);
|
||||
if (m_statep->forPrimary() && nodep->isGParam()) {
|
||||
++m_paramNum;
|
||||
VSymEnt* symp
|
||||
VSymEnt* const symp
|
||||
= m_statep->insertSym(m_curSymp, "__paramNumber" + cvtToStr(m_paramNum),
|
||||
nodep, m_classOrPackagep);
|
||||
symp->exported(false);
|
||||
}
|
||||
AstIfaceRefDType* ifacerefp = LinkDotState::ifaceRefFromArray(nodep->subDTypep());
|
||||
AstIfaceRefDType* const ifacerefp
|
||||
= LinkDotState::ifaceRefFromArray(nodep->subDTypep());
|
||||
if (ifacerefp) {
|
||||
// Can't resolve until interfaces and modport names are
|
||||
// known; see notes at top
|
||||
|
|
@ -1193,11 +1197,11 @@ class LinkDotFindVisitor final : public AstNVisitor {
|
|||
// EnumItem: Remember its name for later resolution
|
||||
iterateChildren(nodep);
|
||||
// Find under either a task or the module's vars
|
||||
VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name());
|
||||
const VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name());
|
||||
if (!foundp && m_modSymp && nodep->name() == m_modSymp->nodep()->name()) {
|
||||
foundp = m_modSymp; // Conflicts with modname?
|
||||
}
|
||||
AstEnumItem* findvarp = foundp ? VN_AS(foundp->nodep(), EnumItem) : nullptr;
|
||||
AstEnumItem* const findvarp = foundp ? VN_AS(foundp->nodep(), EnumItem) : nullptr;
|
||||
bool ins = false;
|
||||
if (!foundp) {
|
||||
ins = true;
|
||||
|
|
@ -1230,13 +1234,13 @@ class LinkDotFindVisitor final : public AstNVisitor {
|
|||
}
|
||||
virtual void visit(AstPackageImport* nodep) override {
|
||||
UINFO(4, " Link: " << nodep << endl);
|
||||
VSymEnt* srcp = m_statep->getNodeSym(nodep->packagep());
|
||||
VSymEnt* const srcp = m_statep->getNodeSym(nodep->packagep());
|
||||
if (nodep->name() == "*") {
|
||||
if (m_curSymp == m_statep->dunitEntp()) {
|
||||
nodep->v3warn(IMPORTSTAR, "Import::* in $unit scope may pollute global namespace");
|
||||
}
|
||||
} else {
|
||||
VSymEnt* impp = srcp->findIdFlat(nodep->name());
|
||||
VSymEnt* const impp = srcp->findIdFlat(nodep->name());
|
||||
if (!impp) {
|
||||
nodep->v3error("Import object not found: '" << nodep->packagep()->prettyName()
|
||||
<< "::" << nodep->prettyName() << "'");
|
||||
|
|
@ -1248,9 +1252,9 @@ class LinkDotFindVisitor final : public AstNVisitor {
|
|||
}
|
||||
virtual void visit(AstPackageExport* nodep) override {
|
||||
UINFO(9, " Link: " << nodep << endl);
|
||||
VSymEnt* srcp = m_statep->getNodeSym(nodep->packagep());
|
||||
VSymEnt* const srcp = m_statep->getNodeSym(nodep->packagep());
|
||||
if (nodep->name() != "*") {
|
||||
VSymEnt* impp = srcp->findIdFlat(nodep->name());
|
||||
VSymEnt* const impp = srcp->findIdFlat(nodep->name());
|
||||
if (!impp) {
|
||||
nodep->v3error("Export object not found: '" << nodep->packagep()->prettyName()
|
||||
<< "::" << nodep->prettyName() << "'");
|
||||
|
|
@ -1335,7 +1339,7 @@ private:
|
|||
// *::user4() -> See LinkDotState
|
||||
|
||||
// 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_modp = nullptr; // Current module
|
||||
|
||||
static int debug() { return LinkDotState::debug(); }
|
||||
|
|
@ -1397,18 +1401,18 @@ private:
|
|||
<< nodep->warnMore()
|
||||
<< "... Suggest use instantiation with #(."
|
||||
<< nodep->prettyName() << "(...etc...))");
|
||||
VSymEnt* foundp = m_statep->getNodeSym(nodep)->findIdFallback(nodep->path());
|
||||
AstCell* cellp = foundp ? VN_AS(foundp->nodep(), Cell) : nullptr;
|
||||
VSymEnt* const foundp = m_statep->getNodeSym(nodep)->findIdFallback(nodep->path());
|
||||
AstCell* const cellp = foundp ? VN_AS(foundp->nodep(), Cell) : nullptr;
|
||||
if (!cellp) {
|
||||
nodep->v3error("In defparam, instance " << nodep->path() << " never declared");
|
||||
} else {
|
||||
AstNode* exprp = nodep->rhsp()->unlinkFrBack();
|
||||
AstNode* const exprp = nodep->rhsp()->unlinkFrBack();
|
||||
UINFO(9, "Defparam cell " << nodep->path() << "." << nodep->name() << " attach-to "
|
||||
<< cellp << " <= " << exprp << endl);
|
||||
// Don't need to check the name of the defparam exists. V3Param does.
|
||||
AstPin* pinp = new AstPin(nodep->fileline(),
|
||||
-1, // Pin# not relevant
|
||||
nodep->name(), exprp);
|
||||
AstPin* const pinp = new AstPin(nodep->fileline(),
|
||||
-1, // Pin# not relevant
|
||||
nodep->name(), exprp);
|
||||
cellp->addParamsp(pinp);
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
}
|
||||
|
|
@ -1417,8 +1421,8 @@ private:
|
|||
// Port: Stash the pin number
|
||||
// Need to set pin numbers after varnames are created
|
||||
// But before we do the final resolution based on names
|
||||
VSymEnt* foundp = m_statep->getNodeSym(m_modp)->findIdFlat(nodep->name());
|
||||
AstVar* refp = foundp ? VN_AS(foundp->nodep(), Var) : nullptr;
|
||||
VSymEnt* const foundp = m_statep->getNodeSym(m_modp)->findIdFlat(nodep->name());
|
||||
AstVar* const refp = foundp ? VN_AS(foundp->nodep(), Var) : nullptr;
|
||||
if (!refp) {
|
||||
nodep->v3error(
|
||||
"Input/output/inout declaration not found for port: " << nodep->prettyNameQ());
|
||||
|
|
@ -1433,9 +1437,9 @@ private:
|
|||
<< refp->warnContextSecondary());
|
||||
}
|
||||
refp->user4(true);
|
||||
VSymEnt* symp = m_statep->insertSym(m_statep->getNodeSym(m_modp),
|
||||
"__pinNumber" + cvtToStr(nodep->pinNum()), refp,
|
||||
nullptr /*classOrPackagep*/);
|
||||
VSymEnt* const symp = m_statep->insertSym(m_statep->getNodeSym(m_modp),
|
||||
"__pinNumber" + cvtToStr(nodep->pinNum()),
|
||||
refp, nullptr /*classOrPackagep*/);
|
||||
symp->exported(false);
|
||||
refp->pinNum(nodep->pinNum());
|
||||
}
|
||||
|
|
@ -1453,10 +1457,10 @@ private:
|
|||
// tran gates need implicit creation
|
||||
// As VarRefs don't exist in forPrimary, sanity check
|
||||
UASSERT_OBJ(!m_statep->forPrimary(), nodep, "Assign aliases unexpected pre-dot");
|
||||
if (AstVarRef* forrefp = VN_CAST(nodep->lhsp(), VarRef)) {
|
||||
if (AstVarRef* const forrefp = VN_CAST(nodep->lhsp(), VarRef)) {
|
||||
pinImplicitExprRecurse(forrefp);
|
||||
}
|
||||
if (AstVarRef* forrefp = VN_CAST(nodep->rhsp(), VarRef)) {
|
||||
if (AstVarRef* const forrefp = VN_CAST(nodep->rhsp(), VarRef)) {
|
||||
pinImplicitExprRecurse(forrefp);
|
||||
}
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -1468,9 +1472,9 @@ private:
|
|||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
}
|
||||
virtual void visit(AstClassOrPackageRef* nodep) override {
|
||||
if (auto* fwdp = VN_CAST(nodep->classOrPackageNodep(), TypedefFwd)) {
|
||||
if (auto* const fwdp = VN_CAST(nodep->classOrPackageNodep(), TypedefFwd)) {
|
||||
// Relink forward definitions to the "real" definition
|
||||
VSymEnt* foundp = m_statep->getNodeSym(fwdp)->findIdFallback(fwdp->name());
|
||||
VSymEnt* const foundp = m_statep->getNodeSym(fwdp)->findIdFallback(fwdp->name());
|
||||
if (foundp && (VN_IS(foundp->nodep(), Class) || VN_IS(foundp->nodep(), Package))) {
|
||||
nodep->classOrPackagep(VN_AS(foundp->nodep(), NodeModule));
|
||||
} else if (foundp && VN_IS(foundp->nodep(), ParamTypeDType)) {
|
||||
|
|
@ -1490,7 +1494,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstTypedefFwd* nodep) override {
|
||||
VSymEnt* foundp = m_statep->getNodeSym(nodep)->findIdFallback(nodep->name());
|
||||
VSymEnt* const foundp = m_statep->getNodeSym(nodep)->findIdFallback(nodep->name());
|
||||
if (!foundp && v3Global.opt.pedantic()) {
|
||||
// We only check it was ever really defined in pedantic mode, as it
|
||||
// might have been in a header file referring to a module we never
|
||||
|
|
@ -1521,8 +1525,8 @@ public:
|
|||
class LinkDotScopeVisitor final : public AstNVisitor {
|
||||
|
||||
// STATE
|
||||
LinkDotState* m_statep; // State to pass between visitors, including symbol table
|
||||
AstScope* m_scopep = nullptr; // The current scope
|
||||
LinkDotState* const m_statep; // State to pass between visitors, including symbol table
|
||||
const AstScope* m_scopep = nullptr; // The current scope
|
||||
VSymEnt* m_modSymp = nullptr; // Symbol entry for current module
|
||||
|
||||
static int debug() { return LinkDotState::debug(); }
|
||||
|
|
@ -1547,12 +1551,12 @@ class LinkDotScopeVisitor final : public AstNVisitor {
|
|||
}
|
||||
virtual void visit(AstVarScope* nodep) override {
|
||||
if (!nodep->varp()->isFuncLocal() && !nodep->varp()->isClassMember()) {
|
||||
VSymEnt* varSymp
|
||||
VSymEnt* const varSymp
|
||||
= m_statep->insertSym(m_modSymp, nodep->varp()->name(), nodep, nullptr);
|
||||
if (nodep->varp()->isIfaceRef() && nodep->varp()->isIfaceParent()) {
|
||||
UINFO(9, "Iface parent ref var " << nodep->varp()->name() << " " << nodep << endl);
|
||||
// Find the interface cell the var references
|
||||
AstIfaceRefDType* dtypep
|
||||
AstIfaceRefDType* const dtypep
|
||||
= LinkDotState::ifaceRefFromArray(nodep->varp()->dtypep());
|
||||
UASSERT_OBJ(dtypep, nodep, "Non AstIfaceRefDType on isIfaceRef() var");
|
||||
UINFO(9, "Iface parent dtype " << dtypep << endl);
|
||||
|
|
@ -1567,8 +1571,8 @@ class LinkDotScopeVisitor final : public AstNVisitor {
|
|||
UINFO(5, " Found interface instance: se" << cvtToHex(cellSymp) << " "
|
||||
<< cellSymp->nodep() << endl);
|
||||
if (dtypep->modportName() != "") {
|
||||
VSymEnt* mpSymp = m_statep->findDotted(nodep->fileline(), m_modSymp,
|
||||
ifcellname, baddot, okSymp);
|
||||
VSymEnt* const mpSymp = m_statep->findDotted(nodep->fileline(), m_modSymp,
|
||||
ifcellname, baddot, okSymp);
|
||||
UASSERT_OBJ(mpSymp, nodep,
|
||||
"No symbol for interface modport: "
|
||||
<< nodep->prettyNameQ(dtypep->modportName()));
|
||||
|
|
@ -1584,12 +1588,12 @@ class LinkDotScopeVisitor final : public AstNVisitor {
|
|||
}
|
||||
}
|
||||
virtual void visit(AstNodeFTask* nodep) override {
|
||||
VSymEnt* symp = m_statep->insertBlock(m_modSymp, nodep->name(), nodep, nullptr);
|
||||
VSymEnt* const symp = m_statep->insertBlock(m_modSymp, nodep->name(), nodep, nullptr);
|
||||
symp->fallbackp(m_modSymp);
|
||||
// No recursion, we don't want to pick up variables
|
||||
}
|
||||
virtual void visit(AstWith* nodep) override {
|
||||
VSymEnt* symp = m_statep->insertBlock(m_modSymp, nodep->name(), nodep, nullptr);
|
||||
VSymEnt* const symp = m_statep->insertBlock(m_modSymp, nodep->name(), nodep, nullptr);
|
||||
symp->fallbackp(m_modSymp);
|
||||
// No recursion, we don't want to pick up variables
|
||||
}
|
||||
|
|
@ -1597,8 +1601,8 @@ class LinkDotScopeVisitor final : public AstNVisitor {
|
|||
// Track aliases created by V3Inline; if we get a VARXREF(aliased_from)
|
||||
// we'll need to replace it with a VARXREF(aliased_to)
|
||||
if (debug() >= 9) nodep->dumpTree(cout, "- alias: ");
|
||||
AstVarScope* fromVscp = VN_AS(nodep->lhsp(), VarRef)->varScopep();
|
||||
AstVarScope* toVscp = VN_AS(nodep->rhsp(), VarRef)->varScopep();
|
||||
AstVarScope* const fromVscp = VN_AS(nodep->lhsp(), VarRef)->varScopep();
|
||||
AstVarScope* const toVscp = VN_AS(nodep->rhsp(), VarRef)->varScopep();
|
||||
UASSERT_OBJ(fromVscp && toVscp, nodep, "Bad alias scopes");
|
||||
fromVscp->user2p(toVscp);
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -1608,8 +1612,8 @@ class LinkDotScopeVisitor final : public AstNVisitor {
|
|||
if (debug() >= 9) nodep->dumpTree(cout, "- avs: ");
|
||||
VSymEnt* rhsSymp;
|
||||
{
|
||||
AstVarRef* refp = VN_CAST(nodep->rhsp(), VarRef);
|
||||
AstVarXRef* xrefp = VN_CAST(nodep->rhsp(), VarXRef);
|
||||
AstVarRef* const refp = VN_CAST(nodep->rhsp(), VarRef);
|
||||
AstVarXRef* const xrefp = VN_CAST(nodep->rhsp(), VarXRef);
|
||||
UASSERT_OBJ(refp || xrefp, nodep,
|
||||
"Unsupported: Non Var(X)Ref attached to interface pin");
|
||||
string inl
|
||||
|
|
@ -1638,8 +1642,8 @@ class LinkDotScopeVisitor final : public AstNVisitor {
|
|||
}
|
||||
VSymEnt* lhsSymp;
|
||||
{
|
||||
const AstVarXRef* xrefp = VN_CAST(nodep->lhsp(), VarXRef);
|
||||
const AstVarRef* refp = VN_CAST(nodep->lhsp(), VarRef);
|
||||
const AstVarXRef* const xrefp = VN_CAST(nodep->lhsp(), VarXRef);
|
||||
const AstVarRef* const refp = VN_CAST(nodep->lhsp(), VarRef);
|
||||
|
||||
UASSERT_OBJ(refp || xrefp, nodep,
|
||||
"Unsupported: Non Var(X)Ref attached to interface pin");
|
||||
|
|
@ -1647,8 +1651,8 @@ class LinkDotScopeVisitor final : public AstNVisitor {
|
|||
= refp ? refp->varp()->name() : xrefp->dotted() + "." + xrefp->name();
|
||||
string baddot;
|
||||
VSymEnt* okSymp;
|
||||
VSymEnt* symp = m_statep->findDotted(nodep->lhsp()->fileline(), m_modSymp, scopename,
|
||||
baddot, okSymp);
|
||||
VSymEnt* const symp = m_statep->findDotted(nodep->lhsp()->fileline(), m_modSymp,
|
||||
scopename, baddot, okSymp);
|
||||
UASSERT_OBJ(symp, nodep, "No symbol for interface alias lhs");
|
||||
UINFO(5, " Found a linked scope LHS: " << scopename << " se" << cvtToHex(symp)
|
||||
<< " " << symp->nodep() << endl);
|
||||
|
|
@ -1705,13 +1709,13 @@ class LinkDotIfaceVisitor final : public AstNVisitor {
|
|||
UINFO(5, " fif: " << nodep << endl);
|
||||
iterateChildren(nodep);
|
||||
if (nodep->isExport()) nodep->v3warn(E_UNSUPPORTED, "Unsupported: modport export");
|
||||
VSymEnt* symp = m_curSymp->findIdFallback(nodep->name());
|
||||
VSymEnt* const symp = m_curSymp->findIdFallback(nodep->name());
|
||||
if (!symp) {
|
||||
nodep->v3error("Modport item not found: " << nodep->prettyNameQ());
|
||||
} else if (AstNodeFTask* ftaskp = VN_CAST(symp->nodep(), NodeFTask)) {
|
||||
} else if (AstNodeFTask* const ftaskp = VN_CAST(symp->nodep(), NodeFTask)) {
|
||||
// Make symbol under modport that points at the _interface_'s var, not the modport.
|
||||
nodep->ftaskp(ftaskp);
|
||||
VSymEnt* subSymp
|
||||
VSymEnt* const subSymp
|
||||
= m_statep->insertSym(m_curSymp, nodep->name(), ftaskp, nullptr /*package*/);
|
||||
m_statep->insertScopeAlias(LinkDotState::SAMN_MODPORT, subSymp, symp);
|
||||
} else {
|
||||
|
|
@ -1727,15 +1731,15 @@ class LinkDotIfaceVisitor final : public AstNVisitor {
|
|||
virtual void visit(AstModportVarRef* nodep) override {
|
||||
UINFO(5, " fiv: " << nodep << endl);
|
||||
iterateChildren(nodep);
|
||||
VSymEnt* symp = m_curSymp->findIdFallback(nodep->name());
|
||||
VSymEnt* const symp = m_curSymp->findIdFallback(nodep->name());
|
||||
if (!symp) {
|
||||
nodep->v3error("Modport item not found: " << nodep->prettyNameQ());
|
||||
} else if (AstVar* varp = VN_CAST(symp->nodep(), Var)) {
|
||||
} else if (AstVar* const varp = VN_CAST(symp->nodep(), Var)) {
|
||||
// Make symbol under modport that points at the _interface_'s var via the modport.
|
||||
// (Need modport still to test input/output markings)
|
||||
nodep->varp(varp);
|
||||
m_statep->insertSym(m_curSymp, nodep->name(), nodep, nullptr /*package*/);
|
||||
} else if (AstVarScope* vscp = VN_CAST(symp->nodep(), VarScope)) {
|
||||
} else if (AstVarScope* const vscp = VN_CAST(symp->nodep(), VarScope)) {
|
||||
// Make symbol under modport that points at the _interface_'s var, not the modport.
|
||||
nodep->varp(vscp->varp());
|
||||
m_statep->insertSym(m_curSymp, nodep->name(), vscp, nullptr /*package*/);
|
||||
|
|
@ -1764,8 +1768,8 @@ public:
|
|||
|
||||
void LinkDotState::computeIfaceModSyms() {
|
||||
for (const auto& itr : m_ifaceModSyms) {
|
||||
AstIface* nodep = itr.first;
|
||||
VSymEnt* symp = itr.second;
|
||||
AstIface* const nodep = itr.first;
|
||||
VSymEnt* const symp = itr.second;
|
||||
LinkDotIfaceVisitor{nodep, symp, this};
|
||||
}
|
||||
m_ifaceModSyms.clear();
|
||||
|
|
@ -1796,19 +1800,19 @@ private:
|
|||
}; // DOT {member-name} [DOT...]
|
||||
|
||||
// STATE
|
||||
LinkDotState* m_statep; // State, including dotted symbol table
|
||||
LinkDotState* const m_statep; // State, including dotted symbol table
|
||||
VSymEnt* m_curSymp = nullptr; // SymEnt for current lookup point
|
||||
VSymEnt* m_modSymp = nullptr; // SymEnt for current module
|
||||
VSymEnt* m_pinSymp = nullptr; // SymEnt for pin lookups
|
||||
AstCell* m_cellp = nullptr; // Current cell
|
||||
const AstCell* m_cellp = nullptr; // Current cell
|
||||
AstNodeModule* m_modp = nullptr; // Current module
|
||||
AstNodeFTask* m_ftaskp = nullptr; // Current function/task
|
||||
const AstNodeFTask* m_ftaskp = nullptr; // Current function/task
|
||||
int m_modportNum = 0; // Uniqueify modport numbers
|
||||
|
||||
struct DotStates {
|
||||
DotPosition m_dotPos; // Scope part of dotted resolution
|
||||
VSymEnt* m_dotSymp; // SymEnt for dotted AstParse lookup
|
||||
AstDot* m_dotp; // Current dot
|
||||
const AstDot* m_dotp; // Current dot
|
||||
bool m_unresolved; // Unresolved, needs help from V3Param
|
||||
AstNode* m_unlinkedScopep; // Unresolved scope, needs corresponding VarXRef
|
||||
bool m_dotErr; // Error found in dotted resolution, ignore upwards
|
||||
|
|
@ -1863,8 +1867,8 @@ private:
|
|||
<< (suggest.empty() ? "" : nodep->warnMore() + suggest));
|
||||
}
|
||||
}
|
||||
AstVar* newp = new AstVar(nodep->fileline(), AstVarType::WIRE, nodep->name(),
|
||||
VFlagLogicPacked(), 1);
|
||||
AstVar* const newp = new AstVar(nodep->fileline(), AstVarType::WIRE, nodep->name(),
|
||||
VFlagLogicPacked(), 1);
|
||||
newp->trace(modp->modTrace());
|
||||
nodep->varp(newp);
|
||||
modp->addStmtp(newp);
|
||||
|
|
@ -1880,8 +1884,8 @@ private:
|
|||
} else if (VN_IS(symp->nodep(), Var)) {
|
||||
return VN_AS(symp->nodep(), Var);
|
||||
} else if (VN_IS(symp->nodep(), ModportVarRef)) {
|
||||
AstModportVarRef* snodep = VN_AS(symp->nodep(), ModportVarRef);
|
||||
AstVar* varp = snodep->varp();
|
||||
AstModportVarRef* const snodep = VN_AS(symp->nodep(), ModportVarRef);
|
||||
AstVar* const varp = snodep->varp();
|
||||
if (access.isWriteOrRW() && snodep->direction().isReadOnly()) {
|
||||
nodep->v3error("Attempt to drive input-only modport: " << nodep->prettyNameQ());
|
||||
} // else other simulators don't warn about reading, and IEEE doesn't say illegal
|
||||
|
|
@ -1906,8 +1910,8 @@ private:
|
|||
}
|
||||
AstVar* findIfaceTopVarp(AstNode* nodep, VSymEnt* parentEntp, const string& name) {
|
||||
const string findName = name + "__Viftop";
|
||||
VSymEnt* ifaceSymp = parentEntp->findIdFallback(findName);
|
||||
AstVar* ifaceTopVarp = ifaceSymp ? VN_AS(ifaceSymp->nodep(), Var) : nullptr;
|
||||
VSymEnt* const ifaceSymp = parentEntp->findIdFallback(findName);
|
||||
AstVar* const ifaceTopVarp = ifaceSymp ? VN_AS(ifaceSymp->nodep(), Var) : nullptr;
|
||||
UASSERT_OBJ(ifaceTopVarp, nodep, "Can't find interface var ref: " << findName);
|
||||
return ifaceTopVarp;
|
||||
}
|
||||
|
|
@ -2014,8 +2018,8 @@ private:
|
|||
iterateChildren(nodep);
|
||||
if (!nodep->modVarp()) {
|
||||
UASSERT_OBJ(m_pinSymp, nodep, "Pin not under instance?");
|
||||
VSymEnt* foundp = m_pinSymp->findIdFlat(nodep->name());
|
||||
const char* whatp = nodep->param() ? "parameter pin" : "pin";
|
||||
VSymEnt* const foundp = m_pinSymp->findIdFlat(nodep->name());
|
||||
const char* const whatp = nodep->param() ? "parameter pin" : "pin";
|
||||
if (!foundp) {
|
||||
if (nodep->name() == "__paramNumber1" && m_cellp
|
||||
&& VN_IS(m_cellp->modp(), Primitive)) {
|
||||
|
|
@ -2023,7 +2027,7 @@ private:
|
|||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
return;
|
||||
}
|
||||
string suggest
|
||||
const string suggest
|
||||
= (nodep->param() ? m_statep->suggestSymFlat(m_pinSymp, nodep->name(),
|
||||
LinkNodeMatcherVarParam())
|
||||
: m_statep->suggestSymFlat(m_pinSymp, nodep->name(),
|
||||
|
|
@ -2032,7 +2036,7 @@ private:
|
|||
ucfirst(whatp)
|
||||
<< " not found: " << nodep->prettyNameQ() << '\n'
|
||||
<< (suggest.empty() ? "" : nodep->warnMore() + suggest));
|
||||
} else if (AstVar* refp = VN_CAST(foundp->nodep(), Var)) {
|
||||
} else if (AstVar* const refp = VN_CAST(foundp->nodep(), Var)) {
|
||||
if (!refp->isIO() && !refp->isParam() && !refp->isIfaceRef()) {
|
||||
nodep->v3error(ucfirst(whatp) << " is not an in/out/inout/param/interface: "
|
||||
<< nodep->prettyNameQ());
|
||||
|
|
@ -2040,7 +2044,7 @@ private:
|
|||
nodep->modVarp(refp);
|
||||
markAndCheckPinDup(nodep, refp, whatp);
|
||||
}
|
||||
} else if (AstParamTypeDType* refp = VN_CAST(foundp->nodep(), ParamTypeDType)) {
|
||||
} else if (AstParamTypeDType* const refp = VN_CAST(foundp->nodep(), ParamTypeDType)) {
|
||||
nodep->modPTypep(refp);
|
||||
markAndCheckPinDup(nodep, refp, whatp);
|
||||
} else {
|
||||
|
|
@ -2080,7 +2084,7 @@ private:
|
|||
UINFO(8, " this. " << m_ds.ascii() << endl);
|
||||
}
|
||||
} else if (VN_IS(nodep->lhsp(), ParseRef) && nodep->lhsp()->name() == "super") {
|
||||
VSymEnt* classSymp = m_ds.m_dotSymp;
|
||||
const VSymEnt* classSymp = m_ds.m_dotSymp;
|
||||
do {
|
||||
classSymp = classSymp->parentp();
|
||||
} while (classSymp && !VN_IS(classSymp->nodep(), Class));
|
||||
|
|
@ -2137,8 +2141,8 @@ private:
|
|||
} else { // Dot midpoint
|
||||
AstNode* newp = nodep->rhsp()->unlinkFrBack();
|
||||
if (m_ds.m_unresolved) {
|
||||
AstCellRef* crp = new AstCellRef(nodep->fileline(), nodep->name(),
|
||||
nodep->lhsp()->unlinkFrBack(), newp);
|
||||
AstCellRef* const crp = new AstCellRef(nodep->fileline(), nodep->name(),
|
||||
nodep->lhsp()->unlinkFrBack(), newp);
|
||||
newp = crp;
|
||||
}
|
||||
nodep->replaceWith(newp);
|
||||
|
|
@ -2182,8 +2186,8 @@ private:
|
|||
return;
|
||||
} else if (m_ds.m_dotPos == DP_MEMBER) {
|
||||
// Found a Var, everything following is membership. {scope}.{var}.HERE {member}
|
||||
AstNode* varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack();
|
||||
AstNode* newp
|
||||
AstNode* const varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack();
|
||||
AstNode* const newp
|
||||
= new AstMemberSel(nodep->fileline(), varEtcp, VFlagChildDType(), nodep->name());
|
||||
if (m_ds.m_dotErr) {
|
||||
nodep->unlinkFrBack(); // Avoid circular node loop on errors
|
||||
|
|
@ -2204,7 +2208,8 @@ private:
|
|||
allowVar = true;
|
||||
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), ClassOrPackageRef), m_ds.m_dotp->lhsp(),
|
||||
"Bad package link");
|
||||
AstClassOrPackageRef* cpackagerefp = VN_AS(m_ds.m_dotp->lhsp(), ClassOrPackageRef);
|
||||
AstClassOrPackageRef* const cpackagerefp
|
||||
= VN_AS(m_ds.m_dotp->lhsp(), ClassOrPackageRef);
|
||||
classOrPackagep = cpackagerefp->classOrPackagep();
|
||||
UASSERT_OBJ(classOrPackagep, m_ds.m_dotp->lhsp(), "Bad package link");
|
||||
m_ds.m_dotSymp = m_statep->getNodeSym(classOrPackagep);
|
||||
|
|
@ -2249,22 +2254,23 @@ private:
|
|||
m_ds.m_dotPos = DP_SCOPE;
|
||||
// Upper AstDot visitor will handle it from here
|
||||
} else if (VN_IS(foundp->nodep(), Cell) && allowVar && m_cellp) {
|
||||
AstCell* cellp = VN_AS(foundp->nodep(), Cell);
|
||||
AstCell* const cellp = VN_AS(foundp->nodep(), Cell);
|
||||
if (VN_IS(cellp->modp(), Iface)) {
|
||||
// Interfaces can be referenced like a variable for interconnect
|
||||
VSymEnt* cellEntp = m_statep->getNodeSym(cellp);
|
||||
VSymEnt* const cellEntp = m_statep->getNodeSym(cellp);
|
||||
UASSERT_OBJ(cellEntp, nodep, "No interface sym entry");
|
||||
VSymEnt* parentEntp
|
||||
VSymEnt* const parentEntp
|
||||
= cellEntp->parentp(); // Container of the var; probably a module or
|
||||
// generate begin
|
||||
AstVar* ifaceRefVarp = findIfaceTopVarp(nodep, parentEntp, nodep->name());
|
||||
AstVar* const ifaceRefVarp
|
||||
= findIfaceTopVarp(nodep, parentEntp, nodep->name());
|
||||
//
|
||||
ok = true;
|
||||
m_ds.m_dotText = VString::dot(m_ds.m_dotText, ".", nodep->name());
|
||||
m_ds.m_dotSymp = foundp;
|
||||
m_ds.m_dotPos = DP_SCOPE;
|
||||
UINFO(9, " cell -> iface varref " << foundp->nodep() << endl);
|
||||
AstNode* newp
|
||||
AstNode* const newp
|
||||
= new AstVarRef(ifaceRefVarp->fileline(), ifaceRefVarp, VAccess::READ);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
|
|
@ -2273,8 +2279,9 @@ private:
|
|||
<< cellp->modp()->prettyNameQ());
|
||||
}
|
||||
}
|
||||
} else if (AstVar* varp = foundToVarp(foundp, nodep, VAccess::READ)) {
|
||||
AstIfaceRefDType* ifacerefp = LinkDotState::ifaceRefFromArray(varp->subDTypep());
|
||||
} else if (AstVar* const varp = foundToVarp(foundp, nodep, VAccess::READ)) {
|
||||
AstIfaceRefDType* const ifacerefp
|
||||
= LinkDotState::ifaceRefFromArray(varp->subDTypep());
|
||||
if (ifacerefp) {
|
||||
UASSERT_OBJ(ifacerefp->ifaceViaCellp(), ifacerefp, "Unlinked interface");
|
||||
// Really this is a scope reference into an interface
|
||||
|
|
@ -2283,13 +2290,13 @@ private:
|
|||
m_ds.m_dotSymp = m_statep->getNodeSym(ifacerefp->ifaceViaCellp());
|
||||
m_ds.m_dotPos = DP_SCOPE;
|
||||
ok = true;
|
||||
AstNode* newp = new AstVarRef(nodep->fileline(), varp, VAccess::READ);
|
||||
AstNode* const newp = new AstVarRef(nodep->fileline(), varp, VAccess::READ);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (allowVar) {
|
||||
AstNode* newp;
|
||||
if (m_ds.m_dotText != "") {
|
||||
AstVarXRef* refp
|
||||
AstVarXRef* const refp
|
||||
= new AstVarXRef(nodep->fileline(), nodep->name(), m_ds.m_dotText,
|
||||
VAccess::READ); // lvalue'ness computed later
|
||||
refp->varp(varp);
|
||||
|
|
@ -2320,7 +2327,7 @@ private:
|
|||
newp = refp;
|
||||
}
|
||||
} else {
|
||||
AstVarRef* refp
|
||||
AstVarRef* const refp
|
||||
= new AstVarRef(nodep->fileline(), varp,
|
||||
VAccess::READ); // lvalue'ness computed later
|
||||
refp->classOrPackagep(foundp->classOrPackagep());
|
||||
|
|
@ -2332,7 +2339,7 @@ private:
|
|||
m_ds.m_dotPos = DP_MEMBER;
|
||||
ok = true;
|
||||
}
|
||||
} else if (AstModport* modportp = VN_CAST(foundp->nodep(), Modport)) {
|
||||
} else if (const AstModport* const modportp = VN_CAST(foundp->nodep(), Modport)) {
|
||||
// A scope reference into an interface's modport (not
|
||||
// necessarily at a pin connection)
|
||||
UINFO(9, "cell-ref-to-modport " << m_ds.m_dotText << " " << nodep << endl);
|
||||
|
|
@ -2349,14 +2356,16 @@ private:
|
|||
nodep->v3error("Modport not referenced from underneath an interface: "
|
||||
<< modportp->prettyNameQ());
|
||||
} else {
|
||||
AstCell* cellp = VN_AS(m_ds.m_dotSymp->nodep(), Cell);
|
||||
AstCell* const cellp = VN_AS(m_ds.m_dotSymp->nodep(), Cell);
|
||||
UASSERT_OBJ(cellp, nodep, "Modport not referenced from an instance");
|
||||
VSymEnt* cellEntp = m_statep->getNodeSym(cellp);
|
||||
VSymEnt* const cellEntp = m_statep->getNodeSym(cellp);
|
||||
UASSERT_OBJ(cellEntp, nodep, "No interface sym entry");
|
||||
VSymEnt* parentEntp = cellEntp->parentp(); // Container of the var; probably a
|
||||
// module or generate begin
|
||||
VSymEnt* const parentEntp
|
||||
= cellEntp->parentp(); // Container of the var; probably a
|
||||
// module or generate begin
|
||||
// We drop __BRA__??__KET__ as cells don't have that naming yet
|
||||
AstVar* ifaceRefVarp = findIfaceTopVarp(nodep, parentEntp, cellp->name());
|
||||
AstVar* const ifaceRefVarp
|
||||
= findIfaceTopVarp(nodep, parentEntp, cellp->name());
|
||||
//
|
||||
ok = true;
|
||||
m_ds.m_dotText = VString::dot(m_ds.m_dotText, ".", nodep->name());
|
||||
|
|
@ -2365,7 +2374,7 @@ private:
|
|||
UINFO(9, " cell -> iface varref " << foundp->nodep() << endl);
|
||||
AstNode* newp
|
||||
= new AstVarRef(ifaceRefVarp->fileline(), ifaceRefVarp, VAccess::READ);
|
||||
auto* cellarrayrefp = VN_CAST(m_ds.m_unlinkedScopep, CellArrayRef);
|
||||
auto* const cellarrayrefp = VN_CAST(m_ds.m_unlinkedScopep, CellArrayRef);
|
||||
if (cellarrayrefp) {
|
||||
// iface[vec].modport became CellArrayRef(iface, lsb)
|
||||
// Convert back to SelBit(iface, lsb)
|
||||
|
|
@ -2379,18 +2388,20 @@ private:
|
|||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
} else if (AstEnumItem* valuep = VN_CAST(foundp->nodep(), EnumItem)) {
|
||||
} else if (AstEnumItem* const valuep = VN_CAST(foundp->nodep(), EnumItem)) {
|
||||
if (allowVar) {
|
||||
AstNode* newp
|
||||
AstNode* const newp
|
||||
= new AstEnumItemRef(nodep->fileline(), valuep, foundp->classOrPackagep());
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
ok = true;
|
||||
m_ds.m_dotText = "";
|
||||
}
|
||||
} else if (AstLambdaArgRef* argrefp = VN_CAST(foundp->nodep(), LambdaArgRef)) {
|
||||
} else if (const AstLambdaArgRef* const argrefp
|
||||
= VN_CAST(foundp->nodep(), LambdaArgRef)) {
|
||||
if (allowVar) {
|
||||
AstNode* newp = new AstLambdaArgRef(nodep->fileline(), argrefp->name(), false);
|
||||
AstNode* const newp
|
||||
= new AstLambdaArgRef(nodep->fileline(), argrefp->name(), false);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
ok = true;
|
||||
|
|
@ -2433,7 +2444,7 @@ private:
|
|||
if (checkImplicit) {
|
||||
// Create if implicit, and also if error (so only complain once)
|
||||
// Else if a scope is allowed, making a signal won't help error cascade
|
||||
AstVarRef* newp
|
||||
AstVarRef* const newp
|
||||
= new AstVarRef(nodep->fileline(), nodep->name(), VAccess::READ);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
|
|
@ -2452,8 +2463,9 @@ private:
|
|||
if (!nodep->varp()) {
|
||||
UINFO(9, " linkVarRef se" << cvtToHex(m_curSymp) << " n=" << nodep << endl);
|
||||
UASSERT_OBJ(m_curSymp, nodep, "nullptr lookup symbol table");
|
||||
VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name());
|
||||
if (AstVar* varp = foundp ? foundToVarp(foundp, nodep, nodep->access()) : nullptr) {
|
||||
VSymEnt* const foundp = m_curSymp->findIdFallback(nodep->name());
|
||||
if (AstVar* const varp
|
||||
= foundp ? foundToVarp(foundp, nodep, nodep->access()) : nullptr) {
|
||||
nodep->varp(varp);
|
||||
// Generally set by parse, but might be an import
|
||||
nodep->classOrPackagep(foundp->classOrPackagep());
|
||||
|
|
@ -2493,8 +2505,9 @@ private:
|
|||
dotSymp = m_statep->findDotted(nodep->fileline(), dotSymp, nodep->dotted(), baddot,
|
||||
okSymp); // Maybe nullptr
|
||||
if (!m_statep->forScopeCreation()) {
|
||||
VSymEnt* foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot);
|
||||
AstVar* varp = foundp ? foundToVarp(foundp, nodep, nodep->access()) : nullptr;
|
||||
VSymEnt* const foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot);
|
||||
AstVar* const varp
|
||||
= foundp ? foundToVarp(foundp, nodep, nodep->access()) : nullptr;
|
||||
nodep->varp(varp);
|
||||
UINFO(7, " Resolved " << nodep << endl); // Also prints varp
|
||||
if (!nodep->varp()) {
|
||||
|
|
@ -2509,14 +2522,14 @@ private:
|
|||
// this and convert to normal VarRefs
|
||||
if (!m_statep->forPrearray() && !m_statep->forScopeCreation()) {
|
||||
if (VN_IS(nodep->dtypep(), IfaceRefDType)) {
|
||||
AstVarRef* newrefp
|
||||
AstVarRef* const newrefp
|
||||
= new AstVarRef(nodep->fileline(), nodep->varp(), nodep->access());
|
||||
nodep->replaceWith(newrefp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
VSymEnt* foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot);
|
||||
VSymEnt* const foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot);
|
||||
AstVarScope* vscp = foundp ? VN_AS(foundp->nodep(), VarScope) : nullptr;
|
||||
if (!vscp) {
|
||||
nodep->v3error("Can't find varpin scope of "
|
||||
|
|
@ -2534,7 +2547,8 @@ private:
|
|||
nodep->varp(vscp->varp());
|
||||
nodep->varScopep(vscp);
|
||||
UINFO(7, " Resolved " << nodep << endl); // Also prints taskp
|
||||
AstVarRef* newvscp = new AstVarRef(nodep->fileline(), vscp, nodep->access());
|
||||
AstVarRef* const newvscp
|
||||
= new AstVarRef(nodep->fileline(), vscp, nodep->access());
|
||||
nodep->replaceWith(newvscp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
UINFO(9, " new " << newvscp << endl); // Also prints taskp
|
||||
|
|
@ -2544,7 +2558,7 @@ private:
|
|||
}
|
||||
virtual void visit(AstEnumDType* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
AstRefDType* refdtypep = VN_CAST(nodep->subDTypep(), RefDType);
|
||||
AstRefDType* const refdtypep = VN_CAST(nodep->subDTypep(), RefDType);
|
||||
if (refdtypep && (nodep == refdtypep->subDTypep())) {
|
||||
refdtypep->v3error("Self-referential enumerated type definition");
|
||||
}
|
||||
|
|
@ -2576,7 +2590,8 @@ private:
|
|||
if (m_ds.m_dotp && m_ds.m_dotPos == DP_PACKAGE) {
|
||||
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), ClassOrPackageRef), m_ds.m_dotp->lhsp(),
|
||||
"Bad package link");
|
||||
AstClassOrPackageRef* cpackagerefp = VN_AS(m_ds.m_dotp->lhsp(), ClassOrPackageRef);
|
||||
AstClassOrPackageRef* const cpackagerefp
|
||||
= VN_AS(m_ds.m_dotp->lhsp(), ClassOrPackageRef);
|
||||
if (cpackagerefp->name() == "process" || cpackagerefp->name() == "local") {
|
||||
nodep->v3warn(E_UNSUPPORTED,
|
||||
"Unsupported: " << AstNode::prettyNameQ(cpackagerefp->name()));
|
||||
|
|
@ -2587,10 +2602,11 @@ private:
|
|||
m_ds.m_dotp = nullptr;
|
||||
} else if (m_ds.m_dotp && m_ds.m_dotPos == DP_FINAL) {
|
||||
if (m_ds.m_unresolved && m_ds.m_unlinkedScopep) {
|
||||
AstNodeFTaskRef* newftaskp = nodep->cloneTree(false);
|
||||
AstNodeFTaskRef* const newftaskp = nodep->cloneTree(false);
|
||||
newftaskp->dotted(m_ds.m_dotText);
|
||||
AstNode* newp = new AstUnlinkedRef(nodep->fileline(), newftaskp, nodep->name(),
|
||||
m_ds.m_unlinkedScopep->unlinkFrBack());
|
||||
AstNode* const newp
|
||||
= new AstUnlinkedRef(nodep->fileline(), newftaskp, nodep->name(),
|
||||
m_ds.m_unlinkedScopep->unlinkFrBack());
|
||||
m_ds.m_unlinkedScopep = nullptr;
|
||||
m_ds.m_unresolved = false;
|
||||
nodep->replaceWith(newp);
|
||||
|
|
@ -2601,11 +2617,11 @@ private:
|
|||
} else if (m_ds.m_dotp && m_ds.m_dotPos == DP_MEMBER) {
|
||||
// Found a Var, everything following is method call.
|
||||
// {scope}.{var}.HERE {method} ( ARGS )
|
||||
AstNode* varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack();
|
||||
AstNode* const varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack();
|
||||
AstNode* argsp = nullptr;
|
||||
if (nodep->pinsp()) argsp = nodep->pinsp()->unlinkFrBackWithNext();
|
||||
AstNode* newp = new AstMethodCall(nodep->fileline(), varEtcp, VFlagChildDType(),
|
||||
nodep->name(), argsp);
|
||||
AstNode* const newp = new AstMethodCall(nodep->fileline(), varEtcp, VFlagChildDType(),
|
||||
nodep->name(), argsp);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
return;
|
||||
|
|
@ -2653,8 +2669,8 @@ private:
|
|||
dotSymp = m_statep->findDotted(nodep->fileline(), dotSymp, nodep->dotted(), baddot,
|
||||
okSymp); // Maybe nullptr
|
||||
}
|
||||
VSymEnt* foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot);
|
||||
AstNodeFTask* taskp
|
||||
VSymEnt* const foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot);
|
||||
AstNodeFTask* const taskp
|
||||
= foundp ? VN_CAST(foundp->nodep(), NodeFTask) : nullptr; // Maybe nullptr
|
||||
if (taskp) {
|
||||
nodep->taskp(taskp);
|
||||
|
|
@ -2688,9 +2704,9 @@ private:
|
|||
} else {
|
||||
AstNode* outp = nullptr;
|
||||
while (nodep->pinsp()) {
|
||||
AstNode* pinp = nodep->pinsp()->unlinkFrBack();
|
||||
AstNode* const pinp = nodep->pinsp()->unlinkFrBack();
|
||||
AstNode* addp = pinp;
|
||||
if (AstArg* argp = VN_CAST(pinp, Arg)) {
|
||||
if (AstArg* const argp = VN_CAST(pinp, Arg)) {
|
||||
addp = argp->exprp()->unlinkFrBack();
|
||||
VL_DO_DANGLING(pinp->deleteTree(), pinp);
|
||||
}
|
||||
|
|
@ -2751,8 +2767,8 @@ private:
|
|||
}
|
||||
}
|
||||
if (m_ds.m_unresolved && m_ds.m_dotPos == DP_SCOPE) {
|
||||
AstNode* exprp = nodep->bitp()->unlinkFrBack();
|
||||
AstCellArrayRef* newp
|
||||
AstNode* const exprp = nodep->bitp()->unlinkFrBack();
|
||||
AstCellArrayRef* const newp
|
||||
= new AstCellArrayRef(nodep->fileline(), nodep->fromp()->name(), exprp);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
|
|
@ -2784,7 +2800,7 @@ private:
|
|||
virtual void visit(AstNodeBlock* nodep) override {
|
||||
UINFO(5, " " << nodep << endl);
|
||||
checkNoDot(nodep);
|
||||
VSymEnt* oldCurSymp = m_curSymp;
|
||||
VSymEnt* const oldCurSymp = m_curSymp;
|
||||
{
|
||||
if (nodep->name() != "") {
|
||||
m_ds.m_dotSymp = m_curSymp = m_statep->getNodeSym(nodep);
|
||||
|
|
@ -2808,7 +2824,7 @@ private:
|
|||
nodep->v3error("definition not found for extern " + nodep->prettyNameQ());
|
||||
}
|
||||
}
|
||||
VSymEnt* oldCurSymp = m_curSymp;
|
||||
VSymEnt* const oldCurSymp = m_curSymp;
|
||||
{
|
||||
m_ftaskp = nodep;
|
||||
m_ds.m_dotSymp = m_curSymp = m_statep->getNodeSym(nodep);
|
||||
|
|
@ -2820,7 +2836,7 @@ private:
|
|||
virtual void visit(AstWith* nodep) override {
|
||||
UINFO(5, " " << nodep << endl);
|
||||
checkNoDot(nodep);
|
||||
VSymEnt* oldCurSymp = m_curSymp;
|
||||
VSymEnt* const oldCurSymp = m_curSymp;
|
||||
{
|
||||
m_ds.m_dotSymp = m_curSymp = m_statep->getNodeSym(nodep);
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -2843,19 +2859,19 @@ private:
|
|||
m_ds.m_dotSymp = m_curSymp = m_modSymp = m_statep->getNodeSym(nodep);
|
||||
m_modp = nodep;
|
||||
for (AstNode* itemp = nodep->extendsp(); itemp; itemp = itemp->nextp()) {
|
||||
if (AstClassExtends* cextp = VN_CAST(itemp, ClassExtends)) {
|
||||
if (AstClassExtends* const cextp = VN_CAST(itemp, ClassExtends)) {
|
||||
// Replace abstract reference with hard pointer
|
||||
// Will need later resolution when deal with parameters
|
||||
if (cextp->childDTypep() || cextp->dtypep()) continue; // Already converted
|
||||
AstClassOrPackageRef* cpackagerefp
|
||||
AstClassOrPackageRef* const cpackagerefp
|
||||
= VN_CAST(cextp->classOrPkgsp(), ClassOrPackageRef);
|
||||
if (!cpackagerefp) {
|
||||
cextp->v3error("Attempting to extend using a non-class ");
|
||||
} else {
|
||||
VSymEnt* foundp = m_curSymp->findIdFallback(cpackagerefp->name());
|
||||
VSymEnt* const foundp = m_curSymp->findIdFallback(cpackagerefp->name());
|
||||
bool ok = false;
|
||||
if (foundp) {
|
||||
if (AstClass* classp = VN_CAST(foundp->nodep(), Class)) {
|
||||
if (AstClass* const classp = VN_CAST(foundp->nodep(), Class)) {
|
||||
UINFO(8, "Import to " << nodep << " from export class " << classp
|
||||
<< endl);
|
||||
if (classp == nodep) {
|
||||
|
|
@ -2869,7 +2885,7 @@ private:
|
|||
cextp->childDTypep(newp);
|
||||
classp->isExtended(true);
|
||||
nodep->isExtended(true);
|
||||
VSymEnt* srcp = m_statep->getNodeSym(classp);
|
||||
VSymEnt* const srcp = m_statep->getNodeSym(classp);
|
||||
m_curSymp->importFromClass(m_statep->symsp(), srcp);
|
||||
VL_DO_DANGLING(cpackagerefp->unlinkFrBack()->deleteTree(),
|
||||
cpackagerefp);
|
||||
|
|
@ -2895,11 +2911,11 @@ private:
|
|||
{
|
||||
nodep->repairCache();
|
||||
for (VSymEnt::const_iterator it = m_curSymp->begin(); it != m_curSymp->end(); ++it) {
|
||||
AstNode* itemp = it->second->nodep();
|
||||
AstNode* const itemp = it->second->nodep();
|
||||
if (!nodep->findMember(it->first)) {
|
||||
if (AstEnumItem* aitemp = VN_CAST(itemp, EnumItem)) {
|
||||
AstEnumItemRef* newp = new AstEnumItemRef(aitemp->fileline(), aitemp,
|
||||
it->second->classOrPackagep());
|
||||
if (AstEnumItem* const aitemp = VN_CAST(itemp, EnumItem)) {
|
||||
AstEnumItemRef* const newp = new AstEnumItemRef(
|
||||
aitemp->fileline(), aitemp, it->second->classOrPackagep());
|
||||
UINFO(8, "Class import noderef '" << it->first << "' " << newp << endl);
|
||||
nodep->addMembersp(newp);
|
||||
}
|
||||
|
|
@ -2910,8 +2926,8 @@ private:
|
|||
virtual void visit(AstRefDType* nodep) override {
|
||||
// Resolve its reference
|
||||
if (nodep->user3SetOnce()) return;
|
||||
if (AstNode* cpackagep = nodep->classOrPackageOpp()) {
|
||||
if (AstClassOrPackageRef* cpackagerefp = VN_CAST(cpackagep, ClassOrPackageRef)) {
|
||||
if (AstNode* const cpackagep = nodep->classOrPackageOpp()) {
|
||||
if (AstClassOrPackageRef* const cpackagerefp = VN_CAST(cpackagep, ClassOrPackageRef)) {
|
||||
nodep->classOrPackagep(cpackagerefp->classOrPackagep());
|
||||
if (!VN_IS(nodep->classOrPackagep(), Class)
|
||||
&& !VN_IS(nodep->classOrPackagep(), Package)) {
|
||||
|
|
@ -2931,7 +2947,7 @@ private:
|
|||
if (m_ds.m_dotp && m_ds.m_dotPos == DP_PACKAGE) {
|
||||
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), ClassOrPackageRef), m_ds.m_dotp->lhsp(),
|
||||
"Bad package link");
|
||||
auto* cpackagerefp = VN_AS(m_ds.m_dotp->lhsp(), ClassOrPackageRef);
|
||||
auto* const cpackagerefp = VN_AS(m_ds.m_dotp->lhsp(), ClassOrPackageRef);
|
||||
UASSERT_OBJ(cpackagerefp->classOrPackagep(), m_ds.m_dotp->lhsp(), "Bad package link");
|
||||
nodep->classOrPackagep(cpackagerefp->classOrPackagep());
|
||||
m_ds.m_dotPos = DP_SCOPE;
|
||||
|
|
@ -2941,16 +2957,16 @@ private:
|
|||
}
|
||||
if (nodep->typeofp()) { // Really is a typeof not a reference
|
||||
} else if (!nodep->typedefp() && !nodep->subDTypep()) {
|
||||
VSymEnt* foundp;
|
||||
const VSymEnt* foundp;
|
||||
if (nodep->classOrPackagep()) {
|
||||
foundp = m_statep->getNodeSym(nodep->classOrPackagep())->findIdFlat(nodep->name());
|
||||
} else {
|
||||
foundp = m_curSymp->findIdFallback(nodep->name());
|
||||
}
|
||||
if (AstTypedef* defp = foundp ? VN_CAST(foundp->nodep(), Typedef) : nullptr) {
|
||||
if (AstTypedef* const defp = foundp ? VN_CAST(foundp->nodep(), Typedef) : nullptr) {
|
||||
nodep->typedefp(defp);
|
||||
nodep->classOrPackagep(foundp->classOrPackagep());
|
||||
} else if (AstParamTypeDType* defp
|
||||
} else if (AstParamTypeDType* const defp
|
||||
= foundp ? VN_CAST(foundp->nodep(), ParamTypeDType) : nullptr) {
|
||||
if (defp == nodep->backp()) { // Where backp is typically typedef
|
||||
nodep->v3error("Reference to '" << m_ds.m_dotText
|
||||
|
|
@ -2962,10 +2978,11 @@ private:
|
|||
nodep->refDTypep(defp);
|
||||
nodep->classOrPackagep(foundp->classOrPackagep());
|
||||
}
|
||||
} else if (AstClass* defp = foundp ? VN_AS(foundp->nodep(), Class) : nullptr) {
|
||||
AstNode* paramsp = nodep->paramsp();
|
||||
} else if (AstClass* const defp = foundp ? VN_AS(foundp->nodep(), Class) : nullptr) {
|
||||
AstNode* const paramsp = nodep->paramsp();
|
||||
if (paramsp) paramsp->unlinkFrBackWithNext();
|
||||
AstClassRefDType* newp = new AstClassRefDType{nodep->fileline(), defp, paramsp};
|
||||
AstClassRefDType* const newp
|
||||
= new AstClassRefDType{nodep->fileline(), defp, paramsp};
|
||||
newp->classOrPackagep(foundp->classOrPackagep());
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
|
|
@ -2981,8 +2998,8 @@ private:
|
|||
// AstDpiExport: Make sure the function referenced exists, then dump it
|
||||
iterateChildren(nodep);
|
||||
checkNoDot(nodep);
|
||||
VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name());
|
||||
AstNodeFTask* taskp = foundp ? VN_AS(foundp->nodep(), NodeFTask) : nullptr;
|
||||
VSymEnt* const foundp = m_curSymp->findIdFallback(nodep->name());
|
||||
AstNodeFTask* const taskp = foundp ? VN_AS(foundp->nodep(), NodeFTask) : nullptr;
|
||||
if (!taskp) {
|
||||
nodep->v3error(
|
||||
"Can't find definition of exported task/function: " << nodep->prettyNameQ());
|
||||
|
|
@ -3048,13 +3065,13 @@ void V3LinkDot::linkDotGuts(AstNetlist* rootp, VLinkDotStep step) {
|
|||
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot.tree"));
|
||||
}
|
||||
LinkDotState state(rootp, step);
|
||||
LinkDotFindVisitor visitor{rootp, &state};
|
||||
const LinkDotFindVisitor visitor{rootp, &state};
|
||||
if (LinkDotState::debug() >= 5 || v3Global.opt.dumpTree() >= 9) {
|
||||
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-find.tree"));
|
||||
}
|
||||
if (step == LDS_PRIMARY || step == LDS_PARAMED) {
|
||||
// Initial link stage, resolve parameters
|
||||
LinkDotParamVisitor visitors{rootp, &state};
|
||||
const LinkDotParamVisitor visitors{rootp, &state};
|
||||
if (LinkDotState::debug() >= 5 || v3Global.opt.dumpTree() >= 9) {
|
||||
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-param.tree"));
|
||||
}
|
||||
|
|
@ -3062,7 +3079,7 @@ void V3LinkDot::linkDotGuts(AstNetlist* rootp, VLinkDotStep step) {
|
|||
} else if (step == LDS_SCOPED) {
|
||||
// Well after the initial link when we're ready to operate on the flat design,
|
||||
// process AstScope's. This needs to be separate pass after whole hierarchy graph created.
|
||||
LinkDotScopeVisitor visitors{rootp, &state};
|
||||
const LinkDotScopeVisitor visitors{rootp, &state};
|
||||
v3Global.assertScoped(true);
|
||||
if (LinkDotState::debug() >= 5 || v3Global.opt.dumpTree() >= 9) {
|
||||
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-scoped.tree"));
|
||||
|
|
|
|||
|
|
@ -259,7 +259,7 @@ private:
|
|||
// if (debug() >= 9) { UINFO(0, "\n"); blockp->dumpTree(cout, " labeli: "); }
|
||||
if (!blockp) {
|
||||
nodep->v3error("disable isn't underneath a begin with name: " << nodep->prettyNameQ());
|
||||
} else if (AstBegin* beginp = VN_CAST(blockp, Begin)) {
|
||||
} else if (AstBegin* const beginp = VN_CAST(blockp, Begin)) {
|
||||
// Jump to the end of the named block
|
||||
AstJumpLabel* const labelp = findAddLabel(beginp, false);
|
||||
nodep->addNextHere(new AstJumpGo(nodep->fileline(), labelp));
|
||||
|
|
|
|||
|
|
@ -142,13 +142,13 @@ void V3LinkLevel::timescaling(const ModVec& mods) {
|
|||
void V3LinkLevel::wrapTop(AstNetlist* rootp) {
|
||||
UINFO(2, __FUNCTION__ << ": " << endl);
|
||||
// We do ONLY the top module
|
||||
AstNodeModule* oldmodp = rootp->modulesp();
|
||||
AstNodeModule* const oldmodp = rootp->modulesp();
|
||||
if (!oldmodp) { // Later V3LinkDot will warn
|
||||
UINFO(1, "No module found to wrap\n");
|
||||
return;
|
||||
}
|
||||
|
||||
AstNodeModule* newmodp = new AstModule(oldmodp->fileline(), "$root");
|
||||
AstNodeModule* const newmodp = new AstModule(oldmodp->fileline(), "$root");
|
||||
newmodp->name(AstNode::encodeName(newmodp->name())); // so origName is nice
|
||||
// Make the new module first in the list
|
||||
oldmodp->unlinkFrBackWithNext();
|
||||
|
|
@ -167,10 +167,11 @@ void V3LinkLevel::wrapTop(AstNetlist* rootp) {
|
|||
// This way all later SCOPE based optimizations can ignore packages
|
||||
for (AstNodeModule* modp = rootp->modulesp(); modp; modp = VN_AS(modp->nextp(), NodeModule)) {
|
||||
if (VN_IS(modp, Package)) {
|
||||
AstCell* cellp = new AstCell(modp->fileline(), modp->fileline(),
|
||||
// Could add __03a__03a="::" to prevent conflict
|
||||
// with module names/"v"
|
||||
modp->name(), modp->name(), nullptr, nullptr, nullptr);
|
||||
AstCell* const cellp
|
||||
= new AstCell(modp->fileline(), modp->fileline(),
|
||||
// Could add __03a__03a="::" to prevent conflict
|
||||
// with module names/"v"
|
||||
modp->name(), modp->name(), nullptr, nullptr, nullptr);
|
||||
cellp->modp(modp);
|
||||
newmodp->addStmtp(cellp);
|
||||
}
|
||||
|
|
@ -180,7 +181,7 @@ void V3LinkLevel::wrapTop(AstNetlist* rootp) {
|
|||
}
|
||||
|
||||
void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
|
||||
AstNodeModule* newmodp = rootp->modulesp();
|
||||
AstNodeModule* const newmodp = rootp->modulesp();
|
||||
UASSERT_OBJ(newmodp && newmodp->isTop(), rootp, "No TOP module found to insert under");
|
||||
|
||||
// Find all duplicate signal names (if multitop)
|
||||
|
|
@ -191,7 +192,7 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
|
|||
for (AstNodeModule* oldmodp = VN_AS(rootp->modulesp()->nextp(), NodeModule);
|
||||
oldmodp && oldmodp->level() <= 2; oldmodp = VN_AS(oldmodp->nextp(), NodeModule)) {
|
||||
for (AstNode* subnodep = oldmodp->stmtsp(); subnodep; subnodep = subnodep->nextp()) {
|
||||
if (AstVar* oldvarp = VN_CAST(subnodep, Var)) {
|
||||
if (AstVar* const oldvarp = VN_CAST(subnodep, Var)) {
|
||||
if (oldvarp->isIO()) {
|
||||
if (ioNames.find(oldvarp->name()) != ioNames.end()) {
|
||||
// UINFO(8, "Multitop dup I/O found: " << oldvarp << endl);
|
||||
|
|
@ -210,7 +211,7 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
|
|||
if (VN_IS(oldmodp, Package)) continue;
|
||||
// Add instance
|
||||
UINFO(5, "LOOP " << oldmodp << endl);
|
||||
AstCell* cellp = new AstCell(
|
||||
AstCell* const cellp = new AstCell(
|
||||
newmodp->fileline(), newmodp->fileline(),
|
||||
(!v3Global.opt.l2Name().empty() ? v3Global.opt.l2Name() : oldmodp->name()),
|
||||
oldmodp->name(), nullptr, nullptr, nullptr);
|
||||
|
|
@ -219,7 +220,7 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
|
|||
|
||||
// Add pins
|
||||
for (AstNode* subnodep = oldmodp->stmtsp(); subnodep; subnodep = subnodep->nextp()) {
|
||||
if (AstVar* oldvarp = VN_CAST(subnodep, Var)) {
|
||||
if (AstVar* const oldvarp = VN_CAST(subnodep, Var)) {
|
||||
UINFO(8, "VARWRAP " << oldvarp << endl);
|
||||
if (oldvarp->isIO()) {
|
||||
string name = oldvarp->name();
|
||||
|
|
@ -228,7 +229,7 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
|
|||
name = oldmodp->name() + "__02E" + name;
|
||||
}
|
||||
|
||||
AstVar* varp = oldvarp->cloneTree(false);
|
||||
AstVar* const varp = oldvarp->cloneTree(false);
|
||||
varp->name(name);
|
||||
varp->protect(false);
|
||||
newmodp->addStmtp(varp);
|
||||
|
|
@ -249,7 +250,7 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
|
|||
varp->trace(false);
|
||||
}
|
||||
|
||||
AstPin* pinp = new AstPin(
|
||||
AstPin* const pinp = new AstPin(
|
||||
oldvarp->fileline(), 0, varp->name(),
|
||||
new AstVarRef(varp->fileline(), varp,
|
||||
oldvarp->isWritable() ? VAccess::WRITE : VAccess::READ));
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ private:
|
|||
nodep->fileline(), nodep->valuep()->cloneTree(true),
|
||||
new AstConst(nodep->fileline(), AstConst::Unsized32(), offset_from_init));
|
||||
}
|
||||
AstNode* newp = new AstEnumItem(nodep->fileline(), name, nullptr, valuep);
|
||||
AstNode* const newp = new AstEnumItem(nodep->fileline(), name, nullptr, valuep);
|
||||
if (addp) {
|
||||
addp = addp->addNextNull(newp);
|
||||
} else {
|
||||
|
|
@ -212,15 +212,15 @@ private:
|
|||
}
|
||||
if (VN_IS(nodep->subDTypep(), ParseTypeDType)) {
|
||||
// It's a parameter type. Use a different node type for this.
|
||||
AstNodeDType* dtypep = VN_CAST(nodep->valuep(), NodeDType);
|
||||
AstNodeDType* const dtypep = VN_CAST(nodep->valuep(), NodeDType);
|
||||
if (!dtypep) {
|
||||
nodep->v3error(
|
||||
"Parameter type's initial value isn't a type: " << nodep->prettyNameQ());
|
||||
nodep->unlinkFrBack();
|
||||
} else {
|
||||
dtypep->unlinkFrBack();
|
||||
AstNode* newp = new AstParamTypeDType(nodep->fileline(), nodep->varType(),
|
||||
nodep->name(), VFlagChildDType(), dtypep);
|
||||
AstNode* const newp = new AstParamTypeDType(
|
||||
nodep->fileline(), nodep->varType(), nodep->name(), VFlagChildDType(), dtypep);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
|
|
@ -256,7 +256,7 @@ private:
|
|||
if (m_inAlways) nodep->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true);
|
||||
if (nodep->valuep()) {
|
||||
// A variable with an = value can be three things:
|
||||
FileLine* fl = nodep->valuep()->fileline();
|
||||
FileLine* const fl = nodep->valuep()->fileline();
|
||||
if (nodep->isParam() || (m_ftaskp && nodep->isNonOutput())) {
|
||||
// 1. Parameters and function inputs: It's a default to use if not overridden
|
||||
} else if (!m_ftaskp && !VN_IS(m_modp, Class) && nodep->isNonOutput()) {
|
||||
|
|
@ -267,9 +267,9 @@ private:
|
|||
// AstInitial
|
||||
else if (m_valueModp) {
|
||||
// Making an AstAssign (vs AstAssignW) to a wire is an error, suppress it
|
||||
FileLine* newfl = new FileLine(fl);
|
||||
FileLine* const newfl = new FileLine(fl);
|
||||
newfl->warnOff(V3ErrorCode::PROCASSWIRE, true);
|
||||
auto* assp
|
||||
auto* const assp
|
||||
= new AstAssign(newfl, new AstVarRef(newfl, nodep->name(), VAccess::WRITE),
|
||||
nodep->valuep()->unlinkFrBack());
|
||||
nodep->addNextHere(new AstInitial(newfl, assp));
|
||||
|
|
@ -295,7 +295,7 @@ private:
|
|||
cleanFileline(nodep);
|
||||
iterateChildren(nodep);
|
||||
if (nodep->attrType() == AstAttrType::DT_PUBLIC) {
|
||||
AstTypedef* typep = VN_AS(nodep->backp(), Typedef);
|
||||
AstTypedef* const typep = VN_AS(nodep->backp(), Typedef);
|
||||
UASSERT_OBJ(typep, nodep, "Attribute not attached to typedef");
|
||||
typep->attrPublic(true);
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
|
|
@ -379,7 +379,7 @@ private:
|
|||
// Unique name space under each containerp() so that an addition of
|
||||
// a new type won't change every verilated module.
|
||||
AstTypedef* defp = nullptr;
|
||||
ImplTypedefMap::iterator it
|
||||
const ImplTypedefMap::iterator it
|
||||
= m_implTypedef.find(std::make_pair(nodep->containerp(), nodep->name()));
|
||||
if (it != m_implTypedef.end()) {
|
||||
defp = it->second;
|
||||
|
|
@ -392,7 +392,7 @@ private:
|
|||
}
|
||||
UASSERT_OBJ(backp, nodep,
|
||||
"Implicit enum/struct type created under unexpected node type");
|
||||
AstNodeDType* dtypep = nodep->childDTypep();
|
||||
AstNodeDType* const dtypep = nodep->childDTypep();
|
||||
dtypep->unlinkFrBack();
|
||||
if (VN_IS(backp, Typedef)) {
|
||||
// A typedef doesn't need us to make yet another level of typedefing
|
||||
|
|
@ -435,11 +435,11 @@ private:
|
|||
AstNode* bracketp = nodep->arrayp();
|
||||
AstNode* firstVarsp = nullptr;
|
||||
while (AstDot* dotp = VN_CAST(bracketp, Dot)) { bracketp = dotp->rhsp(); }
|
||||
if (AstSelBit* selp = VN_CAST(bracketp, SelBit)) {
|
||||
if (AstSelBit* const selp = VN_CAST(bracketp, SelBit)) {
|
||||
firstVarsp = selp->rhsp()->unlinkFrBackWithNext();
|
||||
selp->replaceWith(selp->fromp()->unlinkFrBack());
|
||||
VL_DO_DANGLING(selp->deleteTree(), selp);
|
||||
} else if (AstSelLoopVars* selp = VN_CAST(bracketp, SelLoopVars)) {
|
||||
} else if (AstSelLoopVars* const selp = VN_CAST(bracketp, SelLoopVars)) {
|
||||
firstVarsp = selp->elementsp()->unlinkFrBackWithNext();
|
||||
selp->replaceWith(selp->fromp()->unlinkFrBack());
|
||||
VL_DO_DANGLING(selp->deleteTree(), selp);
|
||||
|
|
@ -449,7 +449,7 @@ private:
|
|||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
return;
|
||||
}
|
||||
AstNode* arrayp = nodep->arrayp(); // Maybe different node since bracketp looked
|
||||
AstNode* const arrayp = nodep->arrayp(); // Maybe different node since bracketp looked
|
||||
if (!VN_IS(arrayp, ParseRef) && !VN_IS(arrayp, Dot)) {
|
||||
// Code below needs to use other then attributes to figure out the bounds
|
||||
// Also need to deal with queues, etc
|
||||
|
|
@ -467,26 +467,27 @@ private:
|
|||
}
|
||||
for (AstNode* varsp = lastVarsp; varsp; varsp = varsp->backp()) {
|
||||
UINFO(9, "foreachVar " << varsp << endl);
|
||||
FileLine* fl = varsp->fileline();
|
||||
AstNode* varp
|
||||
FileLine* const fl = varsp->fileline();
|
||||
AstNode* const varp
|
||||
= new AstVar(fl, AstVarType::BLOCKTEMP, varsp->name(), nodep->findSigned32DType());
|
||||
// These will be the left and right dimensions and size of the array:
|
||||
AstNode* leftp = new AstAttrOf(fl, AstAttrType::DIM_LEFT, arrayp->cloneTree(false),
|
||||
new AstConst(fl, dimension));
|
||||
AstNode* rightp = new AstAttrOf(fl, AstAttrType::DIM_RIGHT, arrayp->cloneTree(false),
|
||||
new AstConst(fl, dimension));
|
||||
AstNode* sizep = new AstAttrOf(fl, AstAttrType::DIM_SIZE, arrayp->cloneTree(false),
|
||||
new AstConst(fl, dimension));
|
||||
AstNode* stmtsp = varp;
|
||||
AstNode* const leftp = new AstAttrOf(
|
||||
fl, AstAttrType::DIM_LEFT, arrayp->cloneTree(false), new AstConst(fl, dimension));
|
||||
AstNode* const rightp = new AstAttrOf(
|
||||
fl, AstAttrType::DIM_RIGHT, arrayp->cloneTree(false), new AstConst(fl, dimension));
|
||||
AstNode* const sizep = new AstAttrOf(
|
||||
fl, AstAttrType::DIM_SIZE, arrayp->cloneTree(false), new AstConst(fl, dimension));
|
||||
AstNode* const stmtsp = varp;
|
||||
// Assign left-dimension into the loop var:
|
||||
stmtsp->addNext(
|
||||
new AstAssign(fl, new AstVarRef(fl, varp->name(), VAccess::WRITE), leftp));
|
||||
// This will turn into a constant bool for static arrays
|
||||
AstNode* notemptyp = new AstGt(fl, sizep, new AstConst(fl, 0));
|
||||
AstNode* const notemptyp = new AstGt(fl, sizep, new AstConst(fl, 0));
|
||||
// This will turn into a bool constant, indicating whether
|
||||
// we count the loop variable up or down:
|
||||
AstNode* countupp = new AstLte(fl, leftp->cloneTree(true), rightp->cloneTree(true));
|
||||
AstNode* comparep = new AstCond(
|
||||
AstNode* const countupp
|
||||
= new AstLte(fl, leftp->cloneTree(true), rightp->cloneTree(true));
|
||||
AstNode* const comparep = new AstCond(
|
||||
fl, countupp->cloneTree(true),
|
||||
// Left increments up to right
|
||||
new AstLte(fl, new AstVarRef(fl, varp->name(), VAccess::READ),
|
||||
|
|
@ -494,8 +495,8 @@ private:
|
|||
// Left decrements down to right
|
||||
new AstGte(fl, new AstVarRef(fl, varp->name(), VAccess::READ), rightp));
|
||||
// This will reduce to comparep for static arrays
|
||||
AstNode* condp = new AstAnd(fl, notemptyp, comparep);
|
||||
AstNode* incp = new AstAssign(
|
||||
AstNode* const condp = new AstAnd(fl, notemptyp, comparep);
|
||||
AstNode* const incp = new AstAssign(
|
||||
fl, new AstVarRef(fl, varp->name(), VAccess::WRITE),
|
||||
new AstAdd(fl, new AstVarRef(fl, varp->name(), VAccess::READ),
|
||||
new AstCond(fl, countupp, new AstConst(fl, 1), new AstConst(fl, -1))));
|
||||
|
|
@ -590,7 +591,7 @@ private:
|
|||
}
|
||||
virtual void visit(AstGenIf* nodep) override {
|
||||
cleanFileline(nodep);
|
||||
bool nestedIf
|
||||
const bool nestedIf
|
||||
= (VN_IS(nodep->backp(), Begin) && nestedIfBegin(VN_CAST(nodep->backp(), Begin)));
|
||||
if (nestedIf) {
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -638,7 +639,7 @@ private:
|
|||
virtual void visit(AstTimingControl* nodep) override {
|
||||
cleanFileline(nodep);
|
||||
iterateChildren(nodep);
|
||||
AstAlways* alwaysp = VN_CAST(nodep->backp(), Always);
|
||||
AstAlways* const alwaysp = VN_CAST(nodep->backp(), Always);
|
||||
if (alwaysp && alwaysp->keyword() == VAlwaysKwd::ALWAYS_COMB) {
|
||||
alwaysp->v3error("Timing control statements not legal under always_comb "
|
||||
"(IEEE 1800-2017 9.2.2.2.2)\n"
|
||||
|
|
@ -648,7 +649,7 @@ private:
|
|||
// Verilator is still ony supporting SenTrees under an always,
|
||||
// so allow the parser to handle everything and shim to
|
||||
// historical AST here
|
||||
if (AstSenTree* sensesp = nodep->sensesp()) {
|
||||
if (AstSenTree* const sensesp = nodep->sensesp()) {
|
||||
sensesp->unlinkFrBackWithNext();
|
||||
alwaysp->sensesp(sensesp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -225,17 +225,17 @@ private:
|
|||
= VN_CAST(basefromp, NodeVarRef)) { // Maybe varxref - so need to clone
|
||||
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE,
|
||||
varrefp->cloneTree(false)));
|
||||
} else if (AstUnlinkedRef* uvxrp
|
||||
} else if (AstUnlinkedRef* const uvxrp
|
||||
= VN_CAST(basefromp, UnlinkedRef)) { // Maybe unlinked - so need to clone
|
||||
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE,
|
||||
uvxrp->cloneTree(false)));
|
||||
} else if (auto* fromp = VN_CAST(basefromp, LambdaArgRef)) {
|
||||
} else if (auto* const fromp = VN_CAST(basefromp, LambdaArgRef)) {
|
||||
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE,
|
||||
fromp->cloneTree(false)));
|
||||
} else if (AstMemberSel* fromp = VN_CAST(basefromp, MemberSel)) {
|
||||
} else if (AstMemberSel* const fromp = VN_CAST(basefromp, MemberSel)) {
|
||||
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::MEMBER_BASE,
|
||||
fromp->cloneTree(false)));
|
||||
} else if (AstEnumItemRef* fromp = VN_CAST(basefromp, EnumItemRef)) {
|
||||
} else if (AstEnumItemRef* const fromp = VN_CAST(basefromp, EnumItemRef)) {
|
||||
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::ENUM_BASE,
|
||||
fromp->cloneTree(false)));
|
||||
} else if (VN_IS(basefromp, Replicate)) {
|
||||
|
|
@ -364,7 +364,7 @@ private:
|
|||
bool inpercent = false;
|
||||
for (int i = 0; i < numchars; i++) {
|
||||
const int ii = numchars - i - 1;
|
||||
char c = constp->num().dataByte(ii);
|
||||
const char c = constp->num().dataByte(ii);
|
||||
str[i] = c;
|
||||
if (!inpercent && c == '%') {
|
||||
inpercent = true;
|
||||
|
|
@ -584,7 +584,7 @@ public:
|
|||
void V3LinkResolve::linkResolve(AstNetlist* rootp) {
|
||||
UINFO(4, __FUNCTION__ << ": " << endl);
|
||||
{
|
||||
LinkResolveVisitor visitor{rootp};
|
||||
const LinkResolveVisitor visitor{rootp};
|
||||
LinkBotupVisitor{rootp};
|
||||
} // Destruct before checking
|
||||
V3Global::dumpCheckGlobalTree("linkresolve", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ private:
|
|||
|
||||
AstNode* m_mgFirstp = nullptr; // First node in merged sequence
|
||||
AstNode* m_mgCondp = nullptr; // The condition of the first node
|
||||
AstNode* m_mgLastp = nullptr; // Last node in merged sequence
|
||||
const AstNode* m_mgLastp = nullptr; // Last node in merged sequence
|
||||
const AstNode* m_mgNextp = nullptr; // Next node in list being examined
|
||||
uint32_t m_listLenght = 0; // Length of current list
|
||||
|
||||
|
|
@ -158,7 +158,7 @@ private:
|
|||
static AstNodeCond* extractCond(AstNode* rhsp) {
|
||||
if (AstNodeCond* const condp = VN_CAST(rhsp, NodeCond)) {
|
||||
return condp;
|
||||
} else if (AstAnd* const andp = VN_CAST(rhsp, And)) {
|
||||
} else if (const AstAnd* const andp = VN_CAST(rhsp, And)) {
|
||||
if (AstNodeCond* const condp = VN_CAST(andp->rhsp(), NodeCond)) {
|
||||
if (VN_IS(andp->lhsp(), Const)) return condp;
|
||||
}
|
||||
|
|
@ -173,7 +173,7 @@ private:
|
|||
return constp->num().toUQuad() <= 1;
|
||||
}
|
||||
if (const AstVarRef* const vrefp = VN_CAST(nodep, VarRef)) {
|
||||
AstVar* const varp = vrefp->varp();
|
||||
const AstVar* const varp = vrefp->varp();
|
||||
return varp->widthMin() == 1 && !varp->dtypep()->isSigned();
|
||||
}
|
||||
if (const AstShiftR* const shiftp = VN_CAST(nodep, ShiftR)) {
|
||||
|
|
@ -225,17 +225,17 @@ private:
|
|||
AstNode* foldAndUnlink(AstNode* rhsp, bool condTrue) {
|
||||
if (rhsp->sameTree(m_mgCondp)) {
|
||||
return new AstConst(rhsp->fileline(), AstConst::BitTrue{}, condTrue);
|
||||
} else if (AstNodeCond* const condp = extractCond(rhsp)) {
|
||||
} else if (const AstNodeCond* const condp = extractCond(rhsp)) {
|
||||
AstNode* const resp
|
||||
= condTrue ? condp->expr1p()->unlinkFrBack() : condp->expr2p()->unlinkFrBack();
|
||||
if (condp == rhsp) { //
|
||||
return resp;
|
||||
}
|
||||
if (AstAnd* const andp = VN_CAST(rhsp, And)) {
|
||||
if (const AstAnd* const andp = VN_CAST(rhsp, And)) {
|
||||
UASSERT_OBJ(andp->rhsp() == condp, rhsp, "Should not try to fold this");
|
||||
return new AstAnd{andp->fileline(), andp->lhsp()->cloneTree(false), resp};
|
||||
}
|
||||
} else if (AstAnd* const andp = VN_CAST(rhsp, And)) {
|
||||
} else if (const AstAnd* const andp = VN_CAST(rhsp, And)) {
|
||||
if (andp->lhsp()->sameTree(m_mgCondp)) {
|
||||
return condTrue ? maskLsb(andp->rhsp()->unlinkFrBack())
|
||||
: new AstConst{rhsp->fileline(), AstConst::BitFalse()};
|
||||
|
|
@ -255,11 +255,11 @@ private:
|
|||
void mergeEnd(int lineno) {
|
||||
UASSERT(m_mgFirstp, "mergeEnd without list " << lineno);
|
||||
// We might want to recursively merge an AstIf. We stash it in this variable.
|
||||
AstNodeIf* recursivep = nullptr;
|
||||
const AstNodeIf* recursivep = nullptr;
|
||||
// Drop leading cheap nodes. These were only added in the hope of finding
|
||||
// an earlier reduced form, but we failed to do so.
|
||||
while (m_mgFirstp->user2() && m_mgFirstp != m_mgLastp) {
|
||||
AstNode* const backp = m_mgFirstp;
|
||||
const AstNode* const backp = m_mgFirstp;
|
||||
m_mgFirstp = m_mgFirstp->nextp();
|
||||
--m_listLenght;
|
||||
UASSERT_OBJ(m_mgFirstp && m_mgFirstp->backp() == backp, m_mgLastp,
|
||||
|
|
@ -268,7 +268,7 @@ private:
|
|||
// Drop trailing cheap nodes. These were only added in the hope of finding
|
||||
// a later conditional to merge, but we failed to do so.
|
||||
while (m_mgLastp->user2() && m_mgFirstp != m_mgLastp) {
|
||||
AstNode* const nextp = m_mgLastp;
|
||||
const AstNode* const nextp = m_mgLastp;
|
||||
m_mgLastp = m_mgLastp->backp();
|
||||
--m_listLenght;
|
||||
UASSERT_OBJ(m_mgLastp && m_mgLastp->nextp() == nextp, m_mgFirstp,
|
||||
|
|
@ -328,7 +328,7 @@ private:
|
|||
} while (nextp);
|
||||
// Recursively merge the resulting AstIf
|
||||
recursivep = resultp;
|
||||
} else if (AstNodeIf* const ifp = VN_CAST(m_mgFirstp, NodeIf)) {
|
||||
} else if (const AstNodeIf* const ifp = VN_CAST(m_mgFirstp, NodeIf)) {
|
||||
// There was nothing to merge this AstNodeIf with, but try to merge it's branches
|
||||
recursivep = ifp;
|
||||
}
|
||||
|
|
@ -353,11 +353,11 @@ private:
|
|||
// Check if the node can be simplified if included under the if
|
||||
bool isSimplifiableNode(AstNode* nodep) {
|
||||
UASSERT_OBJ(m_mgFirstp, nodep, "Cannot check with empty list");
|
||||
if (AstNodeAssign* const assignp = VN_CAST(nodep, NodeAssign)) {
|
||||
if (const AstNodeAssign* const assignp = VN_CAST(nodep, NodeAssign)) {
|
||||
// If it's an assignment to a 1-bit signal, try reduced forms
|
||||
if (assignp->lhsp()->widthMin() == 1) {
|
||||
// Is it a 'lhs = cond & value' or 'lhs = value & cond'?
|
||||
if (AstAnd* const andp = VN_CAST(assignp->rhsp(), And)) {
|
||||
if (const AstAnd* const andp = VN_CAST(assignp->rhsp(), And)) {
|
||||
if (andp->lhsp()->sameTree(m_mgCondp) || andp->rhsp()->sameTree(m_mgCondp)) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -373,7 +373,7 @@ private:
|
|||
// AstIf and is hence not likely to cause a performance degradation if doing so.
|
||||
bool isCheapNode(AstNode* nodep) const {
|
||||
if (VN_IS(nodep, Comment)) return true;
|
||||
if (AstNodeAssign* const assignp = VN_CAST(nodep, NodeAssign)) {
|
||||
if (const AstNodeAssign* const assignp = VN_CAST(nodep, NodeAssign)) {
|
||||
// Check LHS
|
||||
AstNode* lhsp = assignp->lhsp();
|
||||
while (AstWordSel* const wselp = VN_CAST(lhsp, WordSel)) {
|
||||
|
|
@ -479,7 +479,7 @@ private:
|
|||
// VISITORS
|
||||
virtual void visit(AstNodeAssign* nodep) override {
|
||||
AstNode* const rhsp = nodep->rhsp();
|
||||
if (AstNodeCond* const condp = extractCond(rhsp)) {
|
||||
if (const AstNodeCond* const condp = extractCond(rhsp)) {
|
||||
// Check if mergeable
|
||||
if (!checkOrMakeMergeable(nodep)) return;
|
||||
// Close potentially incompatible pending merge
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ private:
|
|||
const AstUser1InUse m_inuser1;
|
||||
|
||||
// STATE
|
||||
AstNodeModule* m_modp = nullptr;
|
||||
const AstNodeModule* m_modp = nullptr;
|
||||
|
||||
// METHODS
|
||||
VL_DEBUG_FUNC; // Declare debug()
|
||||
|
|
|
|||
|
|
@ -220,8 +220,8 @@ void V3Number::V3NumberCreate(AstNode* nodep, const char* sourcep, FileLine* fl)
|
|||
// this = (this * 10)/*product*/ + (*cp-'0')/*addend*/
|
||||
// Assumed rare; lots of optimizations are possible here
|
||||
V3Number product(this, width() + 4); // +4 for overflow detection
|
||||
V3Number ten(this, width() + 4, 10);
|
||||
V3Number addend(this, width(), (*cp - '0'));
|
||||
const V3Number ten(this, width() + 4, 10);
|
||||
const V3Number addend(this, width(), (*cp - '0'));
|
||||
product.opMul(*this, ten);
|
||||
this->opAdd(product, addend);
|
||||
if (product.bitsValue(width(), 4)) { // Overflowed
|
||||
|
|
@ -623,7 +623,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const {
|
|||
str += 'Z';
|
||||
continue;
|
||||
}
|
||||
int v = bitsValue(bit - 2, 3);
|
||||
const int v = bitsValue(bit - 2, 3);
|
||||
str += static_cast<char>('0' + v);
|
||||
}
|
||||
return str;
|
||||
|
|
@ -653,7 +653,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const {
|
|||
str += 'Z';
|
||||
continue;
|
||||
}
|
||||
int v = bitsValue(bit - 3, 4);
|
||||
const int v = bitsValue(bit - 3, 4);
|
||||
if (v >= 10) {
|
||||
str += static_cast<char>('a' + v - 10);
|
||||
} else {
|
||||
|
|
@ -664,7 +664,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const {
|
|||
}
|
||||
case 'c': {
|
||||
if (width() > 8) fl->v3warn(WIDTH, "$display-like format of %c format of > 8 bit value");
|
||||
unsigned int v = bitsValue(0, 8);
|
||||
const unsigned int v = bitsValue(0, 8);
|
||||
char strc[2];
|
||||
strc[0] = v & 0xff;
|
||||
strc[1] = '\0';
|
||||
|
|
@ -677,7 +677,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const {
|
|||
bool start = true;
|
||||
while ((bit % 8) != 7) bit++;
|
||||
for (; bit >= 0; bit -= 8) {
|
||||
int v = bitsValue(bit - 7, 8);
|
||||
const int v = bitsValue(bit - 7, 8);
|
||||
if (!start || v) {
|
||||
str += static_cast<char>((v == 0) ? ' ' : v);
|
||||
start = false; // Drop leading 0s
|
||||
|
|
@ -880,9 +880,9 @@ double V3Number::toDouble() const {
|
|||
|
||||
vlsint32_t V3Number::toSInt() const {
|
||||
if (isSigned()) {
|
||||
uint32_t v = toUInt();
|
||||
uint32_t signExtend = (-(v & (1UL << (width() - 1))));
|
||||
uint32_t extended = v | signExtend;
|
||||
const uint32_t v = toUInt();
|
||||
const uint32_t signExtend = (-(v & (1UL << (width() - 1))));
|
||||
const uint32_t extended = v | signExtend;
|
||||
return static_cast<vlsint32_t>(extended);
|
||||
} else {
|
||||
// Where we use this (widths, etc) and care about signedness,
|
||||
|
|
@ -908,9 +908,9 @@ vluint64_t V3Number::toUQuad() const {
|
|||
|
||||
vlsint64_t V3Number::toSQuad() const {
|
||||
if (isDouble()) return static_cast<vlsint64_t>(toDouble());
|
||||
vluint64_t v = toUQuad();
|
||||
vluint64_t signExtend = (-(v & (1ULL << (width() - 1))));
|
||||
vluint64_t extended = v | signExtend;
|
||||
const vluint64_t v = toUQuad();
|
||||
const vluint64_t signExtend = (-(v & (1ULL << (width() - 1))));
|
||||
const vluint64_t extended = v | signExtend;
|
||||
return static_cast<vlsint64_t>(extended);
|
||||
}
|
||||
|
||||
|
|
@ -923,7 +923,7 @@ string V3Number::toString() const {
|
|||
while ((bit % 8) != 7) bit++;
|
||||
string str;
|
||||
for (; bit >= 0; bit -= 8) {
|
||||
int v = bitsValue(bit - 7, 8);
|
||||
const int v = bitsValue(bit - 7, 8);
|
||||
if (!start || v) {
|
||||
str += static_cast<char>((v == 0) ? ' ' : v);
|
||||
start = false; // Drop leading 0s
|
||||
|
|
@ -1745,7 +1745,7 @@ V3Number& V3Number::opShiftR(const V3Number& lhs, const V3Number& rhs) {
|
|||
for (int bit = 32; bit < rhs.width(); bit++) {
|
||||
if (rhs.bitIs1(bit)) return *this; // shift of over 2^32 must be zero
|
||||
}
|
||||
uint32_t rhsval = rhs.toUInt();
|
||||
const uint32_t rhsval = rhs.toUInt();
|
||||
if (rhsval < static_cast<uint32_t>(lhs.width())) {
|
||||
for (int bit = 0; bit < this->width(); bit++) setBit(bit, lhs.bitIs(bit + rhsval));
|
||||
}
|
||||
|
|
@ -1767,7 +1767,7 @@ V3Number& V3Number::opShiftRS(const V3Number& lhs, const V3Number& rhs, uint32_t
|
|||
if (rhs.bitIs1(lbits - 1)) setAllBits1(); // -1 else 0
|
||||
return *this; // shift of over 2^32 must be -1/0
|
||||
}
|
||||
uint32_t rhsval = rhs.toUInt();
|
||||
const uint32_t rhsval = rhs.toUInt();
|
||||
if (rhsval < static_cast<uint32_t>(lhs.width())) {
|
||||
for (int bit = 0; bit < this->width(); bit++) {
|
||||
setBit(bit, lhs.bitIsExtend(bit + rhsval, lbits));
|
||||
|
|
@ -1789,7 +1789,7 @@ V3Number& V3Number::opShiftL(const V3Number& lhs, const V3Number& rhs) {
|
|||
for (int bit = 32; bit < rhs.width(); bit++) {
|
||||
if (rhs.bitIs1(bit)) return *this; // shift of over 2^32 must be zero
|
||||
}
|
||||
uint32_t rhsval = rhs.toUInt();
|
||||
const uint32_t rhsval = rhs.toUInt();
|
||||
for (int bit = 0; bit < this->width(); bit++) {
|
||||
if (bit >= static_cast<int>(rhsval)) setBit(bit, lhs.bitIs(bit - rhsval));
|
||||
}
|
||||
|
|
@ -1806,7 +1806,7 @@ V3Number& V3Number::opNegate(const V3Number& lhs) {
|
|||
if (lhs.isFourState()) return setAllBitsX();
|
||||
V3Number notlhs(&lhs, width());
|
||||
notlhs.opNot(lhs);
|
||||
V3Number one(&lhs, width(), 1);
|
||||
const V3Number one(&lhs, width(), 1);
|
||||
opAdd(notlhs, one);
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -1872,7 +1872,7 @@ V3Number& V3Number::opMulS(const V3Number& lhs, const V3Number& rhs) {
|
|||
if (lhs.isNegative()) lhsNoSign.opNegate(lhs);
|
||||
V3Number rhsNoSign = rhs;
|
||||
if (rhs.isNegative()) rhsNoSign.opNegate(rhs);
|
||||
V3Number qNoSign = opMul(lhsNoSign, rhsNoSign);
|
||||
const V3Number qNoSign = opMul(lhsNoSign, rhsNoSign);
|
||||
if ((lhs.isNegative() && !rhs.isNegative()) || (!lhs.isNegative() && rhs.isNegative())) {
|
||||
opNegate(qNoSign);
|
||||
} else {
|
||||
|
|
@ -1906,7 +1906,7 @@ V3Number& V3Number::opDivS(const V3Number& lhs, const V3Number& rhs) {
|
|||
if (lhs.isNegative()) lhsNoSign.opNegate(lhs);
|
||||
V3Number rhsNoSign = rhs;
|
||||
if (rhs.isNegative()) rhsNoSign.opNegate(rhs);
|
||||
V3Number qNoSign = opDiv(lhsNoSign, rhsNoSign);
|
||||
const V3Number qNoSign = opDiv(lhsNoSign, rhsNoSign);
|
||||
// UINFO(9, " >divs-mid "<<lhs<<" "<<rhs<<" "<<qNoSign<<endl);
|
||||
if ((lhs.isNegative() && !rhs.isNegative()) || (!lhs.isNegative() && rhs.isNegative())) {
|
||||
opNegate(qNoSign);
|
||||
|
|
@ -1940,7 +1940,7 @@ V3Number& V3Number::opModDivS(const V3Number& lhs, const V3Number& rhs) {
|
|||
if (lhs.isNegative()) lhsNoSign.opNegate(lhs);
|
||||
V3Number rhsNoSign = rhs;
|
||||
if (rhs.isNegative()) rhsNoSign.opNegate(rhs);
|
||||
V3Number qNoSign = opModDiv(lhsNoSign, rhsNoSign);
|
||||
const V3Number qNoSign = opModDiv(lhsNoSign, rhsNoSign);
|
||||
if (lhs.isNegative()) { // Just lhs' sign (*DIFFERENT FROM PERL, which uses rhs sign*)
|
||||
opNegate(qNoSign);
|
||||
} else {
|
||||
|
|
@ -1956,8 +1956,8 @@ V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool
|
|||
setZero();
|
||||
// Find MSB and check for zero.
|
||||
const int words = lhs.words();
|
||||
int umsbp1 = lhs.mostSetBitP1(); // dividend
|
||||
int vmsbp1 = rhs.mostSetBitP1(); // divisor
|
||||
const int umsbp1 = lhs.mostSetBitP1(); // dividend
|
||||
const int vmsbp1 = rhs.mostSetBitP1(); // divisor
|
||||
if (VL_UNLIKELY(vmsbp1 == 0) // rwp==0 so division by zero. Return 0.
|
||||
|| VL_UNLIKELY(umsbp1 == 0)) { // 0/x so short circuit and return 0
|
||||
UINFO(9, " opmoddiv-zero " << lhs << " " << rhs << " now=" << *this << endl);
|
||||
|
|
@ -1970,7 +1970,8 @@ V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool
|
|||
if (vw == 1) { // Single divisor word breaks rest of algorithm
|
||||
vluint64_t k = 0;
|
||||
for (int j = uw - 1; j >= 0; j--) {
|
||||
vluint64_t unw64 = ((k << 32ULL) + static_cast<vluint64_t>(lhs.m_value[j].m_value));
|
||||
const vluint64_t unw64
|
||||
= ((k << 32ULL) + static_cast<vluint64_t>(lhs.m_value[j].m_value));
|
||||
m_value[j].m_value = unw64 / static_cast<vluint64_t>(rhs.m_value[0].m_value);
|
||||
k = unw64
|
||||
- (static_cast<vluint64_t>(m_value[j].m_value)
|
||||
|
|
@ -1996,8 +1997,8 @@ V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool
|
|||
|
||||
// Algorithm requires divisor MSB to be set
|
||||
// Copy and shift to normalize divisor so MSB of vn[vw-1] is set
|
||||
int s = 31 - ((vmsbp1 - 1) & 31); // shift amount (0...31)
|
||||
uint32_t shift_mask = s ? 0xffffffff : 0; // otherwise >> 32 won't mask the value
|
||||
const int s = 31 - ((vmsbp1 - 1) & 31); // shift amount (0...31)
|
||||
const uint32_t shift_mask = s ? 0xffffffff : 0; // otherwise >> 32 won't mask the value
|
||||
for (int i = vw - 1; i > 0; i--) {
|
||||
vn[i] = (rhs.m_value[i].m_value << s)
|
||||
| (shift_mask & (rhs.m_value[i - 1].m_value >> (32 - s)));
|
||||
|
|
@ -2023,8 +2024,8 @@ V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool
|
|||
// Main loop
|
||||
for (int j = uw - vw; j >= 0; j--) {
|
||||
// Estimate
|
||||
vluint64_t unw64 = (static_cast<vluint64_t>(un[j + vw]) << 32ULL
|
||||
| static_cast<vluint64_t>(un[j + vw - 1]));
|
||||
const vluint64_t unw64 = (static_cast<vluint64_t>(un[j + vw]) << 32ULL
|
||||
| static_cast<vluint64_t>(un[j + vw - 1]));
|
||||
vluint64_t qhat = unw64 / static_cast<vluint64_t>(vn[vw - 1]);
|
||||
vluint64_t rhat = unw64 - qhat * static_cast<vluint64_t>(vn[vw - 1]);
|
||||
|
||||
|
|
@ -2038,7 +2039,7 @@ V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool
|
|||
vlsint64_t t = 0; // Must be signed
|
||||
vluint64_t k = 0;
|
||||
for (int i = 0; i < vw; i++) {
|
||||
vluint64_t p = qhat * vn[i]; // Multiply by estimate
|
||||
const vluint64_t p = qhat * vn[i]; // Multiply by estimate
|
||||
t = un[i + j] - k - (p & 0xFFFFFFFFULL); // Subtract
|
||||
un[i + j] = t;
|
||||
k = (p >> 32ULL) - (t >> 32ULL);
|
||||
|
|
@ -2192,8 +2193,8 @@ void V3Number::opCleanThis(bool warnOnTruncation) {
|
|||
// Clean MSB of number
|
||||
NUM_ASSERT_LOGIC_ARGS1(*this);
|
||||
const ValueAndX v = m_value[words() - 1];
|
||||
uint32_t newValueMsb = v.m_value & hiWordMask();
|
||||
uint32_t newValueXMsb = v.m_valueX & hiWordMask();
|
||||
const uint32_t newValueMsb = v.m_value & hiWordMask();
|
||||
const uint32_t newValueXMsb = v.m_valueX & hiWordMask();
|
||||
if (warnOnTruncation && (newValueMsb != v.m_value || newValueXMsb != v.m_valueX)) {
|
||||
// Displaying in decimal avoids hiWordMask truncation
|
||||
v3warn(WIDTH, "Value too large for " << width() << " bit number: " << displayed("%d"));
|
||||
|
|
@ -2258,7 +2259,7 @@ V3Number& V3Number::opIToRD(const V3Number& lhs, bool isSigned) {
|
|||
double d = 0;
|
||||
const bool negate = isSigned && noxz.isNegative();
|
||||
if (negate) {
|
||||
V3Number noxz_signed = noxz;
|
||||
const V3Number noxz_signed = noxz;
|
||||
noxz.opNegate(noxz_signed);
|
||||
}
|
||||
for (int bit = noxz.width() - 1; bit >= 0; bit--) {
|
||||
|
|
@ -2271,14 +2272,14 @@ V3Number& V3Number::opIToRD(const V3Number& lhs, bool isSigned) {
|
|||
V3Number& V3Number::opRToIS(const V3Number& lhs) {
|
||||
NUM_ASSERT_OP_ARGS1(lhs);
|
||||
NUM_ASSERT_DOUBLE_ARGS1(lhs);
|
||||
double v = VL_TRUNC(lhs.toDouble());
|
||||
vlsint32_t i = static_cast<vlsint32_t>(v); // C converts from double to vlsint32
|
||||
const double v = VL_TRUNC(lhs.toDouble());
|
||||
const vlsint32_t i = static_cast<vlsint32_t>(v); // C converts from double to vlsint32
|
||||
return setLongS(i);
|
||||
}
|
||||
V3Number& V3Number::opRToIRoundS(const V3Number& lhs) {
|
||||
NUM_ASSERT_OP_ARGS1(lhs);
|
||||
NUM_ASSERT_DOUBLE_ARGS1(lhs);
|
||||
double v = VL_ROUND(lhs.toDouble());
|
||||
const double v = VL_ROUND(lhs.toDouble());
|
||||
setZero();
|
||||
union {
|
||||
double d;
|
||||
|
|
@ -2289,7 +2290,7 @@ V3Number& V3Number::opRToIRoundS(const V3Number& lhs) {
|
|||
|
||||
const int exp = static_cast<int>((u.q >> 52ULL) & VL_MASK_Q(11)) - 1023;
|
||||
const int lsb = exp - 52;
|
||||
vluint64_t mantissa = (u.q & VL_MASK_Q(52)) | (1ULL << 52);
|
||||
const vluint64_t mantissa = (u.q & VL_MASK_Q(52)) | (1ULL << 52);
|
||||
if (v != 0) {
|
||||
// IEEE format: [63]=sign [62:52]=exp+1023 [51:0]=mantissa
|
||||
// This does not need to support subnormals as they are sub-integral
|
||||
|
|
@ -2300,7 +2301,7 @@ V3Number& V3Number::opRToIRoundS(const V3Number& lhs) {
|
|||
}
|
||||
}
|
||||
if (v < 0) {
|
||||
V3Number noSign = *this;
|
||||
const V3Number noSign = *this;
|
||||
opNegate(noSign);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ public:
|
|||
V3Number& setDouble(double value);
|
||||
void setBit(int bit, char value) { // Note must be pre-zeroed!
|
||||
if (bit >= m_width) return;
|
||||
uint32_t mask = (1UL << (bit & 31));
|
||||
const uint32_t mask = (1UL << (bit & 31));
|
||||
ValueAndX& v = m_value[bit / 32];
|
||||
if (value == '0' || value == 0) {
|
||||
v.m_value &= ~mask;
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ int V3OptionParser::parse(int idx, int argc, char* argv[]) {
|
|||
UASSERT(m_pimpl->m_isFinalized, "finalize() must be called before parse()");
|
||||
const char* optp = argv[idx];
|
||||
if (optp[0] == '-' && optp[1] == '-') ++optp;
|
||||
ActionIfs* actp = find(optp);
|
||||
ActionIfs* const actp = find(optp);
|
||||
if (!actp) return 0;
|
||||
if (!actp->isValueNeeded()) {
|
||||
actp->exec(optp, nullptr);
|
||||
|
|
@ -224,7 +224,7 @@ V3OptionParser::ActionIfs&
|
|||
V3OptionParser::AppendHelper::operator()(const char* optp, CbPartialMatchVal,
|
||||
Impl::ActionCbPartialMatchVal::CbType cb) const {
|
||||
const size_t prefixLen = std::strlen(optp);
|
||||
auto wrap
|
||||
const auto wrap
|
||||
= [prefixLen, cb](const char* optp, const char* argp) { cb(optp + prefixLen, argp); };
|
||||
return m_parser.add<Impl::ActionCbPartialMatchVal>(optp, std::move(wrap));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ public:
|
|||
|
||||
private:
|
||||
// MEMBERS
|
||||
std::unique_ptr<Impl> m_pimpl;
|
||||
const std::unique_ptr<Impl> m_pimpl;
|
||||
|
||||
// METHODS
|
||||
ActionIfs* find(const char* optp);
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ public:
|
|||
V3LangCode::V3LangCode(const char* textp) {
|
||||
// Return code for given string, or ERROR, which is a bad code
|
||||
for (int codei = V3LangCode::L_ERROR; codei < V3LangCode::_ENUM_END; ++codei) {
|
||||
V3LangCode code = V3LangCode(codei);
|
||||
const V3LangCode code = V3LangCode(codei);
|
||||
if (0 == VL_STRCASECMP(textp, code.ascii())) {
|
||||
m_e = code;
|
||||
return;
|
||||
|
|
@ -128,7 +128,7 @@ VTimescale::VTimescale(const string& value, bool& badr)
|
|||
badr = true;
|
||||
const string spaceless = VString::removeWhitespace(value);
|
||||
for (int i = TS_100S; i < _ENUM_END; ++i) {
|
||||
VTimescale ts(i);
|
||||
const VTimescale ts(i);
|
||||
if (spaceless == ts.ascii()) {
|
||||
badr = false;
|
||||
m_e = ts.m_e;
|
||||
|
|
@ -236,7 +236,7 @@ void VTimescale::parseSlashed(FileLine* fl, const char* textp, VTimescale& unitr
|
|||
for (; isspace(*cp); ++cp) {}
|
||||
const char* const unitp = cp;
|
||||
for (; *cp && *cp != '/'; ++cp) {}
|
||||
string unitStr(unitp, cp - unitp);
|
||||
const string unitStr(unitp, cp - unitp);
|
||||
for (; isspace(*cp); ++cp) {}
|
||||
string precStr;
|
||||
if (*cp == '/') {
|
||||
|
|
@ -253,7 +253,7 @@ void VTimescale::parseSlashed(FileLine* fl, const char* textp, VTimescale& unitr
|
|||
}
|
||||
|
||||
bool unitbad;
|
||||
VTimescale unit(unitStr, unitbad /*ref*/);
|
||||
const VTimescale unit(unitStr, unitbad /*ref*/);
|
||||
if (unitbad && !(unitStr.empty() && allowEmpty)) {
|
||||
fl->v3error("`timescale timeunit syntax error: '" << unitStr << "'");
|
||||
return;
|
||||
|
|
@ -471,7 +471,7 @@ string V3Options::fileExists(const string& filename) {
|
|||
}
|
||||
}
|
||||
// Find it
|
||||
std::set<string>* filesetp = &(diriter->second);
|
||||
const std::set<string>* filesetp = &(diriter->second);
|
||||
const auto fileiter = filesetp->find(basename);
|
||||
if (fileiter == filesetp->end()) {
|
||||
return ""; // Not found
|
||||
|
|
@ -894,7 +894,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
|||
}
|
||||
|
||||
V3OptionParser parser;
|
||||
V3OptionParser::AppendHelper DECL_OPTION{parser};
|
||||
const V3OptionParser::AppendHelper DECL_OPTION{parser};
|
||||
V3OPTION_PARSER_DECL_TAGS;
|
||||
|
||||
const auto callStrSetter = [this](void (V3Options::*cbStr)(const string&)) {
|
||||
|
|
@ -1086,7 +1086,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
|||
|
||||
DECL_OPTION("-hierarchical", OnOff, &m_hierarchical);
|
||||
DECL_OPTION("-hierarchical-block", CbVal, [this](const char* valp) {
|
||||
V3HierarchicalBlockOption opt(valp);
|
||||
const V3HierarchicalBlockOption opt(valp);
|
||||
m_hierBlocks.emplace(opt.mangledName(), opt);
|
||||
});
|
||||
DECL_OPTION("-hierarchical-child", OnOff, &m_hierChild);
|
||||
|
|
@ -1103,7 +1103,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
|||
|
||||
DECL_OPTION("-LDFLAGS", CbVal, callStrSetter(&V3Options::addLdLibs));
|
||||
const auto setLang = [this, fl](const char* valp) {
|
||||
V3LangCode optval = V3LangCode(valp);
|
||||
const V3LangCode optval = V3LangCode(valp);
|
||||
if (optval.legal()) {
|
||||
m_defaultLanguage = optval;
|
||||
} else {
|
||||
|
|
@ -1367,7 +1367,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
|||
FileLine::globalWarnStyleOff(false);
|
||||
});
|
||||
DECL_OPTION("-Werror-", CbPartialMatch, [this, fl](const char* optp) {
|
||||
V3ErrorCode code(optp);
|
||||
const V3ErrorCode code(optp);
|
||||
if (code == V3ErrorCode::EC_ERROR) {
|
||||
if (!isFuture(optp)) fl->v3fatal("Unknown warning specified: -Werror-" << optp);
|
||||
} else {
|
||||
|
|
|
|||
141
src/V3Order.cpp
141
src/V3Order.cpp
|
|
@ -179,11 +179,11 @@ static bool isClockerAssignment(AstNodeAssign* nodep) {
|
|||
|
||||
void OrderGraph::loopsVertexCb(V3GraphVertex* vertexp) {
|
||||
if (debug()) cout << "-Info-Loop: " << vertexp << "\n";
|
||||
if (OrderLogicVertex* vvertexp = dynamic_cast<OrderLogicVertex*>(vertexp)) {
|
||||
if (OrderLogicVertex* const vvertexp = dynamic_cast<OrderLogicVertex*>(vertexp)) {
|
||||
std::cerr << vvertexp->nodep()->fileline()->warnOther()
|
||||
<< " Example path: " << vvertexp->nodep()->typeName() << endl;
|
||||
}
|
||||
if (OrderVarVertex* vvertexp = dynamic_cast<OrderVarVertex*>(vertexp)) {
|
||||
if (OrderVarVertex* const vvertexp = dynamic_cast<OrderVarVertex*>(vertexp)) {
|
||||
std::cerr << vvertexp->varScp()->fileline()->warnOther()
|
||||
<< " Example path: " << vvertexp->varScp()->prettyName() << endl;
|
||||
}
|
||||
|
|
@ -229,7 +229,7 @@ class OrderClkMarkVisitor final : public AstNVisitor {
|
|||
return; // skip the marking
|
||||
}
|
||||
|
||||
const AstVarRef* lhsp = VN_CAST(nodep->lhsp(), VarRef);
|
||||
const AstVarRef* const lhsp = VN_CAST(nodep->lhsp(), VarRef);
|
||||
if (lhsp && (lhsp->varp()->attrClocker() == VVarAttrClocker::CLOCKER_UNKNOWN)) {
|
||||
lhsp->varp()->attrClocker(VVarAttrClocker::CLOCKER_YES); // mark as clocker
|
||||
m_newClkMarked = true; // enable a further run since new clocker is marked
|
||||
|
|
@ -724,7 +724,7 @@ class OrderBuildVisitor final : public AstNVisitor {
|
|||
for (AstVarScope* vscp = nodep->topScopep()->scopep()->varsp(); vscp;
|
||||
vscp = VN_AS(vscp->nextp(), VarScope)) {
|
||||
if (vscp->varp()->isNonOutput()) {
|
||||
OrderVarVertex* varVxp = getVarVertex(vscp, VarVertexType::STD);
|
||||
OrderVarVertex* const varVxp = getVarVertex(vscp, VarVertexType::STD);
|
||||
new OrderEdge(m_graphp, m_inputsVxp, varVxp, WEIGHT_INPUT);
|
||||
}
|
||||
}
|
||||
|
|
@ -753,8 +753,8 @@ public:
|
|||
V3List<OrderMoveVertex*> m_readyVertices; // Ready vertices with same domain & scope
|
||||
private:
|
||||
bool m_onReadyList = false; // True if DomScope is already on list of ready dom/scopes
|
||||
const AstSenTree* m_domainp; // Domain all vertices belong to
|
||||
const AstScope* m_scopep; // Scope all vertices belong to
|
||||
const AstSenTree* const m_domainp; // Domain all vertices belong to
|
||||
const AstScope* const m_scopep; // Scope all vertices belong to
|
||||
|
||||
using DomScopeKey = std::pair<const AstSenTree*, const AstScope*>;
|
||||
using DomScopeMap = std::map<DomScopeKey, OrderMoveDomScope*>;
|
||||
|
|
@ -840,7 +840,7 @@ private:
|
|||
// MEMBERS
|
||||
const V3Graph* m_graphp; // Input graph of OrderLogicVertex's etc
|
||||
V3Graph* m_outGraphp; // Output graph of T_MoveVertex's
|
||||
MoveVertexMaker* m_vxMakerp; // Factory class for T_MoveVertex's
|
||||
MoveVertexMaker* const m_vxMakerp; // Factory class for T_MoveVertex's
|
||||
Logic2Move m_logic2move; // Map Logic to Vertex
|
||||
// Maps an (original graph vertex, domain) pair to a T_MoveVertex
|
||||
// Not std::unordered_map, because std::pair doesn't provide std::hash
|
||||
|
|
@ -872,8 +872,8 @@ public:
|
|||
|
||||
// For each logic node, make a T_MoveVertex
|
||||
for (V3GraphVertex* itp = m_graphp->verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (OrderLogicVertex* lvertexp = dynamic_cast<OrderLogicVertex*>(itp)) {
|
||||
T_MoveVertex* moveVxp = m_vxMakerp->makeVertexp(
|
||||
if (OrderLogicVertex* const lvertexp = dynamic_cast<OrderLogicVertex*>(itp)) {
|
||||
T_MoveVertex* const moveVxp = m_vxMakerp->makeVertexp(
|
||||
lvertexp, nullptr, lvertexp->scopep(), lvertexp->domainp());
|
||||
if (moveVxp) {
|
||||
// Cross link so we can find it later
|
||||
|
|
@ -883,8 +883,8 @@ public:
|
|||
}
|
||||
// Build edges between logic vertices
|
||||
for (V3GraphVertex* itp = m_graphp->verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (OrderLogicVertex* lvertexp = dynamic_cast<OrderLogicVertex*>(itp)) {
|
||||
T_MoveVertex* moveVxp = m_logic2move[lvertexp];
|
||||
if (OrderLogicVertex* const lvertexp = dynamic_cast<OrderLogicVertex*>(itp)) {
|
||||
T_MoveVertex* const moveVxp = m_logic2move[lvertexp];
|
||||
if (moveVxp) iterate(moveVxp, lvertexp, lvertexp->domainp());
|
||||
}
|
||||
}
|
||||
|
|
@ -901,7 +901,7 @@ private:
|
|||
continue;
|
||||
}
|
||||
const int weight = edgep->weight();
|
||||
if (const OrderLogicVertex* toLVertexp
|
||||
if (const OrderLogicVertex* const toLVertexp
|
||||
= dynamic_cast<const OrderLogicVertex*>(edgep->top())) {
|
||||
|
||||
// Do not construct dependencies across exclusive domains.
|
||||
|
|
@ -916,11 +916,11 @@ private:
|
|||
// This is an OrderVarVertex or other vertex representing
|
||||
// data. (Could be var, settle, or input type vertex.)
|
||||
const V3GraphVertex* nonLogicVxp = edgep->top();
|
||||
VxDomPair key(nonLogicVxp, domainp);
|
||||
const VxDomPair key(nonLogicVxp, domainp);
|
||||
if (!m_var2move[key]) {
|
||||
const OrderEitherVertex* eithp
|
||||
const OrderEitherVertex* const eithp
|
||||
= dynamic_cast<const OrderEitherVertex*>(nonLogicVxp);
|
||||
T_MoveVertex* newMoveVxp
|
||||
T_MoveVertex* const newMoveVxp
|
||||
= m_vxMakerp->makeVertexp(nullptr, eithp, eithp->scopep(), domainp);
|
||||
m_var2move[key] = newMoveVxp;
|
||||
|
||||
|
|
@ -962,7 +962,7 @@ public:
|
|||
virtual OrderMoveVertex* makeVertexp(OrderLogicVertex* lvertexp, const OrderEitherVertex*,
|
||||
const AstScope* scopep,
|
||||
const AstSenTree* domainp) override {
|
||||
OrderMoveVertex* resultp = new OrderMoveVertex(m_pomGraphp, lvertexp);
|
||||
OrderMoveVertex* const resultp = new OrderMoveVertex(m_pomGraphp, lvertexp);
|
||||
resultp->domScopep(OrderMoveDomScope::findCreate(domainp, scopep));
|
||||
resultp->m_pomWaitingE.pushBack(*m_pomWaitingp, resultp);
|
||||
return resultp;
|
||||
|
|
@ -1005,8 +1005,8 @@ class OrderVerticesByDomainThenScope final {
|
|||
|
||||
public:
|
||||
virtual bool operator()(const V3GraphVertex* lhsp, const V3GraphVertex* rhsp) const {
|
||||
const MTaskMoveVertex* l_vxp = dynamic_cast<const MTaskMoveVertex*>(lhsp);
|
||||
const MTaskMoveVertex* r_vxp = dynamic_cast<const MTaskMoveVertex*>(rhsp);
|
||||
const MTaskMoveVertex* const l_vxp = dynamic_cast<const MTaskMoveVertex*>(lhsp);
|
||||
const MTaskMoveVertex* const r_vxp = dynamic_cast<const MTaskMoveVertex*>(rhsp);
|
||||
vluint64_t l_id = m_ids.findId(l_vxp->domainp());
|
||||
vluint64_t r_id = m_ids.findId(r_vxp->domainp());
|
||||
if (l_id < r_id) return true;
|
||||
|
|
@ -1025,8 +1025,8 @@ public:
|
|||
// Sort vertex's, which must be AbstractMTask's, into a deterministic
|
||||
// order by comparing their serial IDs.
|
||||
virtual bool operator()(const V3GraphVertex* lhsp, const V3GraphVertex* rhsp) const {
|
||||
const AbstractMTask* lmtaskp = dynamic_cast<const AbstractLogicMTask*>(lhsp);
|
||||
const AbstractMTask* rmtaskp = dynamic_cast<const AbstractLogicMTask*>(rhsp);
|
||||
const AbstractMTask* const lmtaskp = dynamic_cast<const AbstractLogicMTask*>(lhsp);
|
||||
const AbstractMTask* const rmtaskp = dynamic_cast<const AbstractLogicMTask*>(rhsp);
|
||||
return lmtaskp->id() < rmtaskp->id();
|
||||
}
|
||||
};
|
||||
|
|
@ -1119,8 +1119,8 @@ class OrderProcess final : AstNDeleter {
|
|||
AstVarScope* const nodep = vertexp->varScp();
|
||||
UASSERT(nodep != v3Global.rootp()->dpiExportTriggerp(),
|
||||
"DPI export trigger should not be marked circular");
|
||||
OrderLogicVertex* fromLVtxp = nullptr;
|
||||
OrderLogicVertex* toLVtxp = nullptr;
|
||||
const OrderLogicVertex* fromLVtxp = nullptr;
|
||||
const OrderLogicVertex* toLVtxp = nullptr;
|
||||
if (edgep) {
|
||||
fromLVtxp = dynamic_cast<OrderLogicVertex*>(edgep->fromp());
|
||||
toLVtxp = dynamic_cast<OrderLogicVertex*>(edgep->top());
|
||||
|
|
@ -1217,8 +1217,8 @@ class OrderProcess final : AstNDeleter {
|
|||
std::unordered_set<const AstVar*> canSplitList;
|
||||
int lim = m_unoptflatVars.size() < 10 ? m_unoptflatVars.size() : 10;
|
||||
for (int i = 0; i < lim; i++) {
|
||||
OrderVarStdVertex* vsvertexp = m_unoptflatVars[i];
|
||||
AstVar* varp = vsvertexp->varScp()->varp();
|
||||
OrderVarStdVertex* const vsvertexp = m_unoptflatVars[i];
|
||||
AstVar* const varp = vsvertexp->varScp()->varp();
|
||||
const bool canSplit = V3SplitVar::canSplitVar(varp);
|
||||
std::cerr << V3Error::warnMore() << " " << varp->fileline() << " "
|
||||
<< varp->prettyName() << std::dec << ", width " << varp->width()
|
||||
|
|
@ -1237,8 +1237,8 @@ class OrderProcess final : AstNDeleter {
|
|||
});
|
||||
lim = m_unoptflatVars.size() < 10 ? m_unoptflatVars.size() : 10;
|
||||
for (int i = 0; i < lim; i++) {
|
||||
OrderVarStdVertex* vsvertexp = m_unoptflatVars[i];
|
||||
AstVar* varp = vsvertexp->varScp()->varp();
|
||||
OrderVarStdVertex* const vsvertexp = m_unoptflatVars[i];
|
||||
AstVar* const varp = vsvertexp->varScp()->varp();
|
||||
const bool canSplit = V3SplitVar::canSplitVar(varp);
|
||||
std::cerr << V3Error::warnMore() << " " << varp->fileline() << " "
|
||||
<< varp->prettyName() << ", width " << std::dec << varp->width()
|
||||
|
|
@ -1261,9 +1261,9 @@ class OrderProcess final : AstNDeleter {
|
|||
void reportLoopVarsIterate(V3GraphVertex* vertexp, uint32_t color) {
|
||||
if (vertexp->user()) return; // Already done
|
||||
vertexp->user(1);
|
||||
if (OrderVarStdVertex* vsvertexp = dynamic_cast<OrderVarStdVertex*>(vertexp)) {
|
||||
if (OrderVarStdVertex* const vsvertexp = dynamic_cast<OrderVarStdVertex*>(vertexp)) {
|
||||
// Only reporting on standard variable vertices
|
||||
AstVar* varp = vsvertexp->varScp()->varp();
|
||||
AstVar* const varp = vsvertexp->varScp()->varp();
|
||||
if (!varp->user3()) {
|
||||
const string name = varp->prettyName();
|
||||
if ((varp->width() != 1) && (name.find("__Vdly") == string::npos)
|
||||
|
|
@ -1286,7 +1286,7 @@ class OrderProcess final : AstNDeleter {
|
|||
// Only for member initialization in constructor
|
||||
static OrderInputsVertex& findInputVertex(OrderGraph& graph) {
|
||||
for (V3GraphVertex* vtxp = graph.verticesBeginp(); vtxp; vtxp = vtxp->verticesNextp()) {
|
||||
if (auto* ivtxp = dynamic_cast<OrderInputsVertex*>(vtxp)) return *ivtxp;
|
||||
if (auto* const ivtxp = dynamic_cast<OrderInputsVertex*>(vtxp)) return *ivtxp;
|
||||
}
|
||||
VL_UNREACHABLE
|
||||
}
|
||||
|
|
@ -1357,7 +1357,7 @@ void OrderProcess::processInputs() {
|
|||
todoVec.push_front(&m_inputsVtx);
|
||||
m_inputsVtx.isFromInput(true); // By definition
|
||||
while (!todoVec.empty()) {
|
||||
OrderEitherVertex* vertexp = todoVec.back();
|
||||
OrderEitherVertex* const vertexp = todoVec.back();
|
||||
todoVec.pop_back();
|
||||
processInputsOutIterate(vertexp, todoVec);
|
||||
}
|
||||
|
|
@ -1368,7 +1368,7 @@ void OrderProcess::processInputsInIterate(OrderEitherVertex* vertexp, VertexVec&
|
|||
if (vertexp->user()) return; // Already processed
|
||||
if (false && debug() >= 9) {
|
||||
UINFO(9, " InIIter " << vertexp << endl);
|
||||
if (OrderLogicVertex* vvertexp = dynamic_cast<OrderLogicVertex*>(vertexp)) {
|
||||
if (OrderLogicVertex* const vvertexp = dynamic_cast<OrderLogicVertex*>(vertexp)) {
|
||||
vvertexp->nodep()->dumpTree(cout, "- TT: ");
|
||||
}
|
||||
}
|
||||
|
|
@ -1377,7 +1377,7 @@ void OrderProcess::processInputsInIterate(OrderEitherVertex* vertexp, VertexVec&
|
|||
// Also, determine if this vertex is an input
|
||||
int inonly = 1; // 0=no, 1=maybe, 2=yes until a no
|
||||
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
OrderEitherVertex* frVertexp = static_cast<OrderEitherVertex*>(edgep->fromp());
|
||||
OrderEitherVertex* const frVertexp = static_cast<OrderEitherVertex*>(edgep->fromp());
|
||||
processInputsInIterate(frVertexp, todoVec);
|
||||
if (frVertexp->isFromInput()) {
|
||||
if (inonly == 1) inonly = 2;
|
||||
|
|
@ -1416,11 +1416,11 @@ void OrderProcess::processInputsOutIterate(OrderEitherVertex* vertexp, VertexVec
|
|||
{
|
||||
// Propagate PrimaryIn through simple assignments, following target of vertex
|
||||
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||
OrderEitherVertex* toVertexp = static_cast<OrderEitherVertex*>(edgep->top());
|
||||
if (OrderVarStdVertex* vvertexp = dynamic_cast<OrderVarStdVertex*>(toVertexp)) {
|
||||
OrderEitherVertex* const toVertexp = static_cast<OrderEitherVertex*>(edgep->top());
|
||||
if (OrderVarStdVertex* const vvertexp = dynamic_cast<OrderVarStdVertex*>(toVertexp)) {
|
||||
processInputsInIterate(vvertexp, todoVec);
|
||||
}
|
||||
if (OrderLogicVertex* vvertexp = dynamic_cast<OrderLogicVertex*>(toVertexp)) {
|
||||
if (OrderLogicVertex* const vvertexp = dynamic_cast<OrderLogicVertex*>(toVertexp)) {
|
||||
if (VN_IS(vvertexp->nodep(), NodeAssign)) {
|
||||
processInputsInIterate(vvertexp, todoVec);
|
||||
}
|
||||
|
|
@ -1436,7 +1436,7 @@ void OrderProcess::processCircular() {
|
|||
// Take broken edges and add circular flags
|
||||
// The change detect code will use this to force changedets
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (OrderVarStdVertex* vvertexp = dynamic_cast<OrderVarStdVertex*>(itp)) {
|
||||
if (OrderVarStdVertex* const vvertexp = dynamic_cast<OrderVarStdVertex*>(itp)) {
|
||||
if (vvertexp->isClock() && !vvertexp->isFromInput()) {
|
||||
// If a clock is generated internally, we need to do another
|
||||
// loop through the entire evaluation. This fixes races; see
|
||||
|
|
@ -1459,7 +1459,7 @@ void OrderProcess::processCircular() {
|
|||
// Also mark any cut edges
|
||||
for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||
if (edgep->weight() == 0) { // was cut
|
||||
OrderEdge* oedgep = dynamic_cast<OrderEdge*>(edgep);
|
||||
OrderEdge* const oedgep = dynamic_cast<OrderEdge*>(edgep);
|
||||
UASSERT_OBJ(oedgep, vvertexp->varScp(), "Cutable edge not of proper type");
|
||||
UINFO(6, " CutCircularO: " << vvertexp->name() << endl);
|
||||
nodeMarkCircular(vvertexp, oedgep);
|
||||
|
|
@ -1467,7 +1467,7 @@ void OrderProcess::processCircular() {
|
|||
}
|
||||
for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
if (edgep->weight() == 0) { // was cut
|
||||
OrderEdge* oedgep = dynamic_cast<OrderEdge*>(edgep);
|
||||
OrderEdge* const oedgep = dynamic_cast<OrderEdge*>(edgep);
|
||||
UASSERT_OBJ(oedgep, vvertexp->varScp(), "Cutable edge not of proper type");
|
||||
UINFO(6, " CutCircularI: " << vvertexp->name() << endl);
|
||||
nodeMarkCircular(vvertexp, oedgep);
|
||||
|
|
@ -1481,12 +1481,12 @@ void OrderProcess::processSensitive() {
|
|||
// Sc sensitives are required on all inputs that go to a combo
|
||||
// block. (Not inputs that go only to clocked blocks.)
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (OrderVarStdVertex* vvertexp = dynamic_cast<OrderVarStdVertex*>(itp)) {
|
||||
if (OrderVarStdVertex* const vvertexp = dynamic_cast<OrderVarStdVertex*>(itp)) {
|
||||
if (vvertexp->varScp()->varp()->isNonOutput()) {
|
||||
// UINFO(0, " scsen " << vvertexp << endl);
|
||||
for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep;
|
||||
edgep = edgep->outNextp()) {
|
||||
if (OrderEitherVertex* toVertexp
|
||||
if (OrderEitherVertex* const toVertexp
|
||||
= dynamic_cast<OrderEitherVertex*>(edgep->top())) {
|
||||
if (edgep->weight() && toVertexp->domainp()) {
|
||||
// UINFO(0, " " << toVertexp->domainp() << endl);
|
||||
|
|
@ -1503,7 +1503,7 @@ void OrderProcess::processSensitive() {
|
|||
|
||||
void OrderProcess::processDomains() {
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
OrderEitherVertex* vertexp = dynamic_cast<OrderEitherVertex*>(itp);
|
||||
OrderEitherVertex* const vertexp = dynamic_cast<OrderEitherVertex*>(itp);
|
||||
UASSERT(vertexp, "Null or vertex not derived from EitherVertex");
|
||||
processDomainsIterate(vertexp);
|
||||
}
|
||||
|
|
@ -1518,13 +1518,13 @@ void OrderProcess::processDomainsIterate(OrderEitherVertex* vertexp) {
|
|||
// else, it's full combo code
|
||||
if (vertexp->domainp()) return; // Already processed, or sequential logic
|
||||
UINFO(5, " pdi: " << vertexp << endl);
|
||||
OrderVarVertex* vvertexp = dynamic_cast<OrderVarVertex*>(vertexp);
|
||||
OrderVarVertex* const vvertexp = dynamic_cast<OrderVarVertex*>(vertexp);
|
||||
AstSenTree* domainp = nullptr;
|
||||
if (vvertexp && vvertexp->varScp()->varp()->isNonOutput()) domainp = m_comboDomainp;
|
||||
if (vvertexp && vvertexp->varScp()->isCircular()) domainp = m_comboDomainp;
|
||||
if (!domainp) {
|
||||
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
OrderEitherVertex* fromVertexp = static_cast<OrderEitherVertex*>(edgep->fromp());
|
||||
OrderEitherVertex* const fromVertexp = static_cast<OrderEitherVertex*>(edgep->fromp());
|
||||
if (edgep->weight() && fromVertexp->domainMatters()) {
|
||||
UINFO(9, " from d=" << cvtToHex(fromVertexp->domainp()) << " " << fromVertexp
|
||||
<< endl);
|
||||
|
|
@ -1553,7 +1553,7 @@ void OrderProcess::processDomainsIterate(OrderEitherVertex* vertexp) {
|
|||
UINFO(0, " d2 =" << fromVertexp->domainp() << endl);
|
||||
fromVertexp->domainp()->dumpTree(cout);
|
||||
} // LCOV_EXCL_STOP
|
||||
AstSenTree* newtreep = domainp->cloneTree(false);
|
||||
AstSenTree* const newtreep = domainp->cloneTree(false);
|
||||
AstSenItem* newtree2p = fromVertexp->domainp()->sensesp()->cloneTree(true);
|
||||
UASSERT_OBJ(newtree2p, fromVertexp->domainp(),
|
||||
"No senitem found under clocked domain");
|
||||
|
|
@ -1602,7 +1602,7 @@ void OrderProcess::processEdgeReport() {
|
|||
std::deque<string> report;
|
||||
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (OrderVarVertex* vvertexp = dynamic_cast<OrderVarVertex*>(itp)) {
|
||||
if (OrderVarVertex* const vvertexp = dynamic_cast<OrderVarVertex*>(itp)) {
|
||||
string name(vvertexp->varScp()->prettyName());
|
||||
if (dynamic_cast<OrderVarPreVertex*>(itp)) {
|
||||
name += " {PRE}";
|
||||
|
|
@ -1614,7 +1614,7 @@ void OrderProcess::processEdgeReport() {
|
|||
std::ostringstream os;
|
||||
os.setf(std::ios::left);
|
||||
os << " " << cvtToHex(vvertexp->varScp()) << " " << std::setw(50) << name << " ";
|
||||
AstSenTree* sentreep = vvertexp->domainp();
|
||||
AstSenTree* const sentreep = vvertexp->domainp();
|
||||
if (sentreep) V3EmitV::verilogForTree(sentreep, os);
|
||||
report.push_back(os.str());
|
||||
}
|
||||
|
|
@ -1668,7 +1668,8 @@ void OrderProcess::processMove() {
|
|||
while (!m_pomReadyDomScope.empty()) {
|
||||
// Start with top node on ready list's domain & scope
|
||||
OrderMoveDomScope* domScopep = m_pomReadyDomScope.begin();
|
||||
OrderMoveVertex* topVertexp = domScopep->readyVertices().begin(); // lintok-begin-on-ref
|
||||
OrderMoveVertex* const topVertexp
|
||||
= domScopep->readyVertices().begin(); // lintok-begin-on-ref
|
||||
UASSERT(topVertexp, "domScope on ready list without any nodes ready under it");
|
||||
// Work on all scopes ready inside this domain
|
||||
while (domScopep) {
|
||||
|
|
@ -1702,7 +1703,7 @@ void OrderProcess::processMovePrepReady() {
|
|||
// Make list of ready nodes
|
||||
UINFO(5, " MovePrepReady\n");
|
||||
for (OrderMoveVertex* vertexp = m_pomWaiting.begin(); vertexp;) {
|
||||
OrderMoveVertex* nextp = vertexp->pomWaitingNextp();
|
||||
OrderMoveVertex* const nextp = vertexp->pomWaitingNextp();
|
||||
if (vertexp->isWait() && vertexp->inEmpty()) processMoveReadyOne(vertexp);
|
||||
vertexp = nextp;
|
||||
}
|
||||
|
|
@ -1737,7 +1738,7 @@ void OrderProcess::processMoveDoneOne(OrderMoveVertex* vertexp) {
|
|||
// Mark our outputs as one closer to ready
|
||||
for (V3GraphEdge *edgep = vertexp->outBeginp(), *nextp; edgep; edgep = nextp) {
|
||||
nextp = edgep->outNextp();
|
||||
OrderMoveVertex* toVertexp = static_cast<OrderMoveVertex*>(edgep->top());
|
||||
OrderMoveVertex* const toVertexp = static_cast<OrderMoveVertex*>(edgep->top());
|
||||
UINFO(9, " Clear to " << (toVertexp->inEmpty() ? "[EMP] " : " ") << toVertexp
|
||||
<< endl);
|
||||
// Delete this edge
|
||||
|
|
@ -1754,11 +1755,11 @@ void OrderProcess::processMoveDoneOne(OrderMoveVertex* vertexp) {
|
|||
void OrderProcess::processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* domScopep,
|
||||
int level) {
|
||||
UASSERT_OBJ(vertexp->domScopep() == domScopep, vertexp, "Domain mismatch; list misbuilt?");
|
||||
const OrderLogicVertex* lvertexp = vertexp->logicp();
|
||||
const AstScope* scopep = lvertexp->scopep();
|
||||
const OrderLogicVertex* const lvertexp = vertexp->logicp();
|
||||
const AstScope* const scopep = lvertexp->scopep();
|
||||
UINFO(5, " POSmove l" << std::setw(3) << level << " d=" << cvtToHex(lvertexp->domainp())
|
||||
<< " s=" << cvtToHex(scopep) << " " << lvertexp << endl);
|
||||
AstActive* newActivep
|
||||
AstActive* const newActivep
|
||||
= processMoveOneLogic(lvertexp, m_pomNewFuncp /*ref*/, m_pomNewStmts /*ref*/);
|
||||
if (newActivep) m_scopetop.addActivep(newActivep);
|
||||
processMoveDoneOne(vertexp);
|
||||
|
|
@ -1827,7 +1828,7 @@ AstActive* OrderProcess::processMoveOneLogic(const OrderLogicVertex* lvertexp,
|
|||
newFuncpr->addStmtsp(nodep);
|
||||
if (v3Global.opt.outputSplitCFuncs()) {
|
||||
// Add in the number of nodes we're adding
|
||||
EmitCBaseCounterVisitor visitor{nodep};
|
||||
const EmitCBaseCounterVisitor visitor{nodep};
|
||||
newStmtsr += visitor.count();
|
||||
}
|
||||
}
|
||||
|
|
@ -1844,10 +1845,10 @@ void OrderProcess::processMTasksInitial(InitialLogicE logic_type) {
|
|||
//
|
||||
int initStmts = 0;
|
||||
AstCFunc* initCFunc = nullptr;
|
||||
AstScope* lastScopep = nullptr;
|
||||
const AstScope* lastScopep = nullptr;
|
||||
for (V3GraphVertex* initVxp = m_graph.verticesBeginp(); initVxp;
|
||||
initVxp = initVxp->verticesNextp()) {
|
||||
OrderLogicVertex* initp = dynamic_cast<OrderLogicVertex*>(initVxp);
|
||||
OrderLogicVertex* const initp = dynamic_cast<OrderLogicVertex*>(initVxp);
|
||||
if (!initp) continue;
|
||||
if ((logic_type == LOGIC_INITIAL) && !initp->domainp()->hasInitial()) continue;
|
||||
if ((logic_type == LOGIC_SETTLE) && !initp->domainp()->hasSettle()) continue;
|
||||
|
|
@ -1856,7 +1857,8 @@ void OrderProcess::processMTasksInitial(InitialLogicE logic_type) {
|
|||
initCFunc = nullptr;
|
||||
lastScopep = initp->scopep();
|
||||
}
|
||||
AstActive* newActivep = processMoveOneLogic(initp, initCFunc /*ref*/, initStmts /*ref*/);
|
||||
AstActive* const newActivep
|
||||
= processMoveOneLogic(initp, initCFunc /*ref*/, initStmts /*ref*/);
|
||||
if (newActivep) m_scopetop.addActivep(newActivep);
|
||||
}
|
||||
}
|
||||
|
|
@ -1899,7 +1901,7 @@ void OrderProcess::processMTasks() {
|
|||
GraphStream<OrderVerticesByDomainThenScope> emit_logic(&logicGraph);
|
||||
const V3GraphVertex* moveVxp;
|
||||
while ((moveVxp = emit_logic.nextp())) {
|
||||
const MTaskMoveVertex* movep = dynamic_cast<const MTaskMoveVertex*>(moveVxp);
|
||||
const MTaskMoveVertex* const movep = dynamic_cast<const MTaskMoveVertex*>(moveVxp);
|
||||
const unsigned mtaskId = movep->color();
|
||||
UASSERT(mtaskId > 0, "Every MTaskMoveVertex should have an mtask assignment >0");
|
||||
if (movep->logicp()) {
|
||||
|
|
@ -1910,22 +1912,22 @@ void OrderProcess::processMTasks() {
|
|||
// take this opportunity to annotate each AstVar with the id's
|
||||
// of mtasks that consume it and produce it. We'll use this
|
||||
// information in V3EmitC when we lay out var's in memory.
|
||||
const OrderLogicVertex* logicp = movep->logicp();
|
||||
const OrderLogicVertex* const logicp = movep->logicp();
|
||||
for (const V3GraphEdge* edgep = logicp->inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
const OrderVarVertex* pre_varp
|
||||
const OrderVarVertex* const pre_varp
|
||||
= dynamic_cast<const OrderVarVertex*>(edgep->fromp());
|
||||
if (!pre_varp) continue;
|
||||
AstVar* varp = pre_varp->varScp()->varp();
|
||||
AstVar* const varp = pre_varp->varScp()->varp();
|
||||
// varp depends on logicp, so logicp produces varp,
|
||||
// and vice-versa below
|
||||
varp->addProducingMTaskId(mtaskId);
|
||||
}
|
||||
for (const V3GraphEdge* edgep = logicp->outBeginp(); edgep;
|
||||
edgep = edgep->outNextp()) {
|
||||
const OrderVarVertex* post_varp
|
||||
const OrderVarVertex* const post_varp
|
||||
= dynamic_cast<const OrderVarVertex*>(edgep->top());
|
||||
if (!post_varp) continue;
|
||||
AstVar* varp = post_varp->varScp()->varp();
|
||||
AstVar* const varp = post_varp->varScp()->varp();
|
||||
varp->addConsumingMTaskId(mtaskId);
|
||||
}
|
||||
// TODO? We ignore IO vars here, so those will have empty mtask
|
||||
|
|
@ -1935,8 +1937,8 @@ void OrderProcess::processMTasks() {
|
|||
|
||||
// Create the AstExecGraph node which represents the execution
|
||||
// of the MTask graph.
|
||||
FileLine* rootFlp = v3Global.rootp()->fileline();
|
||||
AstExecGraph* execGraphp = new AstExecGraph(rootFlp);
|
||||
FileLine* const rootFlp = v3Global.rootp()->fileline();
|
||||
AstExecGraph* const execGraphp = new AstExecGraph(rootFlp);
|
||||
m_scopetop.addActivep(execGraphp);
|
||||
v3Global.rootp()->execGraphp(execGraphp);
|
||||
|
||||
|
|
@ -1944,10 +1946,10 @@ void OrderProcess::processMTasks() {
|
|||
GraphStream<MTaskVxIdLessThan> emit_mtasks(&mtasks);
|
||||
const V3GraphVertex* mtaskVxp;
|
||||
while ((mtaskVxp = emit_mtasks.nextp())) {
|
||||
const AbstractLogicMTask* mtaskp = dynamic_cast<const AbstractLogicMTask*>(mtaskVxp);
|
||||
const AbstractLogicMTask* const mtaskp = dynamic_cast<const AbstractLogicMTask*>(mtaskVxp);
|
||||
|
||||
// Create a body for this mtask
|
||||
AstMTaskBody* bodyp = new AstMTaskBody(rootFlp);
|
||||
AstMTaskBody* const bodyp = new AstMTaskBody(rootFlp);
|
||||
MTaskState& state = mtaskStates[mtaskp->id()];
|
||||
state.m_mtaskBodyp = bodyp;
|
||||
|
||||
|
|
@ -1964,7 +1966,7 @@ void OrderProcess::processMTasks() {
|
|||
}
|
||||
last_domainp = logicp->domainp();
|
||||
|
||||
AstActive* newActivep
|
||||
AstActive* const newActivep
|
||||
= processMoveOneLogic(logicp, leafCFuncp /*ref*/, leafStmts /*ref*/);
|
||||
if (newActivep) bodyp->addStmtsp(newActivep);
|
||||
}
|
||||
|
|
@ -1984,8 +1986,9 @@ void OrderProcess::processMTasks() {
|
|||
state.m_mtaskBodyp->execMTaskp(state.m_execMTaskp);
|
||||
for (V3GraphEdge* inp = mtaskp->inBeginp(); inp; inp = inp->inNextp()) {
|
||||
const V3GraphVertex* fromVxp = inp->fromp();
|
||||
const AbstractLogicMTask* fromp = dynamic_cast<const AbstractLogicMTask*>(fromVxp);
|
||||
MTaskState& fromState = mtaskStates[fromp->id()];
|
||||
const AbstractLogicMTask* const fromp
|
||||
= dynamic_cast<const AbstractLogicMTask*>(fromVxp);
|
||||
const MTaskState& fromState = mtaskStates[fromp->id()];
|
||||
new V3GraphEdge(execGraphp->mutableDepGraphp(), fromState.m_execMTaskp,
|
||||
state.m_execMTaskp, 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ public:
|
|||
// Vertex types
|
||||
|
||||
class OrderEitherVertex VL_NOT_FINAL : public V3GraphVertex {
|
||||
AstScope* m_scopep; // Scope the vertex is in
|
||||
AstScope* const m_scopep; // Scope the vertex is in
|
||||
AstSenTree* m_domainp; // Clock domain (nullptr = to be computed as we iterate)
|
||||
bool m_isFromInput = false; // From input, or derived therefrom (conservatively false)
|
||||
protected:
|
||||
|
|
@ -172,7 +172,7 @@ public:
|
|||
};
|
||||
|
||||
class OrderLogicVertex final : public OrderEitherVertex {
|
||||
AstNode* m_nodep;
|
||||
AstNode* const m_nodep;
|
||||
|
||||
protected:
|
||||
OrderLogicVertex(V3Graph* graphp, const OrderLogicVertex& old)
|
||||
|
|
@ -200,7 +200,7 @@ public:
|
|||
};
|
||||
|
||||
class OrderVarVertex VL_NOT_FINAL : public OrderEitherVertex {
|
||||
AstVarScope* m_varScp;
|
||||
AstVarScope* const m_varScp;
|
||||
bool m_isClock = false; // Used as clock
|
||||
bool m_isDelayed = false; // Set in a delayed assignment
|
||||
protected:
|
||||
|
|
@ -306,7 +306,7 @@ public:
|
|||
class OrderMoveVertex final : public V3GraphVertex {
|
||||
enum OrderMState : uint8_t { POM_WAIT, POM_READY, POM_MOVED };
|
||||
|
||||
OrderLogicVertex* m_logicp;
|
||||
OrderLogicVertex* const m_logicp;
|
||||
OrderMState m_state; // Movement state
|
||||
OrderMoveDomScope* m_domScopep; // Domain/scope list information
|
||||
|
||||
|
|
@ -376,10 +376,10 @@ class MTaskMoveVertex final : public V3GraphVertex {
|
|||
// This could be more compact, since we know m_varp and m_logicp
|
||||
// cannot both be set. Each MTaskMoveVertex represents a logic node
|
||||
// or a var node, it can't be both.
|
||||
OrderLogicVertex* m_logicp; // Logic represented by this vertex
|
||||
const OrderEitherVertex* m_varp; // Var represented by this vertex
|
||||
const AstScope* m_scopep;
|
||||
const AstSenTree* m_domainp;
|
||||
OrderLogicVertex* const m_logicp; // Logic represented by this vertex
|
||||
const OrderEitherVertex* const m_varp; // Var represented by this vertex
|
||||
const AstScope* const m_scopep;
|
||||
const AstSenTree* const m_domainp;
|
||||
|
||||
protected:
|
||||
friend class OrderVisitor;
|
||||
|
|
@ -449,7 +449,7 @@ public:
|
|||
// involving pre/pos variables
|
||||
virtual bool followComboConnected() const { return true; }
|
||||
static bool followComboConnected(const V3GraphEdge* edgep) {
|
||||
const OrderEdge* oedgep = dynamic_cast<const OrderEdge*>(edgep);
|
||||
const OrderEdge* const oedgep = dynamic_cast<const OrderEdge*>(edgep);
|
||||
if (!oedgep) v3fatalSrc("Following edge of non-OrderEdge type");
|
||||
return (oedgep->followComboConnected());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ void V3Os::unlinkRegexp(const string& dir, const string& regexp) {
|
|||
|
||||
vluint64_t V3Os::rand64(std::array<vluint64_t, 2>& stater) {
|
||||
// Xoroshiro128+ algorithm
|
||||
vluint64_t result = stater[0] + stater[1];
|
||||
const vluint64_t result = stater[0] + stater[1];
|
||||
stater[1] ^= stater[0];
|
||||
stater[0] = (((stater[0] << 55) | (stater[0] >> 9)) ^ stater[1] ^ (stater[1] << 14));
|
||||
stater[1] = (stater[1] << 36) | (stater[1] >> 28);
|
||||
|
|
|
|||
|
|
@ -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 (const AstVar* modvarp = pinp->modVarp()) {
|
||||
if (const AstVar* const modvarp = pinp->modVarp()) {
|
||||
AstConst* const constp = VN_AS(pinp->exprp(), Const);
|
||||
UASSERT_OBJ(constp, pinp,
|
||||
"parameter for a hierarchical block must have been constified");
|
||||
|
|
@ -237,7 +237,7 @@ class ParamProcessor final {
|
|||
// STATE
|
||||
using CloneMap = std::unordered_map<const AstNode*, AstNode*>;
|
||||
struct ModInfo {
|
||||
AstNodeModule* m_modp; // Module with specified name
|
||||
AstNodeModule* const m_modp; // Module with specified name
|
||||
CloneMap m_cloneMap; // Map of old-varp -> new cloned varp
|
||||
explicit ModInfo(AstNodeModule* modp)
|
||||
: m_modp{modp} {}
|
||||
|
|
@ -256,7 +256,7 @@ class ParamProcessor final {
|
|||
std::map<const V3Hash, ValueMapValue> m_valueMap; // Hash of node hash to (param value, name)
|
||||
int m_nextValue = 1; // Next value to use in m_valueMap
|
||||
|
||||
AstNodeModule* m_modp = nullptr; // Current module being processed
|
||||
const AstNodeModule* m_modp = nullptr; // Current module being processed
|
||||
|
||||
// Database to get lib-create wrapper that matches parameters in hierarchical Verilation
|
||||
ParameterizedHierBlocks m_hierBlocks;
|
||||
|
|
@ -386,14 +386,14 @@ class ParamProcessor final {
|
|||
if (AstVar* const varp = VN_CAST(stmtp, Var)) {
|
||||
if (varp->isIO() || varp->isGParam() || varp->isIfaceRef()) {
|
||||
// Cloning saved a pointer to the new node for us, so just follow that link.
|
||||
AstVar* const oldvarp = varp->clonep();
|
||||
const AstVar* const oldvarp = varp->clonep();
|
||||
// UINFO(8,"Clone list 0x"<<hex<<(uint32_t)oldvarp
|
||||
// <<" -> 0x"<<(uint32_t)varp<<endl);
|
||||
clonemapp->emplace(oldvarp, varp);
|
||||
}
|
||||
} else if (AstParamTypeDType* ptp = VN_CAST(stmtp, ParamTypeDType)) {
|
||||
} else if (AstParamTypeDType* const ptp = VN_CAST(stmtp, ParamTypeDType)) {
|
||||
if (ptp->isGParam()) {
|
||||
AstParamTypeDType* const oldptp = ptp->clonep();
|
||||
const AstParamTypeDType* const oldptp = ptp->clonep();
|
||||
clonemapp->emplace(oldptp, ptp);
|
||||
}
|
||||
}
|
||||
|
|
@ -428,7 +428,7 @@ class ParamProcessor final {
|
|||
}
|
||||
}
|
||||
for (AstPin* pinp = startpinp; pinp; pinp = VN_AS(pinp->nextp(), Pin)) {
|
||||
if (AstVar* const varp = pinp->modVarp()) {
|
||||
if (const AstVar* const varp = pinp->modVarp()) {
|
||||
const auto varIt = vlstd::as_const(nameToPin).find(varp->name());
|
||||
UASSERT_OBJ(varIt != nameToPin.end(), varp,
|
||||
"Not found in " << modp->prettyNameQ());
|
||||
|
|
@ -471,10 +471,10 @@ class ParamProcessor final {
|
|||
std::map<string, AstConst*> pins;
|
||||
for (AstPin* pinp = paramPinsp; pinp; pinp = VN_AS(pinp->nextp(), Pin)) {
|
||||
checkSupportedParam(modp, pinp);
|
||||
if (AstVar* const varp = pinp->modVarp()) {
|
||||
if (const AstVar* const varp = pinp->modVarp()) {
|
||||
if (!pinp->exprp()) continue;
|
||||
if (varp->isGParam()) {
|
||||
AstConst* constp = VN_CAST(pinp->exprp(), Const);
|
||||
AstConst* const constp = VN_CAST(pinp->exprp(), Const);
|
||||
pins.emplace(varp->name(), constp);
|
||||
}
|
||||
}
|
||||
|
|
@ -575,8 +575,8 @@ class ParamProcessor final {
|
|||
relinkPins(clonemapp, paramsp);
|
||||
// Fix any interface references
|
||||
for (auto it = ifaceRefRefs.cbegin(); it != ifaceRefRefs.cend(); ++it) {
|
||||
AstIfaceRefDType* const portIrefp = it->first;
|
||||
AstIfaceRefDType* const pinIrefp = it->second;
|
||||
const AstIfaceRefDType* const portIrefp = it->first;
|
||||
const AstIfaceRefDType* const pinIrefp = it->second;
|
||||
AstIfaceRefDType* const cloneIrefp = portIrefp->clonep();
|
||||
UINFO(8, " IfaceOld " << portIrefp << endl);
|
||||
UINFO(8, " IfaceTo " << pinIrefp << endl);
|
||||
|
|
@ -589,7 +589,7 @@ class ParamProcessor final {
|
|||
// DOES clone() so must be finished with module clonep() before here
|
||||
for (AstPin* pinp = paramsp; pinp; pinp = VN_AS(pinp->nextp(), Pin)) {
|
||||
if (pinp->exprp()) {
|
||||
if (AstVar* modvarp = pinp->modVarp()) {
|
||||
if (AstVar* const modvarp = pinp->modVarp()) {
|
||||
AstNode* const newp = pinp->exprp(); // Const or InitArray
|
||||
AstConst* const exprp = VN_CAST(newp, Const);
|
||||
AstConst* const origp = VN_CAST(modvarp->valuep(), Const);
|
||||
|
|
@ -694,15 +694,15 @@ class ParamProcessor final {
|
|||
void cellInterfaceCleanup(AstCell* nodep, AstNodeModule* srcModp, string& longnamer,
|
||||
bool& any_overridesr, IfaceRefRefs& ifaceRefRefs) {
|
||||
for (AstPin* pinp = nodep->pinsp(); pinp; pinp = VN_AS(pinp->nextp(), Pin)) {
|
||||
AstVar* const modvarp = pinp->modVarp();
|
||||
const AstVar* const modvarp = pinp->modVarp();
|
||||
if (modvarp->isIfaceRef()) {
|
||||
AstIfaceRefDType* portIrefp = VN_CAST(modvarp->subDTypep(), IfaceRefDType);
|
||||
if (!portIrefp && arraySubDTypep(modvarp->subDTypep())) {
|
||||
portIrefp = VN_CAST(arraySubDTypep(modvarp->subDTypep()), IfaceRefDType);
|
||||
}
|
||||
AstIfaceRefDType* pinIrefp = nullptr;
|
||||
AstNode* const exprp = pinp->exprp();
|
||||
AstVar* const varp
|
||||
const AstNode* const exprp = pinp->exprp();
|
||||
const AstVar* const varp
|
||||
= (exprp && VN_IS(exprp, VarRef)) ? VN_AS(exprp, VarRef)->varp() : nullptr;
|
||||
if (varp && varp->subDTypep() && VN_IS(varp->subDTypep(), IfaceRefDType)) {
|
||||
pinIrefp = VN_AS(varp->subDTypep(), IfaceRefDType);
|
||||
|
|
@ -974,7 +974,7 @@ class ParamVisitor final : public AstNVisitor {
|
|||
UINFO(9, "Found interface parameter: " << varp << endl);
|
||||
nodep->varp(varp);
|
||||
return true;
|
||||
} else if (AstPin* const pinp = VN_CAST(candp, Pin)) {
|
||||
} else if (const AstPin* const pinp = VN_CAST(candp, Pin)) {
|
||||
UINFO(9, "Found interface parameter: " << pinp << endl);
|
||||
UASSERT_OBJ(pinp->exprp(), pinp, "Interface parameter pin missing expression");
|
||||
VL_DO_DANGLING(nodep->replaceWith(pinp->exprp()->cloneTree(false)), nodep);
|
||||
|
|
@ -988,7 +988,7 @@ class ParamVisitor final : public AstNVisitor {
|
|||
// Check to see if the scope is just an interface because interfaces are special
|
||||
const string dotted = nodep->dotted();
|
||||
if (!dotted.empty() && nodep->varp() && nodep->varp()->isParam()) {
|
||||
AstNode* backp = nodep;
|
||||
const AstNode* backp = nodep;
|
||||
while ((backp = backp->backp())) {
|
||||
if (VN_IS(backp, NodeModule)) {
|
||||
UINFO(9, "Hit module boundary, done looking for interface" << endl);
|
||||
|
|
@ -1000,14 +1000,14 @@ class ParamVisitor final : public AstNVisitor {
|
|||
|| (VN_CAST(VN_CAST(backp, Var)->childDTypep(), UnpackArrayDType)
|
||||
&& VN_CAST(VN_CAST(backp, Var)->childDTypep()->getChildDTypep(),
|
||||
IfaceRefDType)))) {
|
||||
AstIfaceRefDType* ifacerefp
|
||||
const AstIfaceRefDType* ifacerefp
|
||||
= VN_CAST(VN_CAST(backp, Var)->childDTypep(), IfaceRefDType);
|
||||
if (!ifacerefp) {
|
||||
ifacerefp = VN_CAST(VN_CAST(backp, Var)->childDTypep()->getChildDTypep(),
|
||||
IfaceRefDType);
|
||||
}
|
||||
// Interfaces passed in on the port map have ifaces
|
||||
if (AstIface* const ifacep = ifacerefp->ifacep()) {
|
||||
if (const AstIface* const ifacep = ifacerefp->ifacep()) {
|
||||
if (dotted == backp->name()) {
|
||||
UINFO(9, "Iface matching scope: " << ifacep << endl);
|
||||
if (ifaceParamReplace(nodep, ifacep->stmtsp())) { //
|
||||
|
|
@ -1016,7 +1016,7 @@ class ParamVisitor final : public AstNVisitor {
|
|||
}
|
||||
}
|
||||
// Interfaces declared in this module have cells
|
||||
else if (AstCell* const cellp = ifacerefp->cellp()) {
|
||||
else if (const AstCell* const cellp = ifacerefp->cellp()) {
|
||||
if (dotted == cellp->name()) {
|
||||
UINFO(9, "Iface matching scope: " << cellp << endl);
|
||||
if (ifaceParamReplace(nodep, cellp->paramsp())) { //
|
||||
|
|
@ -1140,7 +1140,7 @@ class ParamVisitor final : public AstNVisitor {
|
|||
V3Width::widthParamsEdit(nodep); // Param typed widthing will NOT recurse the body,
|
||||
// don't trigger errors yet.
|
||||
V3Const::constifyParamsEdit(nodep->exprp()); // exprp may change
|
||||
AstConst* const exprp = VN_AS(nodep->exprp(), Const);
|
||||
const AstConst* const exprp = VN_AS(nodep->exprp(), Const);
|
||||
// Constify
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp;
|
||||
itemp = VN_AS(itemp->nextp(), CaseItem)) {
|
||||
|
|
|
|||
|
|
@ -193,8 +193,8 @@ double V3ParseImp::lexParseTimenum(const char* textp) {
|
|||
if (*sp != '_') *dp++ = *sp;
|
||||
}
|
||||
*dp++ = '\0';
|
||||
double d = strtod(strgp, nullptr);
|
||||
string suffix(sp);
|
||||
const double d = strtod(strgp, nullptr);
|
||||
const string suffix(sp);
|
||||
|
||||
double divisor = 1;
|
||||
if (suffix == "s") {
|
||||
|
|
@ -288,7 +288,7 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i
|
|||
|
||||
if (v3Global.opt.preprocOnly() || v3Global.opt.keepTempFiles()) {
|
||||
// Create output file with all the preprocessor output we buffered up
|
||||
string vppfilename
|
||||
const string vppfilename
|
||||
= v3Global.opt.hierTopDataDir() + "/" + v3Global.opt.prefix() + "_" + modname + ".vpp";
|
||||
std::ofstream* ofp = nullptr;
|
||||
std::ostream* osp;
|
||||
|
|
@ -392,7 +392,7 @@ void V3ParseImp::tokenPipeline() {
|
|||
if (debugFlex() >= 6) {
|
||||
cout << " tokenPipeline: reading ahead to find possible strength" << endl;
|
||||
}
|
||||
V3ParseBisonYYSType curValue = yylval; // Remember value, as about to read ahead
|
||||
const V3ParseBisonYYSType curValue = yylval; // Remember value, as about to read ahead
|
||||
const V3ParseBisonYYSType* nexttokp = tokenPeekp(0);
|
||||
const int nexttok = nexttokp->token;
|
||||
yylval = curValue;
|
||||
|
|
@ -467,7 +467,8 @@ void V3ParseImp::tokenPipeline() {
|
|||
if (nexttok == yP_COLONCOLON) {
|
||||
token = yaID__CC;
|
||||
} else if (nexttok == '#') {
|
||||
V3ParseBisonYYSType curValue = yylval; // Remember value, as about to read ahead
|
||||
const V3ParseBisonYYSType curValue
|
||||
= yylval; // Remember value, as about to read ahead
|
||||
{
|
||||
const size_t depth = tokenPipeScanParam(0);
|
||||
if (tokenPeekp(depth)->token == yP_COLONCOLON) token = yaID__CC;
|
||||
|
|
@ -487,8 +488,8 @@ void V3ParseImp::tokenPipelineSym() {
|
|||
tokenPipeline(); // sets yylval
|
||||
int token = yylval.token;
|
||||
if (token == yaID__LEX || token == yaID__CC) {
|
||||
VSymEnt* foundp;
|
||||
if (VSymEnt* const look_underp = V3ParseImp::parsep()->symp()->nextId()) {
|
||||
const VSymEnt* foundp;
|
||||
if (const 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));
|
||||
|
|
|
|||
|
|
@ -133,8 +133,8 @@ std::ostream& operator<<(std::ostream& os, const V3ParseBisonYYSType& rhs);
|
|||
|
||||
class V3ParseImp final {
|
||||
// MEMBERS
|
||||
AstNetlist* m_rootp; // Root of the design
|
||||
VInFilter* m_filterp; // Reading filter
|
||||
AstNetlist* const m_rootp; // Root of the design
|
||||
VInFilter* const m_filterp; // Reading filter
|
||||
V3ParseSym* m_symp; // Symbol table
|
||||
|
||||
V3Lexer* m_lexerp; // Current FlexLexer
|
||||
|
|
@ -229,18 +229,18 @@ public:
|
|||
// These can be called by either parser or lexer, as not lex/parser-position aware
|
||||
string* newString(const string& text) {
|
||||
// Allocate a string, remembering it so we can reclaim storage at lex end
|
||||
string* strp = new string(text);
|
||||
string* const strp = new string(text);
|
||||
m_stringps.push_back(strp);
|
||||
return strp;
|
||||
}
|
||||
string* newString(const char* text) {
|
||||
// Allocate a string, remembering it so we can reclaim storage at lex end
|
||||
string* strp = new string(text);
|
||||
string* const strp = new string(text);
|
||||
m_stringps.push_back(strp);
|
||||
return strp;
|
||||
}
|
||||
string* newString(const char* text, size_t length) {
|
||||
string* strp = new string(text, length);
|
||||
string* const strp = new string(text, length);
|
||||
m_stringps.push_back(strp);
|
||||
return strp;
|
||||
}
|
||||
|
|
@ -275,7 +275,8 @@ public:
|
|||
V3ParseSym* symp() { return m_symp; }
|
||||
AstPackage* unitPackage(FileLine* fl) {
|
||||
// Find one made earlier?
|
||||
VSymEnt* const rootSymp = symp()->symRootp()->findIdFlat(AstPackage::dollarUnitName());
|
||||
const VSymEnt* const rootSymp
|
||||
= symp()->symRootp()->findIdFlat(AstPackage::dollarUnitName());
|
||||
AstPackage* pkgp;
|
||||
if (!rootSymp) {
|
||||
pkgp = parsep()->rootp()->dollarUnitPkgAddp();
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public:
|
|||
|
||||
VSymEnt* findNewTable(AstNode* nodep) {
|
||||
if (!nodep->user4p()) {
|
||||
VSymEnt* symsp = new VSymEnt(&m_syms, nodep);
|
||||
VSymEnt* const symsp = new VSymEnt(&m_syms, nodep);
|
||||
nodep->user4p(symsp);
|
||||
}
|
||||
return getTable(nodep);
|
||||
|
|
@ -93,7 +93,7 @@ public:
|
|||
void pushNew(AstNode* nodep) { pushNewUnder(nodep, nullptr); }
|
||||
void pushNewUnder(AstNode* nodep, VSymEnt* parentp) {
|
||||
if (!parentp) parentp = symCurrentp();
|
||||
VSymEnt* symp
|
||||
VSymEnt* const symp
|
||||
= findNewTable(nodep); // Will set user4p, which is how we connect table to node
|
||||
symp->fallbackp(parentp);
|
||||
reinsert(nodep, parentp);
|
||||
|
|
@ -128,7 +128,7 @@ public:
|
|||
void showUpward() { // LCOV_EXCL_START
|
||||
UINFO(1, "ParseSym Stack:\n");
|
||||
for (auto it = m_sympStack.rbegin(); it != m_sympStack.rend(); ++it) {
|
||||
VSymEnt* symp = *it;
|
||||
VSymEnt* const symp = *it;
|
||||
UINFO(1, " " << symp->nodep() << endl);
|
||||
}
|
||||
UINFO(1, "ParseSym Current: " << symCurrentp()->nodep() << endl);
|
||||
|
|
@ -136,7 +136,7 @@ public:
|
|||
void dump(std::ostream& os, const string& indent = "") { m_syms.dump(os, indent); }
|
||||
AstNode* findEntUpward(const string& name) const {
|
||||
// Lookup the given string as an identifier, return type of the id, scanning upward
|
||||
VSymEnt* foundp = symCurrentp()->findIdFallback(name);
|
||||
VSymEnt* const foundp = symCurrentp()->findIdFallback(name);
|
||||
if (foundp) {
|
||||
return foundp->nodep();
|
||||
} else {
|
||||
|
|
@ -145,7 +145,7 @@ public:
|
|||
}
|
||||
void importExtends(AstNode* classp) {
|
||||
// Import from package::id_or_star to this
|
||||
VSymEnt* symp = getTable(classp);
|
||||
VSymEnt* const symp = getTable(classp);
|
||||
UASSERT_OBJ(symp, classp, // Internal problem, because we earlier found it
|
||||
"Extends class package not found");
|
||||
// Walk old sym table and reinsert into current table
|
||||
|
|
@ -154,7 +154,7 @@ public:
|
|||
}
|
||||
void importItem(AstNode* packagep, const string& id_or_star) {
|
||||
// Import from package::id_or_star to this
|
||||
VSymEnt* symp = getTable(packagep);
|
||||
VSymEnt* const symp = getTable(packagep);
|
||||
UASSERT_OBJ(symp, packagep, // Internal problem, because we earlier found it
|
||||
"Import package not found");
|
||||
// Walk old sym table and reinsert into current table
|
||||
|
|
@ -163,7 +163,7 @@ public:
|
|||
}
|
||||
void exportItem(AstNode* packagep, const string& id_or_star) {
|
||||
// Export from this the remote package::id_or_star
|
||||
VSymEnt* symp = getTable(packagep);
|
||||
VSymEnt* const symp = getTable(packagep);
|
||||
UASSERT_OBJ(symp, packagep, // Internal problem, because we earlier found it
|
||||
"Export package not found");
|
||||
symCurrentp()->exportFromPackage(&m_syms, symp, id_or_star);
|
||||
|
|
|
|||
|
|
@ -162,12 +162,12 @@ static void partCheckCachedScoreVsActual(uint32_t cached, uint32_t actual) {
|
|||
template <class T_CostAccessor> class PartPropagateCp : GraphAlg<> {
|
||||
private:
|
||||
// MEMBERS
|
||||
GraphWay m_way; // CPs oriented in this direction: either FORWARD
|
||||
const 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* const m_accessp; // Access cost and CPs on V3GraphVertex's.
|
||||
// // confirm we only process each vertex once.
|
||||
bool m_slowAsserts; // Enable nontrivial asserts
|
||||
const bool m_slowAsserts; // Enable nontrivial asserts
|
||||
SortByValueMap<V3GraphVertex*, uint32_t> m_pending; // Pending rescores
|
||||
|
||||
public:
|
||||
|
|
@ -291,7 +291,7 @@ private:
|
|||
// direction, it assumes REVERSE is symmetrical and would be
|
||||
// redundant to test.
|
||||
GraphStreamUnordered order(&m_graph);
|
||||
while (const V3GraphVertex* cvxp = order.nextp()) {
|
||||
while (const V3GraphVertex* const cvxp = order.nextp()) {
|
||||
V3GraphVertex* const vxp = const_cast<V3GraphVertex*>(cvxp);
|
||||
uint32_t cpCost = 0;
|
||||
for (V3GraphEdge* edgep = vxp->inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
|
|
@ -401,7 +401,7 @@ public:
|
|||
// Check that CP matches that of the longest edge wayward of vxp.
|
||||
void checkNewCpVersusEdges(V3GraphVertex* vxp, GraphWay way, uint32_t cp) const {
|
||||
LogicMTask* const mtaskp = dynamic_cast<LogicMTask*>(vxp);
|
||||
EdgeSet& edges = mtaskp->m_edges[way.invert()];
|
||||
const EdgeSet& edges = mtaskp->m_edges[way.invert()];
|
||||
// This is mtaskp's relative with longest !wayward inclusive CP:
|
||||
const auto edgeIt = edges.rbegin();
|
||||
const uint32_t edgeCp = (*edgeIt).value();
|
||||
|
|
@ -454,7 +454,7 @@ public:
|
|||
for (unsigned int& i : m_critPathCost) i = 0;
|
||||
if (mtmvVxp) { // Else null for test
|
||||
m_vertices.push_back(mtmvVxp);
|
||||
if (OrderLogicVertex* const olvp = mtmvVxp->logicp()) {
|
||||
if (const OrderLogicVertex* const olvp = mtmvVxp->logicp()) {
|
||||
m_cost += V3InstrCount::count(olvp->nodep(), true);
|
||||
}
|
||||
}
|
||||
|
|
@ -527,7 +527,7 @@ public:
|
|||
void checkRelativesCp(GraphWay way) const {
|
||||
const EdgeSet& edges = m_edges[way];
|
||||
for (EdgeSet::const_reverse_iterator it = edges.rbegin(); it != edges.rend(); ++it) {
|
||||
LogicMTask* const relativep = (*it).key();
|
||||
const LogicMTask* const relativep = (*it).key();
|
||||
const uint32_t cachedCp = (*it).value();
|
||||
partCheckCachedScoreVsActual(cachedCp, relativep->critPathCost(way.invert())
|
||||
+ relativep->stepCost());
|
||||
|
|
@ -625,7 +625,7 @@ public:
|
|||
static void dumpCpFilePrefixed(const V3Graph* graphp, const string& nameComment) {
|
||||
const string filename = v3Global.debugFilename(nameComment) + ".txt";
|
||||
UINFO(1, "Writing " << filename << endl);
|
||||
std::unique_ptr<std::ofstream> ofp{V3File::new_ofstream(filename)};
|
||||
const std::unique_ptr<std::ofstream> ofp{V3File::new_ofstream(filename)};
|
||||
std::ostream* const osp = &(*ofp); // &* needed to deref unique_ptr
|
||||
if (osp->fail()) v3fatalStatic("Can't write " << filename);
|
||||
|
||||
|
|
@ -652,7 +652,7 @@ public:
|
|||
totalCost += nextp->cost();
|
||||
|
||||
const EdgeSet& children = nextp->m_edges[GraphWay::FORWARD];
|
||||
EdgeSet::const_reverse_iterator it = children.rbegin();
|
||||
const EdgeSet::const_reverse_iterator it = children.rbegin();
|
||||
if (it == children.rend()) {
|
||||
nextp = nullptr;
|
||||
} else {
|
||||
|
|
@ -976,7 +976,7 @@ static void partInitHalfCriticalPaths(GraphWay way, V3Graph* mtasksp, bool check
|
|||
"Should be no redundant edges in mtasks graph");
|
||||
relatives.insert(edgep->furtherp(rev));
|
||||
#endif
|
||||
LogicMTask* const relativep = dynamic_cast<LogicMTask*>(edgep->furtherp(rev));
|
||||
const LogicMTask* const relativep = dynamic_cast<LogicMTask*>(edgep->furtherp(rev));
|
||||
cpCost = std::max(cpCost, (relativep->critPathCost(way)
|
||||
+ static_cast<uint32_t>(relativep->stepCost())));
|
||||
}
|
||||
|
|
@ -1009,7 +1009,7 @@ static void partCheckCriticalPaths(V3Graph* mtasksp) {
|
|||
partInitHalfCriticalPaths(GraphWay::FORWARD, mtasksp, true);
|
||||
partInitHalfCriticalPaths(GraphWay::REVERSE, mtasksp, true);
|
||||
for (V3GraphVertex* vxp = mtasksp->verticesBeginp(); vxp; vxp = vxp->verticesNextp()) {
|
||||
LogicMTask* const mtaskp = dynamic_cast<LogicMTask*>(vxp);
|
||||
const LogicMTask* const mtaskp = dynamic_cast<LogicMTask*>(vxp);
|
||||
mtaskp->checkRelativesCp(GraphWay::FORWARD);
|
||||
mtaskp->checkRelativesCp(GraphWay::REVERSE);
|
||||
}
|
||||
|
|
@ -1059,12 +1059,12 @@ static void partMergeEdgesFrom(V3Graph* mtasksp, LogicMTask* recipientp, LogicMT
|
|||
V3Scoreboard<MergeCandidate, uint32_t>* sbp) {
|
||||
for (const auto& way : {GraphWay::FORWARD, GraphWay::REVERSE}) {
|
||||
for (V3GraphEdge* edgep = donorp->beginp(way); edgep; edgep = partBlastEdgep(way, edgep)) {
|
||||
MTaskEdge* const tedgep = MTaskEdge::cast(edgep);
|
||||
const MTaskEdge* const tedgep = MTaskEdge::cast(edgep);
|
||||
if (sbp && !tedgep->removedFromSb()) sbp->removeElem(tedgep);
|
||||
// Existing edge; mark it in need of a rescore
|
||||
if (recipientp->hasRelative(way, tedgep->furtherMTaskp(way))) {
|
||||
if (sbp) {
|
||||
MTaskEdge* const existMTaskEdgep = MTaskEdge::cast(
|
||||
const MTaskEdge* const existMTaskEdgep = MTaskEdge::cast(
|
||||
recipientp->findConnectingEdgep(way, tedgep->furtherMTaskp(way)));
|
||||
UASSERT(existMTaskEdgep, "findConnectingEdge didn't find edge");
|
||||
if (!existMTaskEdgep->removedFromSb()) {
|
||||
|
|
@ -1073,7 +1073,7 @@ static void partMergeEdgesFrom(V3Graph* mtasksp, LogicMTask* recipientp, LogicMT
|
|||
}
|
||||
} else {
|
||||
// No existing edge into *this, make one.
|
||||
MTaskEdge* newEdgep;
|
||||
const MTaskEdge* newEdgep;
|
||||
if (way == GraphWay::REVERSE) {
|
||||
newEdgep = new MTaskEdge(mtasksp, tedgep->fromMTaskp(), recipientp, 1);
|
||||
} else {
|
||||
|
|
@ -1112,7 +1112,7 @@ private:
|
|||
uint32_t m_scoreLimit; // Sloppy score allowed when picking merges
|
||||
uint32_t m_scoreLimitBeforeRescore = 0xffffffff; // Next score rescore at
|
||||
unsigned m_mergesSinceRescore = 0; // Merges since last rescore
|
||||
bool m_slowAsserts; // Take extra time to validate algorithm
|
||||
const bool m_slowAsserts; // Take extra time to validate algorithm
|
||||
V3Scoreboard<MergeCandidate, uint32_t> m_sb; // Scoreboard
|
||||
SibSet m_pairs; // Storage for each SiblingMC
|
||||
MTask2Sibs m_mtask2sibs; // SiblingMC set for each mtask
|
||||
|
|
@ -1210,7 +1210,7 @@ public:
|
|||
++mtaskCount;
|
||||
}
|
||||
if (mtaskCount > maxMTasks) {
|
||||
uint32_t oldLimit = m_scoreLimit;
|
||||
const uint32_t oldLimit = m_scoreLimit;
|
||||
m_scoreLimit = (m_scoreLimit * 120) / 100;
|
||||
v3Global.rootp()->fileline()->v3warn(
|
||||
UNOPTTHREADS, "Thread scheduler is unable to provide requested "
|
||||
|
|
@ -1309,7 +1309,7 @@ private:
|
|||
++it) {
|
||||
const SiblingMC* const pairp = *it;
|
||||
if (!pairp->removedFromSb()) m_sb.removeElem(pairp);
|
||||
LogicMTask* const otherp = (pairp->bp() == mtaskp) ? pairp->ap() : pairp->bp();
|
||||
const LogicMTask* const otherp = (pairp->bp() == mtaskp) ? pairp->ap() : pairp->bp();
|
||||
size_t erased = m_mtask2sibs[otherp].erase(pairp);
|
||||
UASSERT_OBJ(erased > 0, otherp, "Expected existing mtask");
|
||||
erased = m_pairs.erase(*pairp);
|
||||
|
|
@ -1323,7 +1323,7 @@ private:
|
|||
LogicMTask* top = nullptr;
|
||||
LogicMTask* fromp = nullptr;
|
||||
MTaskEdge* mergeEdgep = mergeCanp->toMTaskEdge();
|
||||
SiblingMC* mergeSibsp = nullptr;
|
||||
const SiblingMC* mergeSibsp = nullptr;
|
||||
if (mergeEdgep) {
|
||||
top = dynamic_cast<LogicMTask*>(mergeEdgep->top());
|
||||
fromp = dynamic_cast<LogicMTask*>(mergeEdgep->fromp());
|
||||
|
|
@ -1490,8 +1490,8 @@ private:
|
|||
// Score this edge. Lower is better. The score is the new local CP
|
||||
// length if we merge these mtasks. ("Local" means the longest
|
||||
// critical path running through the merged node.)
|
||||
LogicMTask* const top = dynamic_cast<LogicMTask*>(edgep->top());
|
||||
LogicMTask* const fromp = dynamic_cast<LogicMTask*>(edgep->fromp());
|
||||
const LogicMTask* const top = dynamic_cast<LogicMTask*>(edgep->top());
|
||||
const LogicMTask* const fromp = dynamic_cast<LogicMTask*>(edgep->fromp());
|
||||
const uint32_t mergedCpCostFwd
|
||||
= std::max(fromp->critPathCost(GraphWay::FORWARD),
|
||||
top->critPathCostWithout(GraphWay::FORWARD, edgep));
|
||||
|
|
@ -1503,8 +1503,8 @@ private:
|
|||
}
|
||||
|
||||
void makeSiblingMC(LogicMTask* ap, LogicMTask* bp) {
|
||||
SiblingMC newSibs(ap, bp);
|
||||
std::pair<SibSet::iterator, bool> insertResult = m_pairs.insert(newSibs);
|
||||
const SiblingMC newSibs(ap, bp);
|
||||
const std::pair<SibSet::iterator, bool> insertResult = m_pairs.insert(newSibs);
|
||||
if (insertResult.second) {
|
||||
const SiblingMC* const newSibsp = &(*insertResult.first);
|
||||
m_mtask2sibs[ap].insert(newSibsp);
|
||||
|
|
@ -1592,7 +1592,7 @@ private:
|
|||
|
||||
static vluint64_t partitionChainUsecs(unsigned chain_len) {
|
||||
// NOTE: To get a dot file run with --debugi-V3Partition 4 or more.
|
||||
vluint64_t startUsecs = V3Os::timeUsecs();
|
||||
const vluint64_t startUsecs = V3Os::timeUsecs();
|
||||
V3Graph mtasks;
|
||||
LogicMTask* lastp = nullptr;
|
||||
for (unsigned i = 0; i < chain_len; ++i) {
|
||||
|
|
@ -1839,7 +1839,7 @@ private:
|
|||
void findAdjacentTasks(OvvSet::iterator ovvIt, TasksByRank* tasksByRankp) {
|
||||
// Find all writer tasks for this variable, group by rank.
|
||||
for (V3GraphEdge* edgep = (*ovvIt)->inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
OrderLogicVertex* const logicp = dynamic_cast<OrderLogicVertex*>(edgep->fromp());
|
||||
const OrderLogicVertex* const logicp = dynamic_cast<OrderLogicVertex*>(edgep->fromp());
|
||||
if (!logicp) continue;
|
||||
if (logicp->domainp()->hasInitial() || logicp->domainp()->hasSettle()) continue;
|
||||
LogicMTask* const writerMtaskp = m_olv2mtask.at(logicp);
|
||||
|
|
@ -1847,7 +1847,7 @@ private:
|
|||
}
|
||||
// Find all reader tasks for this variable, group by rank.
|
||||
for (V3GraphEdge* edgep = (*ovvIt)->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||
OrderLogicVertex* const logicp = dynamic_cast<OrderLogicVertex*>(edgep->fromp());
|
||||
const OrderLogicVertex* const logicp = dynamic_cast<OrderLogicVertex*>(edgep->fromp());
|
||||
if (!logicp) continue;
|
||||
if (logicp->domainp()->hasInitial() || logicp->domainp()->hasSettle()) continue;
|
||||
LogicMTask* const readerMtaskp = m_olv2mtask.at(logicp);
|
||||
|
|
@ -1882,8 +1882,8 @@ private:
|
|||
// Fix up the map, so donor's OLVs map to mergedp
|
||||
for (LogicMTask::VxList::const_iterator tmvit = donorp->vertexListp()->begin();
|
||||
tmvit != donorp->vertexListp()->end(); ++tmvit) {
|
||||
MTaskMoveVertex* const tmvp = *tmvit;
|
||||
OrderLogicVertex* const logicp = tmvp->logicp();
|
||||
const MTaskMoveVertex* const tmvp = *tmvit;
|
||||
const OrderLogicVertex* const logicp = tmvp->logicp();
|
||||
if (logicp) m_olv2mtask[logicp] = mergedp;
|
||||
}
|
||||
// Move all vertices from donorp to mergedp
|
||||
|
|
@ -1942,15 +1942,15 @@ public:
|
|||
// stage, but whatever, write it as a loop:
|
||||
for (LogicMTask::VxList::const_iterator it = mtaskp->vertexListp()->begin();
|
||||
it != mtaskp->vertexListp()->end(); ++it) {
|
||||
MTaskMoveVertex* const tmvp = *it;
|
||||
if (OrderLogicVertex* const logicp = tmvp->logicp()) {
|
||||
const MTaskMoveVertex* const tmvp = *it;
|
||||
if (const OrderLogicVertex* const logicp = tmvp->logicp()) {
|
||||
m_olv2mtask[logicp] = mtaskp;
|
||||
// Look at downstream vars.
|
||||
for (V3GraphEdge* edgep = logicp->outBeginp(); edgep;
|
||||
edgep = edgep->outNextp()) {
|
||||
// Only consider OrderVarStdVertex which reflects
|
||||
// an actual lvalue assignment; the others do not.
|
||||
OrderVarStdVertex* const ovvp
|
||||
const OrderVarStdVertex* const ovvp
|
||||
= dynamic_cast<OrderVarStdVertex*>(edgep->top());
|
||||
if (!ovvp) continue;
|
||||
if (ovvp->varScp()->varp()->isSc()) {
|
||||
|
|
@ -2145,7 +2145,7 @@ void ThreadSchedule::dumpDotFile(const string& filename) const {
|
|||
// This generates a file used by graphviz, https://www.graphviz.org
|
||||
const std::unique_ptr<std::ofstream> logp{V3File::new_ofstream(filename)};
|
||||
if (logp->fail()) v3fatal("Can't write " << filename);
|
||||
auto* depGraph = v3Global.rootp()->execGraphp()->depGraphp();
|
||||
auto* const depGraph = v3Global.rootp()->execGraphp()->depGraphp();
|
||||
|
||||
// Header
|
||||
*logp << "digraph v3graph {\n";
|
||||
|
|
@ -2172,18 +2172,18 @@ void ThreadSchedule::dumpDotFile(const string& filename) const {
|
|||
}
|
||||
}
|
||||
const double minWidth = 2.0;
|
||||
auto mtaskXPos = [&](const ExecMTask* mtaskp, const double nodeWidth) {
|
||||
const auto mtaskXPos = [&](const ExecMTask* mtaskp, const double nodeWidth) {
|
||||
const double startPosX = (minWidth * startTime(mtaskp)) / minCost;
|
||||
return nodeWidth / minWidth + startPosX;
|
||||
};
|
||||
|
||||
auto emitMTask = [&](const ExecMTask* mtaskp) {
|
||||
const auto emitMTask = [&](const ExecMTask* mtaskp) {
|
||||
const int thread = threadId(mtaskp);
|
||||
const double nodeWidth = minWidth * (static_cast<double>(mtaskp->cost()) / minCost);
|
||||
const double x = mtaskXPos(mtaskp, nodeWidth);
|
||||
const int y = -thread;
|
||||
string label = "label=\"" + mtaskp->name() + " (" + cvtToStr(startTime(mtaskp)) + ":"
|
||||
+ std::to_string(endTime(mtaskp)) + ")" + "\"";
|
||||
const string label = "label=\"" + mtaskp->name() + " (" + cvtToStr(startTime(mtaskp)) + ":"
|
||||
+ std::to_string(endTime(mtaskp)) + ")" + "\"";
|
||||
*logp << " " << mtaskp->name() << " [" << label << " width=" << nodeWidth << " pos=\""
|
||||
<< x << "," << y << "!\"]\n";
|
||||
};
|
||||
|
|
@ -2625,7 +2625,8 @@ void V3Partition::go(V3Graph* mtasksp) {
|
|||
// when scheduling them.
|
||||
const unsigned fudgeNumerator = 3;
|
||||
const unsigned fudgeDenominator = 5;
|
||||
uint32_t cpLimit = ((totalGraphCost * fudgeNumerator) / (targetParFactor * fudgeDenominator));
|
||||
const uint32_t cpLimit
|
||||
= ((totalGraphCost * fudgeNumerator) / (targetParFactor * fudgeDenominator));
|
||||
UINFO(4, "V3Partition set cpLimit = " << cpLimit << endl);
|
||||
|
||||
// Merge MTask nodes together, repeatedly, until the CP budget is
|
||||
|
|
@ -2672,7 +2673,7 @@ void V3Partition::go(V3Graph* mtasksp) {
|
|||
|
||||
// Set color to indicate an mtaskId on every underlying MTaskMoveVertex.
|
||||
for (V3GraphVertex* itp = mtasksp->verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
LogicMTask* const mtaskp = dynamic_cast<LogicMTask*>(itp);
|
||||
const LogicMTask* const mtaskp = dynamic_cast<LogicMTask*>(itp);
|
||||
for (LogicMTask::VxList::const_iterator it = mtaskp->vertexListp()->begin();
|
||||
it != mtaskp->vertexListp()->end(); ++it) {
|
||||
MTaskMoveVertex* const mvertexp = *it;
|
||||
|
|
@ -2728,7 +2729,7 @@ static void normalizeCosts(Costs& costs) {
|
|||
UINFO(9,
|
||||
"Post uint scale: ce = " << est.second.first << " cp=" << est.second.second << endl);
|
||||
}
|
||||
vluint64_t scaleDownTo = 10000000; // Extra room for future algorithms to add costs
|
||||
const vluint64_t scaleDownTo = 10000000; // Extra room for future algorithms to add costs
|
||||
if (maxCost > scaleDownTo) {
|
||||
const double scaleup = static_cast<double>(scaleDownTo) / static_cast<double>(maxCost);
|
||||
UINFO(5, "Scaling data to within 32-bits by multiply by=" << scaleup << ", maxCost="
|
||||
|
|
@ -2826,7 +2827,7 @@ static void fillinCosts(V3Graph* execMTaskGraphp) {
|
|||
|
||||
static void finalizeCosts(V3Graph* execMTaskGraphp) {
|
||||
GraphStreamUnordered ser(execMTaskGraphp, GraphWay::REVERSE);
|
||||
while (const V3GraphVertex* vxp = ser.nextp()) {
|
||||
while (const V3GraphVertex* const vxp = ser.nextp()) {
|
||||
ExecMTask* const mtp = dynamic_cast<ExecMTask*>(const_cast<V3GraphVertex*>(vxp));
|
||||
// "Priority" is the critical path from the start of the mtask, to
|
||||
// the end of the graph reachable from this mtask. Given the
|
||||
|
|
@ -2834,7 +2835,7 @@ static void finalizeCosts(V3Graph* execMTaskGraphp) {
|
|||
// highest priority one first, so we're always working on the "long
|
||||
// pole"
|
||||
for (V3GraphEdge* edgep = mtp->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||
ExecMTask* const followp = dynamic_cast<ExecMTask*>(edgep->top());
|
||||
const ExecMTask* const followp = dynamic_cast<ExecMTask*>(edgep->top());
|
||||
if ((followp->priority() + mtp->cost()) > mtp->priority()) {
|
||||
mtp->priority(followp->priority() + mtp->cost());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,9 +47,9 @@ class VDefine final {
|
|||
// Define class. One for each define.
|
||||
// string m_name; // Name of the define (list is keyed by this)
|
||||
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
|
||||
const string m_value; // Value of define
|
||||
const string m_params; // Parameters
|
||||
const bool m_cmdline; // Set on command line, don't `undefineall
|
||||
public:
|
||||
VDefine(FileLine* fl, const string& value, const string& params, bool cmdline)
|
||||
: m_fileline{fl}
|
||||
|
|
@ -66,8 +66,8 @@ public:
|
|||
|
||||
class VDefineRef final {
|
||||
// One for each pending define substitution
|
||||
string m_name; // Define last name being defined
|
||||
string m_params; // Define parameter list for next expansion
|
||||
const string m_name; // Define last name being defined
|
||||
const string m_params; // Define parameter list for next expansion
|
||||
string m_nextarg; // String being built for next argument
|
||||
int m_parenLevel = 0; // Parenthesis counting inside def args (for PARENT not child)
|
||||
|
||||
|
|
@ -91,8 +91,8 @@ public:
|
|||
|
||||
class VPreIfEntry final {
|
||||
// One for each pending ifdef/ifndef
|
||||
bool m_on; // Current parse for this ifdef level is "on"
|
||||
bool m_everOn; // Some if term in elsif tree has been on
|
||||
const bool m_on; // Current parse for this ifdef level is "on"
|
||||
const bool m_everOn; // Some if term in elsif tree has been on
|
||||
public:
|
||||
bool on() const { return m_on; }
|
||||
bool everOn() const { return m_everOn; }
|
||||
|
|
@ -117,7 +117,7 @@ public:
|
|||
DefinesMap m_defines; ///< Map of defines
|
||||
|
||||
// STATE
|
||||
V3PreProc* m_preprocp = nullptr; ///< Object we're holding data for
|
||||
const V3PreProc* m_preprocp = nullptr; ///< Object we're holding data for
|
||||
V3PreLex* m_lexp = nullptr; ///< Current lexer state (nullptr = closed)
|
||||
std::stack<V3PreLex*> m_includeStack; ///< Stack of includers above current m_lexp
|
||||
int m_lastLineno = 0; // Last line number (stall detection)
|
||||
|
|
@ -496,7 +496,7 @@ void V3PreProc::debug(int level) {
|
|||
}
|
||||
|
||||
FileLine* V3PreProc::fileline() {
|
||||
V3PreProcImp* idatap = static_cast<V3PreProcImp*>(this);
|
||||
const V3PreProcImp* idatap = static_cast<V3PreProcImp*>(this);
|
||||
return idatap->m_lexp->m_tokFilelinep;
|
||||
}
|
||||
|
||||
|
|
@ -1180,7 +1180,7 @@ int V3PreProcImp::getStateToken() {
|
|||
if (VL_UNCOVERABLE(m_defRefs.empty())) {
|
||||
fatalSrc("Shouldn't be in DEFPAREN w/o active defref");
|
||||
}
|
||||
VDefineRef* const refp = &(m_defRefs.top());
|
||||
const VDefineRef* const refp = &(m_defRefs.top());
|
||||
error(string("Expecting ( to begin argument list for define reference `")
|
||||
+ refp->name() + "\n");
|
||||
statePop();
|
||||
|
|
@ -1612,7 +1612,7 @@ string V3PreProcImp::getline() {
|
|||
|
||||
// Make new string with data up to the newline.
|
||||
const int len = rtnp - m_lineChars.c_str() + 1;
|
||||
string theLine(m_lineChars, 0, len);
|
||||
const string theLine(m_lineChars, 0, len);
|
||||
m_lineChars = m_lineChars.erase(0, len); // Remove returned characters
|
||||
if (debug() >= 4) {
|
||||
const string lncln = V3PreLex::cleanDbgStrg(theLine);
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ private:
|
|||
// Shifts of > 32/64 bits in C++ will wrap-around and generate non-0s
|
||||
if (!nodep->user2SetOnce()) {
|
||||
UINFO(4, " ShiftFix " << nodep << endl);
|
||||
const AstConst* shiftp = VN_CAST(nodep->rhsp(), Const);
|
||||
const AstConst* const shiftp = VN_CAST(nodep->rhsp(), Const);
|
||||
if (shiftp && shiftp->num().mostSetBitP1() > 32) {
|
||||
shiftp->v3error(
|
||||
"Unsupported: Shifting of by over 32-bit number isn't supported."
|
||||
|
|
@ -279,7 +279,7 @@ private:
|
|||
AstNRelinker replaceHandle;
|
||||
nodep->unlinkFrBack(&replaceHandle);
|
||||
AstNode* constzerop;
|
||||
int m1value
|
||||
const int m1value
|
||||
= nodep->widthMin() - 1; // Constant of width-1; not changing dtype width
|
||||
if (nodep->signedFlavor()) {
|
||||
// Then over shifting gives the sign bit, not all zeros
|
||||
|
|
@ -295,10 +295,11 @@ private:
|
|||
}
|
||||
constzerop->dtypeFrom(nodep); // unsigned
|
||||
|
||||
AstNode* constwidthp = new AstConst(nodep->fileline(), AstConst::WidthedValue(),
|
||||
nodep->rhsp()->widthMin(), m1value);
|
||||
AstNode* const constwidthp
|
||||
= new AstConst(nodep->fileline(), AstConst::WidthedValue(),
|
||||
nodep->rhsp()->widthMin(), m1value);
|
||||
constwidthp->dtypeFrom(nodep->rhsp()); // unsigned
|
||||
AstCond* newp = new AstCond(
|
||||
AstCond* const newp = new AstCond(
|
||||
nodep->fileline(),
|
||||
new AstGte(nodep->fileline(), constwidthp, nodep->rhsp()->cloneTree(false)),
|
||||
nodep, constzerop);
|
||||
|
|
@ -381,7 +382,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
m_stmtp = nullptr;
|
||||
if (v3Global.opt.autoflush()) {
|
||||
AstNode* searchp = nodep->nextp();
|
||||
const AstNode* searchp = nodep->nextp();
|
||||
while (searchp && VN_IS(searchp, Comment)) searchp = searchp->nextp();
|
||||
if (searchp && VN_IS(searchp, Display)
|
||||
&& nodep->filep()->sameGateTree(VN_AS(searchp, Display)->filep())) {
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ private:
|
|||
|
||||
iterateChildren(nodep);
|
||||
|
||||
V3Hash hash = V3Hasher::uncachedHash(m_cfilep);
|
||||
const V3Hash hash = V3Hasher::uncachedHash(m_cfilep);
|
||||
m_hashValuep->addText(fl, cvtToStr(hash.value()) + ";\n");
|
||||
m_cHashValuep->addText(fl, cvtToStr(hash.value()) + "U;\n");
|
||||
m_foundTop = true;
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ private:
|
|||
= 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)) {
|
||||
} else if (const auto* const classRefp = VN_CAST(dtypep, ClassRefDType)) {
|
||||
auto* const refp
|
||||
= new AstVarRef(nodep->fileline(), memberVarp, VAccess::WRITE);
|
||||
auto* const memberFuncp = V3Randomize::newRandomizeFunc(classRefp->classp());
|
||||
|
|
@ -253,7 +253,7 @@ public:
|
|||
void V3Randomize::randomizeNetlist(AstNetlist* nodep) {
|
||||
UINFO(2, __FUNCTION__ << ": " << endl);
|
||||
{
|
||||
RandomizeMarkVisitor markVisitor{nodep};
|
||||
const RandomizeMarkVisitor markVisitor{nodep};
|
||||
RandomizeVisitor{nodep};
|
||||
}
|
||||
V3Global::dumpCheckGlobalTree("randomize", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||
|
|
|
|||
|
|
@ -54,13 +54,13 @@ private:
|
|||
|
||||
std::vector<AstNodeAssign*> m_mgAssignps; // List of assignments merging
|
||||
AstCFunc* m_mgCfuncp = nullptr; // Parent C function
|
||||
AstNode* m_mgNextp = nullptr; // Next node
|
||||
AstNodeSel* m_mgSelLp = nullptr; // Parent select, nullptr = idle
|
||||
AstNodeSel* m_mgSelRp = nullptr; // Parent select, nullptr = constant
|
||||
AstNodeVarRef* m_mgVarrefLp = nullptr; // Parent varref
|
||||
AstNodeVarRef* m_mgVarrefRp = nullptr; // Parent varref, nullptr = constant
|
||||
const AstNode* m_mgNextp = nullptr; // Next node
|
||||
const AstNodeSel* m_mgSelLp = nullptr; // Parent select, nullptr = idle
|
||||
const AstNodeSel* m_mgSelRp = nullptr; // Parent select, nullptr = constant
|
||||
const AstNodeVarRef* m_mgVarrefLp = nullptr; // Parent varref
|
||||
const AstNodeVarRef* m_mgVarrefRp = nullptr; // Parent varref, nullptr = constant
|
||||
int64_t m_mgOffset = 0; // Index offset
|
||||
AstConst* m_mgConstRp = nullptr; // Parent RHS constant, nullptr = sel
|
||||
const AstConst* m_mgConstRp = nullptr; // Parent RHS constant, nullptr = sel
|
||||
uint32_t m_mgIndexLo = 0; // Merge range
|
||||
uint32_t m_mgIndexHi = 0; // Merge range
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ private:
|
|||
}
|
||||
void mergeEnd() {
|
||||
if (!m_mgAssignps.empty()) {
|
||||
uint32_t items = m_mgIndexHi - m_mgIndexLo + 1;
|
||||
const uint32_t items = m_mgIndexHi - m_mgIndexLo + 1;
|
||||
UINFO(9, "End merge iter=" << items << " " << m_mgIndexHi << ":" << m_mgIndexLo << " "
|
||||
<< m_mgOffset << " " << m_mgAssignps[0] << endl);
|
||||
if (items >= static_cast<uint32_t>(v3Global.opt.reloopLimit())) {
|
||||
|
|
@ -162,7 +162,7 @@ private:
|
|||
if (!m_cfuncp) return;
|
||||
|
||||
// Left select WordSel or ArraySel
|
||||
AstNodeSel* lselp = VN_CAST(nodep->lhsp(), NodeSel);
|
||||
AstNodeSel* const lselp = VN_CAST(nodep->lhsp(), NodeSel);
|
||||
if (!lselp) { // Not ever merged
|
||||
mergeEnd();
|
||||
return;
|
||||
|
|
@ -179,16 +179,16 @@ private:
|
|||
}
|
||||
const uint32_t lindex = lbitp->toUInt();
|
||||
// Of variable
|
||||
AstNodeVarRef* const lvarrefp = VN_CAST(lselp->fromp(), NodeVarRef);
|
||||
const AstNodeVarRef* const lvarrefp = VN_CAST(lselp->fromp(), NodeVarRef);
|
||||
if (!lvarrefp) {
|
||||
mergeEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
// RHS is a constant or a select
|
||||
AstConst* const rconstp = VN_CAST(nodep->rhsp(), Const);
|
||||
AstNodeSel* const rselp = VN_CAST(nodep->rhsp(), NodeSel);
|
||||
AstNodeVarRef* rvarrefp = nullptr;
|
||||
const AstConst* const rconstp = VN_CAST(nodep->rhsp(), Const);
|
||||
const AstNodeSel* const rselp = VN_CAST(nodep->rhsp(), NodeSel);
|
||||
const AstNodeVarRef* rvarrefp = nullptr;
|
||||
uint32_t rindex = lindex;
|
||||
if (rconstp) { // Ok
|
||||
} else if (rselp) {
|
||||
|
|
|
|||
|
|
@ -401,7 +401,7 @@ public:
|
|||
void V3Scope::scopeAll(AstNetlist* nodep) {
|
||||
UINFO(2, __FUNCTION__ << ": " << endl);
|
||||
{
|
||||
ScopeVisitor visitor{nodep};
|
||||
const ScopeVisitor visitor{nodep};
|
||||
ScopeCleanupVisitor{nodep};
|
||||
} // Destruct before checking
|
||||
V3Global::dumpCheckGlobalTree("scope", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||
|
|
|
|||
|
|
@ -355,7 +355,7 @@ private:
|
|||
class CmpElems final {
|
||||
public:
|
||||
bool operator()(const T_Elem* const& ap, const T_Elem* const& bp) const {
|
||||
T_ElemCompare cmp;
|
||||
const T_ElemCompare cmp;
|
||||
return cmp.operator()(*ap, *bp);
|
||||
}
|
||||
};
|
||||
|
|
@ -369,8 +369,8 @@ private:
|
|||
// set members, set is better performant.
|
||||
std::set<const T_Elem*> m_unknown; // Elements with unknown scores
|
||||
SortedMap m_sorted; // Set of elements with known scores
|
||||
UserScoreFnp m_scoreFnp; // Scoring function
|
||||
bool m_slowAsserts; // Do some asserts that require extra lookups
|
||||
const UserScoreFnp m_scoreFnp; // Scoring function
|
||||
const bool m_slowAsserts; // Do some asserts that require extra lookups
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
|
|||
114
src/V3Simulate.h
114
src/V3Simulate.h
|
|
@ -115,10 +115,10 @@ private:
|
|||
|
||||
// Potentially very slow, intended for debugging
|
||||
string prettyNumber(const V3Number* nump, AstNodeDType* dtypep) {
|
||||
if (AstRefDType* refdtypep = VN_CAST(dtypep, RefDType)) { //
|
||||
if (AstRefDType* const refdtypep = VN_CAST(dtypep, RefDType)) { //
|
||||
dtypep = refdtypep->skipRefp();
|
||||
}
|
||||
if (AstStructDType* stp = VN_CAST(dtypep, StructDType)) {
|
||||
if (AstStructDType* const stp = VN_CAST(dtypep, StructDType)) {
|
||||
if (stp->packed()) {
|
||||
std::ostringstream out;
|
||||
out << "'{";
|
||||
|
|
@ -130,7 +130,7 @@ private:
|
|||
V3Number fieldNum(nump, width);
|
||||
fieldNum.opSel(*nump, msb, lsb);
|
||||
out << itemp->name() << ": ";
|
||||
if (AstNodeDType* childTypep = itemp->subDTypep()) {
|
||||
if (AstNodeDType* const childTypep = itemp->subDTypep()) {
|
||||
out << prettyNumber(&fieldNum, childTypep);
|
||||
} else {
|
||||
out << fieldNum;
|
||||
|
|
@ -140,8 +140,8 @@ private:
|
|||
out << "}";
|
||||
return out.str();
|
||||
}
|
||||
} else if (AstPackArrayDType* arrayp = VN_CAST(dtypep, PackArrayDType)) {
|
||||
if (AstNodeDType* childTypep = arrayp->subDTypep()) {
|
||||
} else if (const AstPackArrayDType* const arrayp = VN_CAST(dtypep, PackArrayDType)) {
|
||||
if (AstNodeDType* const childTypep = arrayp->subDTypep()) {
|
||||
std::ostringstream out;
|
||||
out << "[";
|
||||
const int arrayElements = arrayp->elementsConst();
|
||||
|
|
@ -180,16 +180,16 @@ public:
|
|||
m_whyNotOptimizable = why;
|
||||
std::ostringstream stack;
|
||||
for (auto it = m_callStack.rbegin(); it != m_callStack.rend(); ++it) {
|
||||
AstFuncRef* funcp = (*it)->m_funcp;
|
||||
AstFuncRef* const funcp = (*it)->m_funcp;
|
||||
stack << "\n " << funcp->fileline() << "... Called from "
|
||||
<< funcp->prettyName() << "() with parameters:";
|
||||
V3TaskConnects* tconnects = (*it)->m_tconnects;
|
||||
for (V3TaskConnects::iterator conIt = tconnects->begin();
|
||||
conIt != tconnects->end(); ++conIt) {
|
||||
AstVar* portp = conIt->first;
|
||||
AstNode* pinp = conIt->second->exprp();
|
||||
AstNodeDType* dtypep = pinp->dtypep();
|
||||
if (AstConst* valp = fetchConstNull(pinp))
|
||||
AstVar* const portp = conIt->first;
|
||||
AstNode* const pinp = conIt->second->exprp();
|
||||
AstNodeDType* const dtypep = pinp->dtypep();
|
||||
if (AstConst* const valp = fetchConstNull(pinp))
|
||||
stack << "\n " << portp->prettyName() << " = "
|
||||
<< prettyNumber(&valp->num(), dtypep);
|
||||
}
|
||||
|
|
@ -245,7 +245,7 @@ private:
|
|||
|
||||
public:
|
||||
void newValue(AstNode* nodep, const AstNode* valuep) {
|
||||
if (const AstConst* constp = VN_CAST(valuep, Const)) {
|
||||
if (const AstConst* const constp = VN_CAST(valuep, Const)) {
|
||||
newConst(nodep)->num().opAssign(constp->num());
|
||||
} else if (fetchValueNull(nodep) != valuep) {
|
||||
// const_cast, as clonep() is set on valuep, but nothing should care
|
||||
|
|
@ -253,7 +253,7 @@ public:
|
|||
}
|
||||
}
|
||||
void newOutValue(AstNode* nodep, const AstNode* valuep) {
|
||||
if (const AstConst* constp = VN_CAST(valuep, Const)) {
|
||||
if (const AstConst* const constp = VN_CAST(valuep, Const)) {
|
||||
newOutConst(nodep)->num().opAssign(constp->num());
|
||||
} else if (fetchOutValueNull(nodep) != valuep) {
|
||||
// const_cast, as clonep() is set on valuep, but nothing should care
|
||||
|
|
@ -263,14 +263,14 @@ public:
|
|||
|
||||
private:
|
||||
AstNode* newTrackedClone(AstNode* nodep) {
|
||||
AstNode* newp = nodep->cloneTree(false);
|
||||
AstNode* const newp = nodep->cloneTree(false);
|
||||
m_reclaimValuesp.push_back(newp);
|
||||
return newp;
|
||||
}
|
||||
AstConst* newConst(AstNode* nodep) {
|
||||
// Set a constant value for this node
|
||||
if (!VN_IS(nodep->user3p(), Const)) {
|
||||
AstConst* constp = allocConst(nodep);
|
||||
AstConst* const constp = allocConst(nodep);
|
||||
setValue(nodep, constp);
|
||||
return constp;
|
||||
} else {
|
||||
|
|
@ -280,7 +280,7 @@ private:
|
|||
AstConst* newOutConst(AstNode* nodep) {
|
||||
// Set a var-output constant value for this node
|
||||
if (!VN_IS(nodep->user2p(), Const)) {
|
||||
AstConst* constp = allocConst(nodep);
|
||||
AstConst* const constp = allocConst(nodep);
|
||||
setOutValue(nodep, constp);
|
||||
return constp;
|
||||
} else {
|
||||
|
|
@ -298,31 +298,31 @@ private:
|
|||
return VN_CAST(fetchOutValueNull(nodep), Const);
|
||||
}
|
||||
AstNode* fetchValue(AstNode* nodep) {
|
||||
AstNode* valuep = fetchValueNull(nodep);
|
||||
AstNode* const valuep = fetchValueNull(nodep);
|
||||
UASSERT_OBJ(valuep, nodep, "No value found for node.");
|
||||
// UINFO(9, " fetch val " << *valuep << " on " << nodep << endl);
|
||||
return valuep;
|
||||
}
|
||||
AstConst* fetchConst(AstNode* nodep) {
|
||||
AstConst* constp = fetchConstNull(nodep);
|
||||
AstConst* const constp = fetchConstNull(nodep);
|
||||
UASSERT_OBJ(constp, nodep, "No value found for node.");
|
||||
// UINFO(9, " fetch num " << *constp << " on " << nodep << endl);
|
||||
return constp;
|
||||
}
|
||||
AstConst* fetchOutConst(AstNode* nodep) {
|
||||
AstConst* constp = fetchOutConstNull(nodep);
|
||||
AstConst* const constp = fetchOutConstNull(nodep);
|
||||
UASSERT_OBJ(constp, nodep, "No value found for node.");
|
||||
return constp;
|
||||
}
|
||||
|
||||
public:
|
||||
V3Number* fetchNumberNull(AstNode* nodep) {
|
||||
AstConst* constp = fetchConstNull(nodep);
|
||||
AstConst* const constp = fetchConstNull(nodep);
|
||||
if (constp) return &constp->num();
|
||||
return nullptr;
|
||||
}
|
||||
V3Number* fetchOutNumberNull(AstNode* nodep) {
|
||||
AstConst* constp = fetchOutConstNull(nodep);
|
||||
AstConst* const constp = fetchOutConstNull(nodep);
|
||||
if (constp) return &constp->num();
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -405,7 +405,7 @@ private:
|
|||
if (!optimizable()) return; // Accelerate
|
||||
UASSERT_OBJ(nodep->varp(), nodep, "Unlinked");
|
||||
iterateChildren(nodep->varp());
|
||||
AstNode* vscp = varOrScope(nodep);
|
||||
AstNode* const vscp = varOrScope(nodep);
|
||||
|
||||
// We can't have non-delayed assignments with same value on LHS and RHS
|
||||
// as we don't figure out variable ordering.
|
||||
|
|
@ -438,7 +438,8 @@ private:
|
|||
}
|
||||
vscp->user1(vscp->user1() | VU_RV);
|
||||
const bool isConst = nodep->varp()->isParam() && nodep->varp()->valuep();
|
||||
AstNode* valuep = isConst ? fetchValueNull(nodep->varp()->valuep()) : nullptr;
|
||||
AstNode* const valuep
|
||||
= isConst ? fetchValueNull(nodep->varp()->valuep()) : nullptr;
|
||||
if (isConst
|
||||
&& valuep) { // Propagate PARAM constants for constant function analysis
|
||||
if (!m_checkOnly && optimizable()) newValue(vscp, valuep);
|
||||
|
|
@ -526,7 +527,7 @@ private:
|
|||
checkNodeInfo(nodep);
|
||||
UASSERT_OBJ(nodep->itemp(), nodep, "Not linked");
|
||||
if (!m_checkOnly && optimizable()) {
|
||||
AstNode* valuep = nodep->itemp()->valuep();
|
||||
AstNode* const valuep = nodep->itemp()->valuep();
|
||||
if (valuep) {
|
||||
iterateAndNextNull(valuep);
|
||||
if (optimizable()) newValue(nodep, fetchValue(valuep));
|
||||
|
|
@ -619,7 +620,8 @@ private:
|
|||
iterate(nodep->lhsp());
|
||||
if (optimizable()) {
|
||||
if (fetchConst(nodep->lhsp())->num().isEqZero()) {
|
||||
AstConst cnst(nodep->fileline(), AstConst::WidthedValue(), 1, 1); // a one
|
||||
const AstConst cnst(nodep->fileline(), AstConst::WidthedValue(), 1,
|
||||
1); // a one
|
||||
newValue(nodep, &cnst); // a one
|
||||
} else {
|
||||
iterate(nodep->rhsp());
|
||||
|
|
@ -656,29 +658,30 @@ private:
|
|||
// To do better, we need the concept of lvalues, or similar, to know where/how to insert
|
||||
checkNodeInfo(selp);
|
||||
iterateAndNextNull(selp->bitp()); // Bit index
|
||||
AstVarRef* varrefp = VN_CAST(selp->fromp(), VarRef);
|
||||
AstVarRef* const varrefp = VN_CAST(selp->fromp(), VarRef);
|
||||
if (!varrefp) {
|
||||
clearOptimizable(nodep, "Array select LHS isn't simple variable");
|
||||
return;
|
||||
}
|
||||
AstUnpackArrayDType* arrayp = VN_AS(varrefp->varp()->dtypeSkipRefp(), UnpackArrayDType);
|
||||
AstUnpackArrayDType* const arrayp
|
||||
= VN_AS(varrefp->varp()->dtypeSkipRefp(), UnpackArrayDType);
|
||||
UASSERT_OBJ(arrayp, nodep, "Array select of non-array dtype");
|
||||
AstBasicDType* basicp = VN_CAST(arrayp->subDTypep()->skipRefp(), BasicDType);
|
||||
AstBasicDType* const basicp = VN_CAST(arrayp->subDTypep()->skipRefp(), BasicDType);
|
||||
if (!basicp) {
|
||||
clearOptimizable(nodep, "Array of non-basic dtype (e.g. array-of-array)");
|
||||
return;
|
||||
}
|
||||
if (!m_checkOnly && optimizable()) {
|
||||
AstNode* vscp = varOrScope(varrefp);
|
||||
AstNode* const vscp = varOrScope(varrefp);
|
||||
AstInitArray* initp = nullptr;
|
||||
if (AstInitArray* vscpnump = VN_CAST(fetchOutValueNull(vscp), InitArray)) {
|
||||
if (AstInitArray* const vscpnump = VN_CAST(fetchOutValueNull(vscp), InitArray)) {
|
||||
initp = vscpnump;
|
||||
} else if (AstInitArray* vscpnump = VN_CAST(fetchValueNull(vscp), InitArray)) {
|
||||
} else if (AstInitArray* const vscpnump = VN_CAST(fetchValueNull(vscp), InitArray)) {
|
||||
initp = vscpnump;
|
||||
} else { // Assignment to unassigned variable, all bits are X
|
||||
// TODO generic initialization which builds X/arrays by recursion
|
||||
AstConst* outconstp = new AstConst(nodep->fileline(), AstConst::WidthedValue(),
|
||||
basicp->widthMin(), 0);
|
||||
AstConst* const outconstp = new AstConst(
|
||||
nodep->fileline(), AstConst::WidthedValue(), basicp->widthMin(), 0);
|
||||
if (basicp->isZeroInit()) {
|
||||
outconstp->num().setAllBits0();
|
||||
} else {
|
||||
|
|
@ -688,8 +691,8 @@ private:
|
|||
initp = new AstInitArray(nodep->fileline(), arrayp, outconstp);
|
||||
m_reclaimValuesp.push_back(initp);
|
||||
}
|
||||
uint32_t index = fetchConst(selp->bitp())->toUInt();
|
||||
AstNode* valuep = newTrackedClone(fetchValue(nodep->rhsp()));
|
||||
const uint32_t index = fetchConst(selp->bitp())->toUInt();
|
||||
AstNode* const valuep = newTrackedClone(fetchValue(nodep->rhsp()));
|
||||
UINFO(9, " set val[" << index << "] = " << valuep << endl);
|
||||
// Values are in the "real" tree under the InitArray so can eventually extract it,
|
||||
// Not in the usual setValue (pointed to by user2/3p)
|
||||
|
|
@ -706,11 +709,11 @@ private:
|
|||
if (!m_checkOnly && optimizable()) {
|
||||
UASSERT_OBJ(varrefp, nodep,
|
||||
"Indicated optimizable, but no variable found on RHS of select");
|
||||
AstNode* vscp = varOrScope(varrefp);
|
||||
AstNode* const vscp = varOrScope(varrefp);
|
||||
AstConst* outconstp = nullptr;
|
||||
if (AstConst* vscpnump = fetchOutConstNull(vscp)) {
|
||||
if (AstConst* const vscpnump = fetchOutConstNull(vscp)) {
|
||||
outconstp = vscpnump;
|
||||
} else if (AstConst* vscpnump = fetchConstNull(vscp)) {
|
||||
} else if (AstConst* const vscpnump = fetchConstNull(vscp)) {
|
||||
outconstp = vscpnump;
|
||||
} else { // Assignment to unassigned variable, all bits are X or 0
|
||||
outconstp = new AstConst(nodep->fileline(), AstConst::WidthedValue(),
|
||||
|
|
@ -731,11 +734,11 @@ private:
|
|||
// lsb to be eventually set on lsbRef
|
||||
checkNodeInfo(selp);
|
||||
iterateAndNextNull(selp->lsbp()); // Bit index
|
||||
if (AstVarRef* varrefp = VN_CAST(selp->fromp(), VarRef)) {
|
||||
if (AstVarRef* const varrefp = VN_CAST(selp->fromp(), VarRef)) {
|
||||
outVarrefpRef = varrefp;
|
||||
lsbRef = fetchConst(selp->lsbp())->num();
|
||||
return; // And presumably still optimizable()
|
||||
} else if (AstSel* subselp = VN_CAST(selp->lhsp(), Sel)) {
|
||||
} else if (AstSel* const subselp = VN_CAST(selp->lhsp(), Sel)) {
|
||||
V3Number sublsb(nodep);
|
||||
handleAssignSelRecurse(nodep, subselp, outVarrefpRef, sublsb /*ref*/, depth + 1);
|
||||
if (optimizable()) {
|
||||
|
|
@ -759,13 +762,13 @@ private:
|
|||
m_anyAssignComb = true;
|
||||
}
|
||||
|
||||
if (AstSel* selp = VN_CAST(nodep->lhsp(), Sel)) {
|
||||
if (AstSel* const selp = VN_CAST(nodep->lhsp(), Sel)) {
|
||||
if (!m_params) {
|
||||
clearOptimizable(nodep, "LHS has select");
|
||||
return;
|
||||
}
|
||||
handleAssignSel(nodep, selp);
|
||||
} else if (AstArraySel* selp = VN_CAST(nodep->lhsp(), ArraySel)) {
|
||||
} else if (AstArraySel* const selp = VN_CAST(nodep->lhsp(), ArraySel)) {
|
||||
if (!m_params) {
|
||||
clearOptimizable(nodep, "LHS has select");
|
||||
return;
|
||||
|
|
@ -778,7 +781,7 @@ private:
|
|||
} else if (optimizable()) {
|
||||
iterateAndNextNull(nodep->rhsp());
|
||||
if (optimizable()) {
|
||||
AstNode* vscp = varOrScope(VN_CAST(nodep->lhsp(), VarRef));
|
||||
AstNode* const vscp = varOrScope(VN_CAST(nodep->lhsp(), VarRef));
|
||||
assignOutValue(nodep, vscp, fetchValue(nodep->rhsp()));
|
||||
}
|
||||
}
|
||||
|
|
@ -787,10 +790,10 @@ private:
|
|||
virtual void visit(AstArraySel* nodep) override {
|
||||
checkNodeInfo(nodep);
|
||||
iterateChildren(nodep);
|
||||
if (AstInitArray* initp = VN_CAST(fetchValueNull(nodep->fromp()), InitArray)) {
|
||||
AstConst* indexp = fetchConst(nodep->bitp());
|
||||
uint32_t offset = indexp->num().toUInt();
|
||||
AstNode* itemp = initp->getIndexDefaultedValuep(offset);
|
||||
if (AstInitArray* const initp = VN_CAST(fetchValueNull(nodep->fromp()), InitArray)) {
|
||||
AstConst* const indexp = fetchConst(nodep->bitp());
|
||||
const uint32_t offset = indexp->num().toUInt();
|
||||
AstNode* const itemp = initp->getIndexDefaultedValuep(offset);
|
||||
if (!itemp) {
|
||||
clearOptimizable(nodep, "Array initialization has too few elements, need element "
|
||||
+ cvtToStr(offset));
|
||||
|
|
@ -977,8 +980,8 @@ private:
|
|||
// Must do this in two steps, eval all params, then apply them
|
||||
// Otherwise chained functions may have the wrong results
|
||||
for (V3TaskConnects::iterator it = tconnects.begin(); it != tconnects.end(); ++it) {
|
||||
AstVar* portp = it->first;
|
||||
AstNode* pinp = it->second->exprp();
|
||||
AstVar* const portp = it->first;
|
||||
AstNode* const pinp = it->second->exprp();
|
||||
if (pinp) { // Else too few arguments in function call - ignore it
|
||||
if (portp->isWritable()) {
|
||||
clearOptimizable(
|
||||
|
|
@ -991,8 +994,8 @@ private:
|
|||
}
|
||||
}
|
||||
for (V3TaskConnects::iterator it = tconnects.begin(); it != tconnects.end(); ++it) {
|
||||
AstVar* portp = it->first;
|
||||
AstNode* pinp = it->second->exprp();
|
||||
AstVar* const portp = it->first;
|
||||
AstNode* const pinp = it->second->exprp();
|
||||
if (pinp) { // Else too few arguments in function call - ignore it
|
||||
// Apply value to the function
|
||||
if (!m_checkOnly && optimizable()) newValue(portp, fetchValue(pinp));
|
||||
|
|
@ -1002,7 +1005,7 @@ private:
|
|||
// cppcheck-suppress danglingLifetime
|
||||
m_callStack.push_back(&stackNode);
|
||||
// Clear output variable
|
||||
if (auto* const basicp = VN_CAST(funcp->fvarp(), Var)->basicp()) {
|
||||
if (const auto* const basicp = VN_CAST(funcp->fvarp(), Var)->basicp()) {
|
||||
AstConst cnst(funcp->fvarp()->fileline(), AstConst::WidthedValue(), basicp->widthMin(),
|
||||
0);
|
||||
if (basicp->isZeroInit()) {
|
||||
|
|
@ -1055,9 +1058,9 @@ private:
|
|||
inPct = false;
|
||||
|
||||
if (V3Number::displayedFmtLegal(tolower(pos[0]), false)) {
|
||||
AstNode* argp = nextArgp;
|
||||
AstNode* const argp = nextArgp;
|
||||
nextArgp = nextArgp->nextp();
|
||||
AstConst* constp = fetchConstNull(argp);
|
||||
AstConst* const constp = fetchConstNull(argp);
|
||||
if (!constp) {
|
||||
clearOptimizable(
|
||||
nodep, "Argument for $display like statement is not constant");
|
||||
|
|
@ -1081,7 +1084,8 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
AstConst* resultConstp = new AstConst(nodep->fileline(), AstConst::String(), result);
|
||||
AstConst* const resultConstp
|
||||
= new AstConst(nodep->fileline(), AstConst::String(), result);
|
||||
setValue(nodep, resultConstp);
|
||||
m_reclaimValuesp.push_back(resultConstp);
|
||||
}
|
||||
|
|
@ -1092,7 +1096,7 @@ private:
|
|||
if (!optimizable()) return; // Accelerate
|
||||
iterateChildren(nodep);
|
||||
if (m_params) {
|
||||
AstConst* textp = fetchConst(nodep->fmtp());
|
||||
AstConst* const textp = fetchConst(nodep->fmtp());
|
||||
switch (nodep->displayType()) {
|
||||
case AstDisplayType::DT_DISPLAY: // FALLTHRU
|
||||
case AstDisplayType::DT_INFO: v3warn(USERINFO, textp->name()); break;
|
||||
|
|
|
|||
|
|
@ -97,12 +97,12 @@ class SliceVisitor final : public AstNVisitor {
|
|||
itemp = initp->initsp();
|
||||
}
|
||||
newp = itemp->cloneTree(false);
|
||||
} else if (AstNodeCond* snodep = VN_CAST(nodep, NodeCond)) {
|
||||
} else if (AstNodeCond* const snodep = VN_CAST(nodep, NodeCond)) {
|
||||
UINFO(9, " cloneCond(" << elements << "," << offset << ") " << nodep << endl);
|
||||
return snodep->cloneType(snodep->condp()->cloneTree(false),
|
||||
cloneAndSel(snodep->expr1p(), elements, offset),
|
||||
cloneAndSel(snodep->expr2p(), elements, offset));
|
||||
} else if (AstSliceSel* snodep = VN_CAST(nodep, SliceSel)) {
|
||||
} else if (const AstSliceSel* const snodep = VN_CAST(nodep, SliceSel)) {
|
||||
UINFO(9, " cloneSliceSel(" << elements << "," << offset << ") " << nodep << endl);
|
||||
const int leOffset = (snodep->declRange().lo()
|
||||
+ (!snodep->declRange().littleEndian()
|
||||
|
|
|
|||
|
|
@ -322,7 +322,7 @@ protected:
|
|||
vertexp = vertexp->verticesNextp()) {
|
||||
if (!vertexp->outBeginp() && dynamic_cast<SplitVarStdVertex*>(vertexp)) {
|
||||
if (debug() >= 9) {
|
||||
SplitVarStdVertex* const stdp = static_cast<SplitVarStdVertex*>(vertexp);
|
||||
const SplitVarStdVertex* const stdp = static_cast<SplitVarStdVertex*>(vertexp);
|
||||
UINFO(0, "Will prune deps on var " << stdp->nodep() << endl);
|
||||
stdp->nodep()->dumpTree(cout, "- ");
|
||||
}
|
||||
|
|
@ -477,7 +477,8 @@ protected:
|
|||
// vertexes not involved with this step as unimportant
|
||||
for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp;
|
||||
vertexp = vertexp->verticesNextp()) {
|
||||
if (SplitLogicVertex* const vvertexp = dynamic_cast<SplitLogicVertex*>(vertexp)) {
|
||||
if (const SplitLogicVertex* const vvertexp
|
||||
= dynamic_cast<SplitLogicVertex*>(vertexp)) {
|
||||
if (!vvertexp->user()) {
|
||||
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep;
|
||||
edgep = edgep->inNextp()) {
|
||||
|
|
@ -502,7 +503,7 @@ protected:
|
|||
for (AstNode* nextp = nodep; nextp; nextp = nextp->nextp()) {
|
||||
SplitLogicVertex* const vvertexp
|
||||
= reinterpret_cast<SplitLogicVertex*>(nextp->user3p());
|
||||
uint32_t color = vvertexp->color();
|
||||
const uint32_t color = vvertexp->color();
|
||||
UASSERT_OBJ(color, nextp, "No node color assigned");
|
||||
if (lastOfColor[color]) {
|
||||
new SplitStrictEdge(&m_graph, lastOfColor[color], vvertexp);
|
||||
|
|
@ -526,7 +527,7 @@ protected:
|
|||
std::multimap<uint32_t, AstNode*> rankMap;
|
||||
int currOrder = 0; // Existing sequence number of assignment
|
||||
for (AstNode* nextp = nodep; nextp; nextp = nextp->nextp()) {
|
||||
SplitLogicVertex* const vvertexp
|
||||
const SplitLogicVertex* const vvertexp
|
||||
= reinterpret_cast<SplitLogicVertex*>(nextp->user3p());
|
||||
rankMap.emplace(vvertexp->rank(), nextp);
|
||||
nextp->user4(++currOrder); // Record current ordering
|
||||
|
|
@ -536,7 +537,7 @@ protected:
|
|||
bool leaveAlone = true;
|
||||
int newOrder = 0; // New sequence number of assignment
|
||||
for (auto it = rankMap.cbegin(); it != rankMap.cend(); ++it) {
|
||||
AstNode* const nextp = it->second;
|
||||
const AstNode* const nextp = it->second;
|
||||
if (++newOrder != nextp->user4()) leaveAlone = false;
|
||||
}
|
||||
if (leaveAlone) {
|
||||
|
|
@ -650,8 +651,9 @@ public:
|
|||
private:
|
||||
void trackNode(AstNode* nodep) {
|
||||
if (nodep->user3p()) {
|
||||
SplitLogicVertex* const vertexp = reinterpret_cast<SplitLogicVertex*>(nodep->user3p());
|
||||
uint32_t color = vertexp->color();
|
||||
const SplitLogicVertex* const vertexp
|
||||
= reinterpret_cast<SplitLogicVertex*>(nodep->user3p());
|
||||
const uint32_t color = vertexp->color();
|
||||
m_colors.insert(color);
|
||||
UINFO(8, " SVL " << vertexp << " has color " << color << "\n");
|
||||
|
||||
|
|
@ -681,7 +683,7 @@ private:
|
|||
|
||||
class EmitSplitVisitor final : public AstNVisitor {
|
||||
// MEMBERS
|
||||
AstAlways* const m_origAlwaysp; // Block that *this will split
|
||||
const 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
|
||||
|
|
@ -747,8 +749,8 @@ protected:
|
|||
UASSERT_OBJ(nodep->user3p(), nodep, "null user3p in V3Split leaf");
|
||||
|
||||
// Clone the leaf into its new always block
|
||||
SplitLogicVertex* const vxp = reinterpret_cast<SplitLogicVertex*>(nodep->user3p());
|
||||
uint32_t color = vxp->color();
|
||||
const SplitLogicVertex* const vxp = reinterpret_cast<SplitLogicVertex*>(nodep->user3p());
|
||||
const uint32_t color = vxp->color();
|
||||
AstNode* const clonedp = nodep->cloneTree(false);
|
||||
m_addAfter[color]->addNextHere(clonedp);
|
||||
m_addAfter[color] = clonedp;
|
||||
|
|
@ -765,7 +767,7 @@ protected:
|
|||
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);
|
||||
const AstIf* const origp = VN_CAST(nodep, If);
|
||||
if (origp) {
|
||||
// Preserve pragmas from unique if's
|
||||
// so assertions work properly
|
||||
|
|
@ -817,7 +819,7 @@ private:
|
|||
std::unordered_map<AstAlways*, AlwaysVec> m_replaceBlocks;
|
||||
|
||||
// AstNodeIf* whose condition we're currently visiting
|
||||
AstNode* m_curIfConditional = nullptr;
|
||||
const AstNode* m_curIfConditional = nullptr;
|
||||
|
||||
// CONSTRUCTORS
|
||||
public:
|
||||
|
|
@ -832,7 +834,7 @@ public:
|
|||
for (AlwaysVec::iterator addme = it->second.begin(); addme != it->second.end();
|
||||
++addme) {
|
||||
origp->addNextHere(*addme);
|
||||
RemovePlaceholdersVisitor removePlaceholders(*addme);
|
||||
RemovePlaceholdersVisitor{*addme};
|
||||
}
|
||||
origp->unlinkFrBack(); // Without next
|
||||
VL_DO_DANGLING(origp->deleteTree(), origp);
|
||||
|
|
@ -847,7 +849,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* const ifNodep = VN_CAST((*it)->nodep(), NodeIf);
|
||||
const AstNodeIf* const ifNodep = VN_CAST((*it)->nodep(), NodeIf);
|
||||
if (ifNodep && (m_curIfConditional != ifNodep)) continue;
|
||||
new SplitRVEdge(&m_graph, *it, vstdp);
|
||||
}
|
||||
|
|
@ -871,15 +873,15 @@ protected:
|
|||
// inputs) prune all edges that depend on the 'if'.
|
||||
for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp;
|
||||
vertexp = vertexp->verticesNextp()) {
|
||||
SplitLogicVertex* const logicp = dynamic_cast<SplitLogicVertex*>(vertexp);
|
||||
const SplitLogicVertex* const logicp = dynamic_cast<SplitLogicVertex*>(vertexp);
|
||||
if (!logicp) continue;
|
||||
|
||||
AstNodeIf* const ifNodep = VN_CAST(logicp->nodep(), NodeIf);
|
||||
const AstNodeIf* const ifNodep = VN_CAST(logicp->nodep(), NodeIf);
|
||||
if (!ifNodep) continue;
|
||||
|
||||
bool pruneMe = true;
|
||||
for (V3GraphEdge* edgep = logicp->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||
SplitEdge* const oedgep = dynamic_cast<SplitEdge*>(edgep);
|
||||
const 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.
|
||||
|
|
@ -889,7 +891,7 @@ protected:
|
|||
// give a hint about why...
|
||||
if (debug() >= 9) {
|
||||
V3GraphVertex* vxp = oedgep->top();
|
||||
SplitNodeVertex* const nvxp = dynamic_cast<SplitNodeVertex*>(vxp);
|
||||
const 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, "- ");
|
||||
|
|
@ -936,7 +938,7 @@ protected:
|
|||
|
||||
// Map each AstNodeIf to the set of colors (split always blocks)
|
||||
// it must participate in. Also find the whole set of colors.
|
||||
IfColorVisitor ifColor{nodep};
|
||||
const IfColorVisitor ifColor{nodep};
|
||||
|
||||
if (ifColor.colors().size() > 1) {
|
||||
// Counting original always blocks rather than newly-split
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ class SplitAsCleanVisitor final : public SplitAsBaseVisitor {
|
|||
private:
|
||||
// STATE
|
||||
AstVarScope* const m_splitVscp; // Variable we want to split
|
||||
bool m_modeMatch; // Remove matching Vscp, else non-matching
|
||||
const 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
|
||||
|
||||
|
|
@ -144,11 +144,11 @@ private:
|
|||
newp->user1(true); // So we don't clone it again
|
||||
nodep->addNextHere(newp);
|
||||
{ // Delete stuff we don't want in old
|
||||
SplitAsCleanVisitor visitor{nodep, m_splitVscp, false};
|
||||
const SplitAsCleanVisitor visitor{nodep, m_splitVscp, false};
|
||||
if (debug() >= 9) nodep->dumpTree(cout, "-out0: ");
|
||||
}
|
||||
{ // Delete stuff we don't want in new
|
||||
SplitAsCleanVisitor visitor{newp, m_splitVscp, true};
|
||||
const SplitAsCleanVisitor visitor{newp, m_splitVscp, true};
|
||||
if (debug() >= 9) newp->dumpTree(cout, "-out1: ");
|
||||
}
|
||||
}
|
||||
|
|
@ -159,7 +159,7 @@ private:
|
|||
const AstVarScope* lastSplitVscp = nullptr;
|
||||
while (!nodep->user1()) {
|
||||
// Find any splittable variables
|
||||
SplitAsFindVisitor visitor{nodep};
|
||||
const SplitAsFindVisitor visitor{nodep};
|
||||
m_splitVscp = visitor.splitVscp();
|
||||
if (m_splitVscp && m_splitVscp == lastSplitVscp) {
|
||||
// We did this last time! Something's stuck!
|
||||
|
|
|
|||
|
|
@ -249,13 +249,13 @@ struct AstNodeComparator {
|
|||
|
||||
class UnpackRef final {
|
||||
// m_nodep is called in this context (AstNodeStmt, AstCell, AstNodeFTask, or AstAlways)
|
||||
AstNode* m_contextp;
|
||||
AstNode* m_nodep; // ArraySel, SliceSel, ArrayVarRef (entire value)
|
||||
int m_index; // for ArraySel
|
||||
int m_msb; // for SliceSel
|
||||
int m_lsb; // for SliceSel
|
||||
VAccess m_access;
|
||||
bool m_ftask; // true if the reference is in function/task. false if in module.
|
||||
AstNode* const m_contextp;
|
||||
AstNode* const m_nodep; // ArraySel, SliceSel, ArrayVarRef (entire value)
|
||||
const int m_index; // for ArraySel
|
||||
const int m_msb; // for SliceSel
|
||||
const int m_lsb; // for SliceSel
|
||||
const VAccess m_access;
|
||||
const bool m_ftask; // true if the reference is in function/task. false if in module.
|
||||
public:
|
||||
UnpackRef(AstNode* stmtp, AstVarRef* nodep, bool ftask)
|
||||
: m_contextp{stmtp}
|
||||
|
|
@ -402,7 +402,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
|||
AstNodeModule* m_modp = nullptr;
|
||||
// AstNodeStmt, AstCell, AstNodeFTaskRef, or AstAlways(Public) for sensitivity
|
||||
AstNode* m_contextp = nullptr;
|
||||
AstNodeFTask* m_inFTask = nullptr;
|
||||
const AstNodeFTask* m_inFTask = nullptr;
|
||||
size_t m_numSplit = 0;
|
||||
// List for SplitPackedVarVisitor
|
||||
SplitVarRefsMap m_refsForPackedSplit;
|
||||
|
|
@ -490,13 +490,13 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
|||
VL_RESTORER(m_contextp);
|
||||
{
|
||||
m_contextp = nodep;
|
||||
AstNodeFTask* const ftaskp = nodep->taskp();
|
||||
const AstNodeFTask* const ftaskp = nodep->taskp();
|
||||
UASSERT_OBJ(ftaskp, nodep, "Unlinked");
|
||||
// Iterate arguments of a function/task.
|
||||
for (AstNode *argp = nodep->pinsp(), *paramp = ftaskp->stmtsp(); argp;
|
||||
argp = argp->nextp(), paramp = paramp ? paramp->nextp() : nullptr) {
|
||||
const char* reason = nullptr;
|
||||
AstVar* vparamp = nullptr;
|
||||
const AstVar* vparamp = nullptr;
|
||||
while (paramp) {
|
||||
vparamp = VN_CAST(paramp, Var);
|
||||
if (vparamp && vparamp->isIO()) {
|
||||
|
|
@ -527,7 +527,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
|||
if (!exprp) return; // Not connected pin
|
||||
m_foundTargetVar.clear();
|
||||
iterate(exprp);
|
||||
if (const char* reason = cannotSplitConnectedPortReason(nodep)) {
|
||||
if (const char* const reason = cannotSplitConnectedPortReason(nodep)) {
|
||||
for (AstVar* const varp : m_foundTargetVar) {
|
||||
warnNoSplit(varp, nodep, reason);
|
||||
m_refs.remove(varp);
|
||||
|
|
@ -564,7 +564,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
|||
}
|
||||
virtual void visit(AstArraySel* nodep) override {
|
||||
if (AstVarRef* const refp = isTargetVref(nodep->fromp())) {
|
||||
AstConst* const indexp = VN_CAST(nodep->bitp(), Const);
|
||||
const AstConst* const indexp = VN_CAST(nodep->bitp(), Const);
|
||||
if (indexp) { // OK
|
||||
UINFO(4, "add " << nodep << " for " << refp->varp()->prettyName() << "\n");
|
||||
if (indexp->toSInt() < outerMostSizeOfUnpackedArray(refp->varp())) {
|
||||
|
|
@ -601,7 +601,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
|||
}
|
||||
}
|
||||
AstNode* toInsertPoint(AstNode* insertp) {
|
||||
if (AstNodeStmt* const stmtp = VN_CAST(insertp, NodeStmt)) {
|
||||
if (const AstNodeStmt* const stmtp = VN_CAST(insertp, NodeStmt)) {
|
||||
if (!stmtp->isStatement()) insertp = stmtp->backp();
|
||||
}
|
||||
return insertp;
|
||||
|
|
@ -630,7 +630,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
|||
= newVarRef(fl, vars.at(start_idx + i), lvalue ? VAccess::WRITE : VAccess::READ);
|
||||
AstNode* rhsp = new AstArraySel{
|
||||
fl, newVarRef(fl, varp, !lvalue ? VAccess::WRITE : VAccess::READ), i};
|
||||
AstNode* refp = lhsp;
|
||||
AstNode* const refp = lhsp;
|
||||
UINFO(9, "Creating assign idx:" << i << " + " << start_idx << "\n");
|
||||
if (!lvalue) std::swap(lhsp, rhsp);
|
||||
AstNode* newassignp;
|
||||
|
|
@ -699,7 +699,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
|||
// Unpacked array is traced as var(idx), not var[idx].
|
||||
const std::string name
|
||||
= varp->name() + AstNode::encodeName('(' + cvtToStr(i + dtypep->lo()) + ')');
|
||||
AstVar* newp = newVar(varp->fileline(), AstVarType::VAR, name, subTypep);
|
||||
AstVar* const newp = newVar(varp->fileline(), AstVarType::VAR, name, subTypep);
|
||||
newp->propagateAttrFrom(varp);
|
||||
// If varp is an IO, varp will remain and will be traced.
|
||||
newp->trace(!varp->isIO() && varp->isTrace());
|
||||
|
|
@ -721,7 +721,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
|||
if (refp) {
|
||||
adtypep = VN_AS(refp->dtypep()->skipRefp(), UnpackArrayDType);
|
||||
} else {
|
||||
AstSliceSel* selp = VN_AS(ref.nodep(), SliceSel);
|
||||
AstSliceSel* const selp = VN_AS(ref.nodep(), SliceSel);
|
||||
UASSERT_OBJ(selp, ref.nodep(), "Unexpected op is registered");
|
||||
refp = VN_AS(selp->fromp(), VarRef);
|
||||
UASSERT_OBJ(refp, selp, "Unexpected op is registered");
|
||||
|
|
@ -809,8 +809,8 @@ public:
|
|||
|
||||
// Split variable
|
||||
class SplitNewVar final {
|
||||
int m_lsb; // LSB in the original bitvector
|
||||
int m_bitwidth;
|
||||
const int m_lsb; // LSB in the original bitvector
|
||||
const int m_bitwidth;
|
||||
AstVar* m_varp; // The LSB of this variable is always 0, not m_lsb
|
||||
public:
|
||||
SplitNewVar(int lsb, int bitwidth, AstVar* varp = nullptr)
|
||||
|
|
@ -835,9 +835,9 @@ public:
|
|||
|
||||
// One Entry instance for an AstVarRef instance
|
||||
class PackedVarRefEntry final {
|
||||
AstNode* m_nodep; // Either AstSel or AstVarRef is expected.
|
||||
int m_lsb;
|
||||
int m_bitwidth;
|
||||
AstNode* const m_nodep; // Either AstSel or AstVarRef is expected.
|
||||
const int m_lsb;
|
||||
const int m_bitwidth;
|
||||
|
||||
public:
|
||||
PackedVarRefEntry(AstSel* selp, int lsb, int bitwidth)
|
||||
|
|
@ -859,7 +859,7 @@ public:
|
|||
// If this is AstVarRef and referred in the sensitivity list of always@,
|
||||
// return the sensitivity item
|
||||
AstSenItem* backSenItemp() const {
|
||||
if (AstVarRef* const refp = VN_CAST(m_nodep, VarRef)) {
|
||||
if (const AstVarRef* const refp = VN_CAST(m_nodep, VarRef)) {
|
||||
return VN_CAST(refp->backp(), SenItem);
|
||||
}
|
||||
return nullptr;
|
||||
|
|
@ -875,7 +875,7 @@ class PackedVarRef final {
|
|||
}
|
||||
};
|
||||
std::vector<PackedVarRefEntry> m_lhs, m_rhs;
|
||||
AstBasicDType* m_basicp; // Cache the ptr since varp->dtypep()->basicp() is expensive
|
||||
AstBasicDType* const m_basicp; // Cache the ptr since varp->dtypep()->basicp() is expensive
|
||||
bool m_dedupDone = false;
|
||||
static void dedupRefs(std::vector<PackedVarRefEntry>& refs) {
|
||||
// Use raw pointer to dedup
|
||||
|
|
@ -959,8 +959,8 @@ public:
|
|||
};
|
||||
|
||||
class SplitPackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
||||
AstNetlist* m_netp;
|
||||
AstNodeModule* m_modp = nullptr; // Current module (just for log)
|
||||
AstNetlist* const m_netp;
|
||||
const AstNodeModule* m_modp = nullptr; // Current module (just for log)
|
||||
int m_numSplit = 0; // Total number of split variables
|
||||
// key:variable to be split. value:location where the variable is referenced.
|
||||
std::map<AstVar*, PackedVarRef, AstNodeComparator> m_refs;
|
||||
|
|
@ -985,14 +985,14 @@ class SplitPackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
|||
UASSERT_OBJ(varp->attrSplitVar(), varp, "split_var attribute must be attached");
|
||||
UASSERT_OBJ(!nodep->classOrPackagep(), nodep,
|
||||
"variable in package must have been dropped beforehand.");
|
||||
const AstBasicDType* basicp = refit->second.basicp();
|
||||
const AstBasicDType* const basicp = refit->second.basicp();
|
||||
refit->second.append(PackedVarRefEntry(nodep, basicp->lo(), varp->width()),
|
||||
nodep->access());
|
||||
UINFO(5, varp->prettyName()
|
||||
<< " Entire bit of [" << basicp->lo() << "+:" << varp->width() << "] \n");
|
||||
}
|
||||
virtual void visit(AstSel* nodep) override {
|
||||
AstVarRef* const vrefp = VN_CAST(nodep->fromp(), VarRef);
|
||||
const AstVarRef* const vrefp = VN_CAST(nodep->fromp(), VarRef);
|
||||
if (!vrefp) {
|
||||
iterateChildren(nodep);
|
||||
return;
|
||||
|
|
@ -1006,7 +1006,7 @@ class SplitPackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
|||
}
|
||||
UASSERT_OBJ(varp->attrSplitVar(), varp, "split_var attribute must be attached");
|
||||
|
||||
std::array<AstConst*, 2> consts
|
||||
const std::array<AstConst*, 2> consts
|
||||
= {{VN_CAST(nodep->lsbp(), Const),
|
||||
VN_CAST(nodep->widthp(), Const)}}; // GCC 3.8.0 wants {{}}
|
||||
if (consts[0] && consts[1]) { // OK
|
||||
|
|
@ -1224,7 +1224,7 @@ public:
|
|||
// when the access to the variable cannot be determined statically.
|
||||
static const char* cannotSplitReason(const AstVar* nodep, bool checkUnpacked) {
|
||||
const char* reason = nullptr;
|
||||
if (AstBasicDType* const basicp = nodep->dtypep()->basicp()) {
|
||||
if (const AstBasicDType* const basicp = nodep->dtypep()->basicp()) {
|
||||
const std::pair<uint32_t, uint32_t> dim = nodep->dtypep()->dimensions(false);
|
||||
// Unpacked array will be split in SplitUnpackedVarVisitor() beforehand
|
||||
if (!((!checkUnpacked || dim.second == 0) && nodep->dtypep()->widthMin() > 1))
|
||||
|
|
@ -1255,7 +1255,7 @@ void V3SplitVar::splitVariable(AstNetlist* nodep) {
|
|||
UINFO(2, __FUNCTION__ << ": " << endl);
|
||||
SplitVarRefsMap refs;
|
||||
{
|
||||
SplitUnpackedVarVisitor visitor{nodep};
|
||||
const SplitUnpackedVarVisitor visitor{nodep};
|
||||
refs = visitor.getPackedVarRefs();
|
||||
}
|
||||
V3Global::dumpCheckGlobalTree("split_var", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 9);
|
||||
|
|
|
|||
|
|
@ -37,12 +37,12 @@ private:
|
|||
using NameMap = std::map<const std::string, int>; // Number of times a name appears
|
||||
|
||||
// STATE
|
||||
string m_stage; // Name of the stage we are scanning
|
||||
const string m_stage; // Name of the stage we are scanning
|
||||
/// m_fast = true: Counting only critical branch of fastpath
|
||||
/// m_fast = false: Counting every node, ignoring structure of program
|
||||
bool m_fast;
|
||||
const bool m_fast;
|
||||
|
||||
AstCFunc* m_cfuncp; // Current CFUNC
|
||||
const AstCFunc* m_cfuncp; // Current CFUNC
|
||||
bool m_counting; // Currently counting
|
||||
double m_instrs; // Current instr count (for determining branch direction)
|
||||
bool m_tracingCall; // Iterating into a CCall to a CFunc
|
||||
|
|
@ -233,7 +233,7 @@ public:
|
|||
const double count = double(m_statVarWidths.at(i));
|
||||
if (count != 0.0) {
|
||||
if (v3Global.opt.statsVars()) {
|
||||
NameMap& nameMapr = m_statVarWidthNames.at(i);
|
||||
const NameMap& nameMapr = m_statVarWidthNames.at(i);
|
||||
for (const auto& itr : nameMapr) {
|
||||
std::ostringstream os;
|
||||
os << "Vars, width " << std::setw(5) << std::dec << i << " " << itr.first;
|
||||
|
|
|
|||
|
|
@ -67,11 +67,11 @@ public:
|
|||
|
||||
class V3Statistic final {
|
||||
// A statistical entry we want published into the database
|
||||
string m_name; ///< Nameiption of this statistic
|
||||
const string m_name; ///< Name of this statistic
|
||||
double m_count; ///< Count of occurrences/ value
|
||||
string m_stage; ///< Runtime stage
|
||||
bool m_sumit; ///< Do summation of similar stats
|
||||
bool m_perf; ///< Performance section
|
||||
const string m_stage; ///< Runtime stage
|
||||
const bool m_sumit; ///< Do summation of similar stats
|
||||
const bool m_perf; ///< Performance section
|
||||
bool m_printit = true; ///< Print the results
|
||||
public:
|
||||
// METHODS
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ void V3Stats::statsReport() {
|
|||
std::ofstream* ofp{V3File::new_ofstream(filename)};
|
||||
if (ofp->fail()) v3fatal("Can't write " << filename);
|
||||
|
||||
StatsReport reporter(ofp);
|
||||
const StatsReport reporter(ofp);
|
||||
|
||||
// Cleanup
|
||||
ofp->close();
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ double VString::parseDouble(const string& str, bool* successp) {
|
|||
}
|
||||
*dp++ = '\0';
|
||||
char* endp = strgp;
|
||||
double d = strtod(strgp, &endp);
|
||||
const double d = strtod(strgp, &endp);
|
||||
const size_t parsed_len = endp - strgp;
|
||||
if (parsed_len != strlen(strgp)) {
|
||||
if (successp) *successp = false;
|
||||
|
|
@ -321,7 +321,7 @@ uint64_t VHashSha256::digestUInt64() {
|
|||
const string& binhash = digestBinary();
|
||||
uint64_t out = 0;
|
||||
for (size_t byte = 0; byte < sizeof(uint64_t); ++byte) {
|
||||
unsigned char c = binhash[byte];
|
||||
const unsigned char c = binhash[byte];
|
||||
out = (out << 8) | c;
|
||||
}
|
||||
return out;
|
||||
|
|
@ -411,14 +411,14 @@ string VName::dehash(const string& in) {
|
|||
const string::size_type next_dot_pos = in.find("__DOT__", last_dot_pos);
|
||||
// Two iterators defining the range between the last and next dots.
|
||||
const auto search_begin = std::begin(in) + last_dot_pos;
|
||||
auto search_end
|
||||
const auto search_end
|
||||
= next_dot_pos == string::npos ? std::end(in) : std::begin(in) + next_dot_pos;
|
||||
|
||||
// Search for __Vhsh between the two dots.
|
||||
auto begin_vhsh
|
||||
const auto begin_vhsh
|
||||
= std::search(search_begin, search_end, std::begin(VHSH), std::end(VHSH) - 1);
|
||||
if (begin_vhsh != search_end) {
|
||||
std::string vhsh(begin_vhsh, search_end);
|
||||
const std::string vhsh(begin_vhsh, search_end);
|
||||
const auto& it = s_dehashMap.find(vhsh);
|
||||
UASSERT(it != s_dehashMap.end(), "String not in reverse hash map '" << vhsh << "'");
|
||||
// Is this not the first component, but the first to require dehashing?
|
||||
|
|
@ -582,7 +582,7 @@ void VSpellCheck::selfTest() {
|
|||
selfTestSuggestOne(false, "sqrt", "assert", 3);
|
||||
}
|
||||
{
|
||||
VSpellCheck speller;
|
||||
const VSpellCheck speller;
|
||||
UASSERT_SELFTEST(string, "", speller.bestCandidate(""));
|
||||
}
|
||||
{
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ private:
|
|||
// See SubstVisitor
|
||||
//
|
||||
// STATE
|
||||
int m_origStep; // Step number where subst was recorded
|
||||
const int m_origStep; // Step number where subst was recorded
|
||||
bool m_ok = true; // No misassignments found
|
||||
|
||||
// METHODS
|
||||
|
|
@ -274,7 +274,7 @@ private:
|
|||
entryp->assignWhole(m_assignStep, nodep);
|
||||
}
|
||||
}
|
||||
} else if (AstWordSel* wordp = VN_CAST(nodep->lhsp(), WordSel)) {
|
||||
} else if (const AstWordSel* const wordp = VN_CAST(nodep->lhsp(), WordSel)) {
|
||||
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();
|
||||
|
|
@ -315,7 +315,7 @@ private:
|
|||
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)};
|
||||
const SubstUseVisitor visitor{substp, entryp->getWordStep(word)};
|
||||
if (visitor.ok()) {
|
||||
VL_DO_DANGLING(replaceSubstEtc(nodep, substp), nodep);
|
||||
} else {
|
||||
|
|
@ -340,9 +340,9 @@ private:
|
|||
if (nodep->access().isWriteOrRW()) {
|
||||
UINFO(8, " ASSIGNcpx " << nodep << endl);
|
||||
entryp->assignComplex();
|
||||
} else if (AstNode* substp = entryp->substWhole(nodep)) {
|
||||
} else if (AstNode* const substp = entryp->substWhole(nodep)) {
|
||||
// Check that the RHS hasn't changed value since we recorded it.
|
||||
SubstUseVisitor visitor{substp, entryp->getWholeStep()};
|
||||
const SubstUseVisitor visitor{substp, entryp->getWholeStep()};
|
||||
if (visitor.ok()) {
|
||||
UINFO(8, " USEwhole " << nodep << endl);
|
||||
VL_DO_DANGLING(replaceSubstEtc(nodep, substp), nodep);
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ public:
|
|||
VSymEnt* findIdFallback(const string& name) const {
|
||||
// Find identifier looking upward through symbol hierarchy
|
||||
// First, scan this begin/end block or module for the name
|
||||
if (VSymEnt* entp = findIdFlat(name)) return entp;
|
||||
if (VSymEnt* const entp = findIdFlat(name)) return entp;
|
||||
// Then scan the upper begin/end block or module for the name
|
||||
if (m_fallbackp) return m_fallbackp->findIdFallback(name);
|
||||
return nullptr;
|
||||
|
|
@ -166,7 +166,7 @@ public:
|
|||
void candidateIdFlat(VSpellCheck* spellerp, const VNodeMatcher* matcherp) const {
|
||||
// Suggest alternative symbol candidates without looking upward through symbol hierarchy
|
||||
for (IdNameMap::const_iterator it = m_idNameMap.begin(); it != m_idNameMap.end(); ++it) {
|
||||
const AstNode* itemp = it->second->nodep();
|
||||
const AstNode* const itemp = it->second->nodep();
|
||||
if (itemp && (!matcherp || matcherp->nodeMatch(itemp))) {
|
||||
spellerp->pushCandidate(itemp->prettyName());
|
||||
}
|
||||
|
|
@ -185,7 +185,7 @@ private:
|
|||
bool honorExport) {
|
||||
if ((!honorExport || srcp->exported())
|
||||
&& !findIdFlat(name)) { // Don't insert over existing entry
|
||||
VSymEnt* symp = new VSymEnt(graphp, srcp);
|
||||
VSymEnt* const symp = new VSymEnt(graphp, srcp);
|
||||
symp->exported(false); // Can't reimport an import without an export
|
||||
symp->imported(true);
|
||||
reinsert(name, symp);
|
||||
|
|
@ -193,7 +193,7 @@ private:
|
|||
}
|
||||
void exportOneSymbol(VSymGraph* graphp, const string& name, const VSymEnt* srcp) const {
|
||||
if (srcp->exported()) {
|
||||
if (VSymEnt* symp = findIdFlat(name)) { // Should already exist in current table
|
||||
if (VSymEnt* const symp = findIdFlat(name)) { // Should already exist in current table
|
||||
if (!symp->exported()) symp->exported(true);
|
||||
}
|
||||
}
|
||||
|
|
@ -237,7 +237,7 @@ public:
|
|||
void exportStarStar(VSymGraph* graphp) {
|
||||
// Export *:*: Export all tokens from imported packages
|
||||
for (IdNameMap::const_iterator it = m_idNameMap.begin(); it != m_idNameMap.end(); ++it) {
|
||||
VSymEnt* symp = it->second;
|
||||
VSymEnt* const symp = it->second;
|
||||
if (!symp->exported()) symp->exported(true);
|
||||
}
|
||||
}
|
||||
|
|
@ -247,10 +247,10 @@ public:
|
|||
for (IdNameMap::const_iterator it = srcp->m_idNameMap.begin();
|
||||
it != srcp->m_idNameMap.end(); ++it) {
|
||||
const string& name = it->first;
|
||||
VSymEnt* subSrcp = it->second;
|
||||
const AstVar* varp = VN_CAST(subSrcp->nodep(), Var);
|
||||
VSymEnt* const subSrcp = it->second;
|
||||
const AstVar* const varp = VN_CAST(subSrcp->nodep(), Var);
|
||||
if (!onlyUnmodportable || (varp && varp->isParam())) {
|
||||
VSymEnt* subSymp = new VSymEnt(graphp, subSrcp);
|
||||
VSymEnt* const subSymp = new VSymEnt(graphp, subSrcp);
|
||||
reinsert(name, subSymp);
|
||||
// And recurse to create children
|
||||
subSymp->importFromIface(graphp, subSrcp);
|
||||
|
|
@ -261,7 +261,7 @@ public:
|
|||
if (prettyName == "") prettyName = lookp->prettyName();
|
||||
string scopes;
|
||||
for (IdNameMap::iterator it = m_idNameMap.begin(); it != m_idNameMap.end(); ++it) {
|
||||
AstNode* itemp = it->second->nodep();
|
||||
AstNode* const itemp = it->second->nodep();
|
||||
if (VN_IS(itemp, Cell) || (VN_IS(itemp, Module) && VN_AS(itemp, Module)->isTop())) {
|
||||
if (scopes != "") scopes += ", ";
|
||||
scopes += AstNode::prettyName(it->first);
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ VL_DEBUG_FUNC; // Declare debug()
|
|||
// Vertex that tracks a per-vertex key
|
||||
template <typename T_Key> class TspVertexTmpl : public V3GraphVertex {
|
||||
private:
|
||||
T_Key m_key;
|
||||
const T_Key m_key;
|
||||
|
||||
public:
|
||||
TspVertexTmpl(V3Graph* graphp, const T_Key& k)
|
||||
|
|
@ -112,7 +112,7 @@ public:
|
|||
|
||||
bool empty() const { return m_vertices.empty(); }
|
||||
|
||||
std::list<Vertex*> keysToVertexList(const std::vector<T_Key>& odds) {
|
||||
const std::list<Vertex*> keysToVertexList(const std::vector<T_Key>& odds) {
|
||||
std::list<Vertex*> vertices;
|
||||
for (unsigned i = 0; i < odds.size(); ++i) { vertices.push_back(findVertex(odds.at(i))); }
|
||||
return vertices;
|
||||
|
|
@ -177,7 +177,7 @@ public:
|
|||
unsigned edges_made = 0;
|
||||
while (!pendingEdges.empty()) {
|
||||
const auto firstIt = pendingEdges.cbegin();
|
||||
V3GraphEdge* bestEdgep = *firstIt;
|
||||
const V3GraphEdge* bestEdgep = *firstIt;
|
||||
pendingEdges.erase(firstIt);
|
||||
|
||||
// bestEdgep->fromp() should be already seen
|
||||
|
|
@ -298,7 +298,7 @@ public:
|
|||
|
||||
// Look for an arbitrary edge we've not yet marked
|
||||
for (V3GraphEdge* edgep = cur_vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||
vluint32_t edgeId = edgep->user();
|
||||
const vluint32_t edgeId = edgep->user();
|
||||
if (markedEdgesp->end() == markedEdgesp->find(edgeId)) {
|
||||
// This edge is not yet marked, so follow it.
|
||||
markedEdgesp->insert(edgeId);
|
||||
|
|
@ -322,7 +322,7 @@ public:
|
|||
recursed = false;
|
||||
// Look for an arbitrary edge at vxp we've not yet marked
|
||||
for (V3GraphEdge* edgep = vxp->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||
vluint32_t edgeId = edgep->user();
|
||||
const vluint32_t edgeId = edgep->user();
|
||||
if (markedEdgesp->end() == markedEdgesp->find(edgeId)) {
|
||||
UINFO(6, "Recursing.\n");
|
||||
findEulerTourRecurse(markedEdgesp, vxp, sortedOutp);
|
||||
|
|
@ -423,7 +423,7 @@ void V3TSP::tspSort(const V3TSP::StateVec& states, V3TSP::StateVec* resultp) {
|
|||
graph.makeMinSpanningTree(&minGraph);
|
||||
if (debug() >= 6) minGraph.dumpGraphFilePrefixed("minGraph");
|
||||
|
||||
std::vector<const TspStateBase*> oddDegree = minGraph.getOddDegreeKeys();
|
||||
const std::vector<const TspStateBase*> oddDegree = minGraph.getOddDegreeKeys();
|
||||
Graph matching;
|
||||
graph.perfectMatching(oddDegree, &matching);
|
||||
if (debug() >= 6) matching.dumpGraphFilePrefixed("matching");
|
||||
|
|
@ -526,9 +526,9 @@ public:
|
|||
bool operator<(const TspTestState& other) const { return m_serial < other.m_serial; }
|
||||
|
||||
private:
|
||||
unsigned m_xpos;
|
||||
unsigned m_ypos;
|
||||
unsigned m_serial;
|
||||
const unsigned m_xpos;
|
||||
const unsigned m_ypos;
|
||||
const unsigned m_serial;
|
||||
static unsigned s_serialNext;
|
||||
};
|
||||
|
||||
|
|
@ -538,11 +538,11 @@ void V3TSP::selfTestStates() {
|
|||
// Linear test -- coords all along the x-axis
|
||||
{
|
||||
V3TSP::StateVec states;
|
||||
TspTestState s10(10, 0);
|
||||
TspTestState s60(60, 0);
|
||||
TspTestState s20(20, 0);
|
||||
TspTestState s100(100, 0);
|
||||
TspTestState s5(5, 0);
|
||||
const TspTestState s10(10, 0);
|
||||
const TspTestState s60(60, 0);
|
||||
const TspTestState s20(20, 0);
|
||||
const TspTestState s100(100, 0);
|
||||
const TspTestState s5(5, 0);
|
||||
states.push_back(&s10);
|
||||
states.push_back(&s60);
|
||||
states.push_back(&s20);
|
||||
|
|
@ -572,13 +572,13 @@ void V3TSP::selfTestStates() {
|
|||
// Test that tspSort() will rotate the list for minimum cost.
|
||||
{
|
||||
V3TSP::StateVec states;
|
||||
TspTestState a(0, 0);
|
||||
TspTestState b(100, 0);
|
||||
TspTestState c(200, 0);
|
||||
TspTestState d(200, 100);
|
||||
TspTestState e(150, 150);
|
||||
TspTestState f(0, 150);
|
||||
TspTestState g(0, 100);
|
||||
const TspTestState a(0, 0);
|
||||
const TspTestState b(100, 0);
|
||||
const TspTestState c(200, 0);
|
||||
const TspTestState d(200, 100);
|
||||
const TspTestState e(150, 150);
|
||||
const TspTestState f(0, 150);
|
||||
const TspTestState g(0, 100);
|
||||
|
||||
states.push_back(&a);
|
||||
states.push_back(&b);
|
||||
|
|
@ -631,7 +631,7 @@ void V3TSP::selfTestString() {
|
|||
graph.makeMinSpanningTree(&minGraph);
|
||||
if (debug() >= 6) minGraph.dumpGraphFilePrefixed("minGraph");
|
||||
|
||||
std::vector<string> oddDegree = minGraph.getOddDegreeKeys();
|
||||
const std::vector<string> oddDegree = minGraph.getOddDegreeKeys();
|
||||
Graph matching;
|
||||
graph.perfectMatching(oddDegree, &matching);
|
||||
if (debug() >= 6) matching.dumpGraphFilePrefixed("matching");
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ public:
|
|||
void simulateVarRefCb(AstVarRef* nodep) {
|
||||
// Called by TableSimulateVisitor on each unique varref encountered
|
||||
UINFO(9, " SimVARREF " << nodep << endl);
|
||||
AstVarScope* vscp = nodep->varScopep();
|
||||
AstVarScope* const vscp = nodep->varScopep();
|
||||
if (nodep->access().isWriteOrRW()) {
|
||||
// We'll make the table with a separate natural alignment for each output var, so
|
||||
// always have 8, 16 or 32 bit widths, so use widthTotalBytes
|
||||
|
|
@ -265,7 +265,7 @@ private:
|
|||
// Populate the tables
|
||||
createTables(nodep, outputAssignedTableBuilder);
|
||||
|
||||
AstNode* stmtsp = createLookupInput(fl, indexVscp);
|
||||
AstNode* const stmtsp = createLookupInput(fl, indexVscp);
|
||||
createOutputAssigns(nodep, stmtsp, indexVscp, outputAssignedTableBuilder.varScopep());
|
||||
|
||||
// Link it in.
|
||||
|
|
@ -333,7 +333,7 @@ private:
|
|||
// First var in inVars becomes the LSB of the concat
|
||||
AstNode* concatp = nullptr;
|
||||
for (AstVarScope* invscp : m_inVarps) {
|
||||
AstVarRef* refp = new AstVarRef(fl, invscp, VAccess::READ);
|
||||
AstVarRef* const refp = new AstVarRef(fl, invscp, VAccess::READ);
|
||||
if (concatp) {
|
||||
concatp = new AstConcat(fl, refp, concatp);
|
||||
} else {
|
||||
|
|
|
|||
177
src/V3Task.cpp
177
src/V3Task.cpp
|
|
@ -391,7 +391,7 @@ class TaskGatherWrittenVisitor final : public AstNVisitor {
|
|||
public:
|
||||
// Gather all written non-local variables
|
||||
static const std::vector<AstVarScope*> gather(AstCFunc* funcp) {
|
||||
TaskGatherWrittenVisitor visitor{funcp};
|
||||
const TaskGatherWrittenVisitor visitor{funcp};
|
||||
return std::move(visitor.m_writtenVariables);
|
||||
}
|
||||
};
|
||||
|
|
@ -419,7 +419,7 @@ private:
|
|||
using DpiCFuncs = std::map<const string, std::tuple<AstNodeFTask*, std::string, AstCFunc*>>;
|
||||
|
||||
// STATE
|
||||
TaskStateVisitor* m_statep; // Common state between visitors
|
||||
TaskStateVisitor* const m_statep; // Common state between visitors
|
||||
AstNodeModule* m_modp = nullptr; // Current module
|
||||
AstTopScope* const m_topScopep = v3Global.rootp()->topScopep(); // The AstTopScope
|
||||
AstScope* m_scopep = nullptr; // Current scope
|
||||
|
|
@ -432,20 +432,21 @@ private:
|
|||
VL_DEBUG_FUNC; // Declare debug()
|
||||
|
||||
AstVarScope* createFuncVar(AstCFunc* funcp, const string& name, AstVar* examplep) {
|
||||
AstVar* newvarp = new AstVar(funcp->fileline(), AstVarType::BLOCKTEMP, name, examplep);
|
||||
AstVar* const newvarp
|
||||
= new AstVar(funcp->fileline(), AstVarType::BLOCKTEMP, name, examplep);
|
||||
newvarp->funcLocal(true);
|
||||
funcp->addInitsp(newvarp);
|
||||
AstVarScope* newvscp = new AstVarScope(funcp->fileline(), m_scopep, newvarp);
|
||||
AstVarScope* const newvscp = new AstVarScope(funcp->fileline(), m_scopep, newvarp);
|
||||
m_scopep->addVarp(newvscp);
|
||||
return newvscp;
|
||||
}
|
||||
AstVarScope* createInputVar(AstCFunc* funcp, const string& name, AstBasicDTypeKwd kwd) {
|
||||
AstVar* newvarp = new AstVar(funcp->fileline(), AstVarType::BLOCKTEMP, name,
|
||||
funcp->findBasicDType(kwd));
|
||||
AstVar* const newvarp = new AstVar(funcp->fileline(), AstVarType::BLOCKTEMP, name,
|
||||
funcp->findBasicDType(kwd));
|
||||
newvarp->funcLocal(true);
|
||||
newvarp->direction(VDirection::INPUT);
|
||||
funcp->addArgsp(newvarp);
|
||||
AstVarScope* newvscp = new AstVarScope(funcp->fileline(), m_scopep, newvarp);
|
||||
AstVarScope* const newvscp = new AstVarScope(funcp->fileline(), m_scopep, newvarp);
|
||||
m_scopep->addVarp(newvscp);
|
||||
return newvscp;
|
||||
}
|
||||
|
|
@ -458,11 +459,12 @@ private:
|
|||
// It shouldn't matter, as they are only local variables.
|
||||
// We choose to do it under whichever called this function, which results
|
||||
// in more cache locality.
|
||||
AstVar* newvarp = new AstVar{invarp->fileline(), AstVarType::BLOCKTEMP, name, invarp};
|
||||
AstVar* const newvarp
|
||||
= new AstVar{invarp->fileline(), AstVarType::BLOCKTEMP, name, invarp};
|
||||
newvarp->funcLocal(false);
|
||||
newvarp->propagateAttrFrom(invarp);
|
||||
m_modp->addStmtp(newvarp);
|
||||
AstVarScope* newvscp = new AstVarScope{newvarp->fileline(), m_scopep, newvarp};
|
||||
AstVarScope* const newvscp = new AstVarScope{newvarp->fileline(), m_scopep, newvarp};
|
||||
m_scopep->addVarp(newvscp);
|
||||
return newvscp;
|
||||
}
|
||||
|
|
@ -472,20 +474,20 @@ private:
|
|||
AstVarScope* outvscp) {
|
||||
// outvscp is the variable for functions only, if nullptr, it's a task
|
||||
UASSERT_OBJ(refp->taskp(), refp, "Unlinked?");
|
||||
AstNode* newbodysp
|
||||
AstNode* const newbodysp
|
||||
= AstNode::cloneTreeNull(refp->taskp()->stmtsp(), true); // Maybe nullptr
|
||||
AstNode* beginp
|
||||
AstNode* const beginp
|
||||
= new AstComment(refp->fileline(), string("Function: ") + refp->name(), true);
|
||||
if (newbodysp) beginp->addNext(newbodysp);
|
||||
if (debug() >= 9) beginp->dumpTreeAndNext(cout, "-newbegi:");
|
||||
//
|
||||
// Create input variables
|
||||
AstNode::user2ClearTree();
|
||||
V3TaskConnects tconnects = V3Task::taskConnects(refp, beginp);
|
||||
const V3TaskConnects tconnects = V3Task::taskConnects(refp, beginp);
|
||||
for (const auto& itr : tconnects) {
|
||||
AstVar* portp = itr.first;
|
||||
AstArg* argp = itr.second;
|
||||
AstNode* pinp = argp->exprp();
|
||||
AstVar* const portp = itr.first;
|
||||
AstArg* const argp = itr.second;
|
||||
AstNode* const pinp = argp->exprp();
|
||||
portp->unlinkFrBack();
|
||||
pushDeletep(portp); // Remove it from the clone (not original)
|
||||
if (!pinp) {
|
||||
|
|
@ -504,9 +506,9 @@ private:
|
|||
// Correct lvalue; see comments below
|
||||
V3LinkLValue::linkLValueSet(pinp);
|
||||
|
||||
if (AstVarRef* varrefp = VN_CAST(pinp, VarRef)) {
|
||||
if (AstVarRef* const varrefp = VN_CAST(pinp, VarRef)) {
|
||||
// Connect to this exact variable
|
||||
AstVarScope* localVscp = varrefp->varScopep();
|
||||
AstVarScope* const localVscp = varrefp->varScopep();
|
||||
UASSERT_OBJ(localVscp, varrefp, "Null var scope");
|
||||
portp->user2p(localVscp);
|
||||
pushDeletep(pinp);
|
||||
|
|
@ -525,10 +527,10 @@ private:
|
|||
|
||||
// Even if it's referencing a varref, we still make a temporary
|
||||
// Else task(x,x,x) might produce incorrect results
|
||||
AstVarScope* tempvscp
|
||||
AstVarScope* const tempvscp
|
||||
= createVarScope(portp, namePrefix + "__" + portp->shortName());
|
||||
portp->user2p(tempvscp);
|
||||
AstAssign* assp = new AstAssign(
|
||||
AstAssign* const assp = new AstAssign(
|
||||
pinp->fileline(), pinp,
|
||||
new AstVarRef(tempvscp->fileline(), tempvscp, VAccess::READ));
|
||||
assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ,
|
||||
|
|
@ -537,16 +539,16 @@ private:
|
|||
beginp->addNext(assp);
|
||||
} else if (portp->isNonOutput()) {
|
||||
// Make input variable
|
||||
AstVarScope* inVscp
|
||||
AstVarScope* const inVscp
|
||||
= createVarScope(portp, namePrefix + "__" + portp->shortName());
|
||||
portp->user2p(inVscp);
|
||||
AstAssign* assp = new AstAssign(
|
||||
AstAssign* const assp = new AstAssign(
|
||||
pinp->fileline(),
|
||||
new AstVarRef(inVscp->fileline(), inVscp, VAccess::WRITE), pinp);
|
||||
assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ,
|
||||
true); // Ok if in <= block
|
||||
// Put assignment in FRONT of all other statements
|
||||
if (AstNode* afterp = beginp->nextp()) {
|
||||
if (AstNode* const afterp = beginp->nextp()) {
|
||||
afterp->unlinkFrBackWithNext();
|
||||
assp->addNext(afterp);
|
||||
}
|
||||
|
|
@ -559,13 +561,13 @@ private:
|
|||
AstNode* nextstmtp;
|
||||
for (AstNode* stmtp = beginp; stmtp; stmtp = nextstmtp) {
|
||||
nextstmtp = stmtp->nextp();
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (AstVar* const portp = VN_CAST(stmtp, Var)) {
|
||||
// Any I/O variables that fell out of above loop were already linked
|
||||
if (!portp->user2p()) {
|
||||
// Move it to a new localized variable
|
||||
portp->unlinkFrBack();
|
||||
pushDeletep(portp); // Remove it from the clone (not original)
|
||||
AstVarScope* localVscp
|
||||
AstVarScope* const localVscp
|
||||
= createVarScope(portp, namePrefix + "__" + portp->shortName());
|
||||
portp->user2p(localVscp);
|
||||
}
|
||||
|
|
@ -580,8 +582,8 @@ private:
|
|||
// Replace variable refs
|
||||
// Iteration requires a back, so put under temporary node
|
||||
{
|
||||
AstBegin* tempp = new AstBegin(beginp->fileline(), "[EditWrapper]", beginp);
|
||||
TaskRelinkVisitor visitor{tempp};
|
||||
AstBegin* const tempp = new AstBegin(beginp->fileline(), "[EditWrapper]", beginp);
|
||||
const TaskRelinkVisitor visitor{tempp};
|
||||
tempp->stmtsp()->unlinkFrBackWithNext();
|
||||
VL_DO_DANGLING(tempp->deleteTree(), tempp);
|
||||
}
|
||||
|
|
@ -594,19 +596,19 @@ private:
|
|||
AstVarScope* outvscp, AstCNew*& cnewpr) {
|
||||
// outvscp is the variable for functions only, if nullptr, it's a task
|
||||
UASSERT_OBJ(refp->taskp(), refp, "Unlinked?");
|
||||
AstCFunc* cfuncp = m_statep->ftaskCFuncp(refp->taskp());
|
||||
AstCFunc* const cfuncp = m_statep->ftaskCFuncp(refp->taskp());
|
||||
UASSERT_OBJ(cfuncp, refp, "No non-inline task associated with this task call?");
|
||||
//
|
||||
AstNode* beginp
|
||||
AstNode* const beginp
|
||||
= new AstComment(refp->fileline(), string("Function: ") + refp->name(), true);
|
||||
AstNodeCCall* ccallp;
|
||||
if (VN_IS(refp, New)) {
|
||||
AstCNew* cnewp = new AstCNew(refp->fileline(), cfuncp);
|
||||
AstCNew* const cnewp = new AstCNew(refp->fileline(), cfuncp);
|
||||
cnewp->dtypep(refp->dtypep());
|
||||
ccallp = cnewp;
|
||||
// Parent AstNew will replace with this CNew
|
||||
cnewpr = cnewp;
|
||||
} else if (AstMethodCall* mrefp = VN_CAST(refp, MethodCall)) {
|
||||
} else if (const AstMethodCall* const mrefp = VN_CAST(refp, MethodCall)) {
|
||||
ccallp = new AstCMethodCall(refp->fileline(), mrefp->fromp()->unlinkFrBack(), cfuncp);
|
||||
beginp->addNext(ccallp);
|
||||
} else {
|
||||
|
|
@ -615,10 +617,10 @@ private:
|
|||
}
|
||||
|
||||
// Convert complicated outputs to temp signals
|
||||
V3TaskConnects tconnects = V3Task::taskConnects(refp, refp->taskp()->stmtsp());
|
||||
const V3TaskConnects tconnects = V3Task::taskConnects(refp, refp->taskp()->stmtsp());
|
||||
for (const auto& itr : tconnects) {
|
||||
AstVar* portp = itr.first;
|
||||
AstNode* pinp = itr.second->exprp();
|
||||
AstVar* const portp = itr.first;
|
||||
AstNode* const pinp = itr.second->exprp();
|
||||
if (!pinp) {
|
||||
// Too few arguments in function call
|
||||
} else {
|
||||
|
|
@ -649,11 +651,11 @@ private:
|
|||
|
||||
// Even if it's referencing a varref, we still make a temporary
|
||||
// Else task(x,x,x) might produce incorrect results
|
||||
AstVarScope* newvscp
|
||||
AstVarScope* const newvscp
|
||||
= createVarScope(portp, namePrefix + "__" + portp->shortName());
|
||||
portp->user2p(newvscp);
|
||||
pinp->replaceWith(new AstVarRef(newvscp->fileline(), newvscp, VAccess::WRITE));
|
||||
AstAssign* assp = new AstAssign(
|
||||
AstAssign* const assp = new AstAssign(
|
||||
pinp->fileline(), pinp,
|
||||
new AstVarRef(newvscp->fileline(), newvscp, VAccess::READ));
|
||||
assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ,
|
||||
|
|
@ -669,7 +671,7 @@ private:
|
|||
|
||||
if (refp->taskp()->dpiContext()) {
|
||||
// __Vscopep
|
||||
AstNode* snp = refp->scopeNamep()->unlinkFrBack();
|
||||
AstNode* const snp = refp->scopeNamep()->unlinkFrBack();
|
||||
UASSERT_OBJ(snp, refp, "Missing scoping context");
|
||||
ccallp->addArgsp(snp);
|
||||
// __Vfilenamep
|
||||
|
|
@ -684,7 +686,7 @@ private:
|
|||
for (AstNode* pinp = refp->pinsp(); pinp; pinp = nextpinp) {
|
||||
nextpinp = pinp->nextp();
|
||||
// Move pin to the CCall, removing all Arg's
|
||||
AstNode* exprp = VN_AS(pinp, Arg)->exprp();
|
||||
AstNode* const exprp = VN_AS(pinp, Arg)->exprp();
|
||||
exprp->unlinkFrBack();
|
||||
ccallp->addArgsp(exprp);
|
||||
}
|
||||
|
|
@ -705,7 +707,7 @@ private:
|
|||
dpiproto += " " + nodep->cname() + " (";
|
||||
string args;
|
||||
for (AstNode* stmtp = nodep->stmtsp(); 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() && portp != rtnvarp) {
|
||||
if (args != "") {
|
||||
args += ", ";
|
||||
|
|
@ -735,7 +737,7 @@ private:
|
|||
// Create assignment from DPI temporary into internal format
|
||||
// DPI temporary is scalar or 1D array (if unpacked array)
|
||||
// Internal representation is scalar, 1D, or multi-dimensional array (similar to SV)
|
||||
AstVar* portp = portvscp->varp();
|
||||
AstVar* const portp = portvscp->varp();
|
||||
string frstmt;
|
||||
string ket;
|
||||
const bool useSetWSvlv = TaskDpiUtils::dpiToInternalFrStmt(portp, frName, frstmt, ket);
|
||||
|
|
@ -766,7 +768,7 @@ private:
|
|||
AstNode* stmtp = nullptr;
|
||||
// extract a scalar from DPI temporary var that is scalar or 1D array
|
||||
if (useSetWSvlv) {
|
||||
AstNode* linesp = new AstText(portvscp->fileline(), frstmt + ket);
|
||||
AstNode* const linesp = new AstText(portvscp->fileline(), frstmt + ket);
|
||||
linesp->addNext(srcp);
|
||||
linesp->addNext(
|
||||
new AstText(portvscp->fileline(),
|
||||
|
|
@ -780,9 +782,9 @@ private:
|
|||
from += "[" + cvtToStr(i * coef) + "]";
|
||||
}
|
||||
from += ket;
|
||||
AstNode* rhsp = new AstSel(portp->fileline(),
|
||||
new AstCMath(portp->fileline(), from, cwidth, false), 0,
|
||||
portp->width());
|
||||
AstNode* const rhsp = new AstSel(
|
||||
portp->fileline(), new AstCMath(portp->fileline(), from, cwidth, false), 0,
|
||||
portp->width());
|
||||
stmtp = new AstAssign(portp->fileline(), srcp, rhsp);
|
||||
}
|
||||
if (i > 0) {
|
||||
|
|
@ -827,7 +829,7 @@ private:
|
|||
// If the find fails, it will throw an error
|
||||
stmt += "const VerilatedScope* __Vscopep = Verilated::dpiScope();\n";
|
||||
// If dpiScope is fails and is null; the exportFind function throws and error
|
||||
string cbtype
|
||||
const string cbtype
|
||||
= VIdProtect::protect(v3Global.opt.prefix() + "__Vcb_" + nodep->cname() + "_t");
|
||||
stmt += cbtype + " __Vcb = (" + cbtype
|
||||
+ ")(VerilatedScope::exportFind(__Vscopep, __Vfuncnum));\n"; // Can't use
|
||||
|
|
@ -842,7 +844,7 @@ private:
|
|||
+ "*)(__Vscopep->symsp())"); // Upcast w/o overhead
|
||||
AstNode* argnodesp = nullptr;
|
||||
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (AstVar* const portp = VN_CAST(stmtp, Var)) {
|
||||
if (portp->isIO() && !portp->isFuncReturn() && portp != rtnvarp) {
|
||||
// No createDpiTemp; we make a real internal variable instead
|
||||
// SAME CODE BELOW
|
||||
|
|
@ -851,11 +853,12 @@ private:
|
|||
argnodesp = argnodesp->addNext(new AstText(portp->fileline(), args, true));
|
||||
args = "";
|
||||
}
|
||||
AstVarScope* outvscp = createFuncVar(funcp, portp->name() + tmpSuffixp, portp);
|
||||
AstVarScope* const outvscp
|
||||
= createFuncVar(funcp, portp->name() + tmpSuffixp, portp);
|
||||
// No information exposure; is already visible in import/export func template
|
||||
outvscp->varp()->protect(false);
|
||||
portp->protect(false);
|
||||
AstVarRef* refp
|
||||
AstVarRef* const refp
|
||||
= new AstVarRef(portp->fileline(), outvscp,
|
||||
portp->isWritable() ? VAccess::WRITE : VAccess::READ);
|
||||
argnodesp = argnodesp->addNextNull(refp);
|
||||
|
|
@ -874,18 +877,18 @@ private:
|
|||
}
|
||||
|
||||
if (rtnvarp) {
|
||||
AstVar* portp = rtnvarp;
|
||||
AstVar* const portp = rtnvarp;
|
||||
// SAME CODE ABOVE
|
||||
args += ", ";
|
||||
if (args != "") {
|
||||
argnodesp = argnodesp->addNext(new AstText(portp->fileline(), args, true));
|
||||
args = "";
|
||||
}
|
||||
AstVarScope* outvscp = createFuncVar(funcp, portp->name() + tmpSuffixp, portp);
|
||||
AstVarScope* const outvscp = createFuncVar(funcp, portp->name() + tmpSuffixp, portp);
|
||||
// No information exposure; is already visible in import/export func template
|
||||
outvscp->varp()->protect(false);
|
||||
AstVarRef* refp = new AstVarRef(portp->fileline(), outvscp,
|
||||
portp->isWritable() ? VAccess::WRITE : VAccess::READ);
|
||||
AstVarRef* const refp = new AstVarRef(
|
||||
portp->fileline(), outvscp, portp->isWritable() ? VAccess::WRITE : VAccess::READ);
|
||||
argnodesp = argnodesp->addNextNull(refp);
|
||||
}
|
||||
|
||||
|
|
@ -893,7 +896,7 @@ private:
|
|||
// Add the variables referenced as VarRef's so that lifetime analysis
|
||||
// doesn't rip up the variables on us
|
||||
args += ");\n";
|
||||
AstCStmt* newp = new AstCStmt(nodep->fileline(), "(*__Vcb)(");
|
||||
AstCStmt* const newp = new AstCStmt(nodep->fileline(), "(*__Vcb)(");
|
||||
newp->addBodysp(argnodesp);
|
||||
VL_DANGLING(argnodesp);
|
||||
newp->addBodysp(new AstText(nodep->fileline(), args, true));
|
||||
|
|
@ -902,7 +905,7 @@ private:
|
|||
|
||||
// Convert output/inout arguments back to internal type
|
||||
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (AstVar* const portp = VN_CAST(stmtp, Var)) {
|
||||
if (portp->isIO() && portp->isWritable() && !portp->isFuncReturn()) {
|
||||
funcp->addStmtsp(createAssignInternalToDpi(portp, true, tmpSuffixp, ""));
|
||||
}
|
||||
|
|
@ -984,10 +987,10 @@ private:
|
|||
static void makePortList(AstNodeFTask* nodep, AstCFunc* dpip) {
|
||||
// Copy nodep's list of function I/O to the new dpip c function
|
||||
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (AstVar* const portp = VN_CAST(stmtp, Var)) {
|
||||
if (portp->isIO()) {
|
||||
// Move it to new function
|
||||
AstVar* newPortp = portp->cloneTree(false);
|
||||
AstVar* const newPortp = portp->cloneTree(false);
|
||||
newPortp->funcLocal(true);
|
||||
dpip->addArgsp(newPortp);
|
||||
if (!portp->basicp()) {
|
||||
|
|
@ -1011,8 +1014,8 @@ private:
|
|||
// Convert input/inout arguments to DPI types
|
||||
string args;
|
||||
for (AstNode* stmtp = cfuncp->argsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
AstVarScope* portvscp
|
||||
if (AstVar* const portp = VN_CAST(stmtp, Var)) {
|
||||
AstVarScope* const portvscp
|
||||
= VN_AS(portp->user2p(), VarScope); // Remembered when we created it earlier
|
||||
if (portp->isIO() && !portp->isFuncReturn() && portvscp != rtnvscp
|
||||
&& portp->name() != "__Vscopep" // Passed to dpiContext, not callee
|
||||
|
|
@ -1021,7 +1024,7 @@ private:
|
|||
if (args != "") args += ", ";
|
||||
|
||||
if (portp->isDpiOpenArray()) {
|
||||
AstNodeDType* dtypep = portp->dtypep()->skipRefp();
|
||||
AstNodeDType* const dtypep = portp->dtypep()->skipRefp();
|
||||
if (VN_IS(dtypep, DynArrayDType) || VN_IS(dtypep, QueueDType)) {
|
||||
v3fatalSrc("Passing dynamic array or queue as actual argument to DPI "
|
||||
"open array is not yet supported");
|
||||
|
|
@ -1038,7 +1041,7 @@ private:
|
|||
// point to this task & thread's data, in addition
|
||||
// to static info about the variable
|
||||
const string name = portp->name() + "__Vopenarray";
|
||||
string varCode
|
||||
const string varCode
|
||||
= ("VerilatedDpiOpenVar "
|
||||
// NOLINTNEXTLINE(performance-inefficient-string-concatenation)
|
||||
+ name + " (&" + propName + ", &" + portp->name() + ");\n");
|
||||
|
|
@ -1082,11 +1085,11 @@ private:
|
|||
|
||||
// Convert output/inout arguments back to internal type
|
||||
for (AstNode* stmtp = cfuncp->argsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (AstVar* const portp = VN_CAST(stmtp, Var)) {
|
||||
portp->protect(false); // No additional exposure - already part of shown proto
|
||||
if (portp->isIO() && (portp->isWritable() || portp->isFuncReturn())
|
||||
&& !portp->isDpiOpenArray()) {
|
||||
AstVarScope* portvscp = VN_AS(
|
||||
AstVarScope* const portvscp = VN_AS(
|
||||
portp->user2p(), VarScope); // Remembered when we created it earlier
|
||||
cfuncp->addStmtsp(
|
||||
createAssignDpiToInternal(portvscp, portp->name() + tmpSuffixp));
|
||||
|
|
@ -1118,11 +1121,11 @@ private:
|
|||
AstNode::user2ClearTree();
|
||||
AstVar* rtnvarp = nullptr;
|
||||
if (nodep->isFunction()) {
|
||||
AstVar* portp = VN_AS(nodep->fvarp(), Var);
|
||||
AstVar* const portp = VN_AS(nodep->fvarp(), Var);
|
||||
UASSERT_OBJ(portp, nodep, "function without function output variable");
|
||||
if (!portp->isFuncReturn()) nodep->v3error("Not marked as function return var");
|
||||
if (nodep->dpiImport() || nodep->dpiExport()) {
|
||||
AstBasicDType* bdtypep = portp->dtypep()->basicp();
|
||||
AstBasicDType* const bdtypep = portp->dtypep()->basicp();
|
||||
if (!bdtypep->isDpiPrimitive()) {
|
||||
if (bdtypep->isDpiBitVec() && portp->width() > 32) {
|
||||
portp->v3error("DPI function may not return a > 32 bits wide type "
|
||||
|
|
@ -1190,7 +1193,7 @@ private:
|
|||
string suffix; // So, make them unique
|
||||
if (!nodep->taskPublic() && !nodep->classMethod()) suffix = "_" + m_scopep->nameDotless();
|
||||
const string name = ((nodep->name() == "new") ? "new" : prefix + nodep->name() + suffix);
|
||||
AstCFunc* cfuncp = new AstCFunc(
|
||||
AstCFunc* const cfuncp = new AstCFunc(
|
||||
nodep->fileline(), name, m_scopep,
|
||||
((nodep->taskPublic() && rtnvarp) ? rtnvarp->cPubArgType(true, true) : ""));
|
||||
// It's ok to combine imports because this is just a wrapper;
|
||||
|
|
@ -1211,7 +1214,7 @@ private:
|
|||
cfuncp->pure(nodep->pure());
|
||||
if (nodep->name() == "new") {
|
||||
cfuncp->isConstructor(true);
|
||||
AstClass* classp = m_statep->getClassp(nodep);
|
||||
AstClass* const classp = m_statep->getClassp(nodep);
|
||||
if (classp->extendsp()) {
|
||||
cfuncp->ctorInits(EmitCBaseVisitor::prefixNameProtect(classp->extendsp()->classp())
|
||||
+ "(vlSymsp)");
|
||||
|
|
@ -1235,7 +1238,7 @@ private:
|
|||
}
|
||||
|
||||
if (nodep->dpiExport()) {
|
||||
AstScopeName* snp = nodep->scopeNamep();
|
||||
AstScopeName* const snp = nodep->scopeNamep();
|
||||
UASSERT_OBJ(snp, nodep, "Missing scoping context");
|
||||
snp->dpiExport(
|
||||
true); // The AstScopeName is really a statement(ish) for tracking, not a function
|
||||
|
|
@ -1246,7 +1249,7 @@ private:
|
|||
// Create list of arguments and move to function
|
||||
for (AstNode *nextp, *stmtp = nodep->stmtsp(); stmtp; stmtp = nextp) {
|
||||
nextp = stmtp->nextp();
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (AstVar* const portp = VN_CAST(stmtp, Var)) {
|
||||
if (portp->isParam() && VN_IS(portp->valuep(), InitArray)) {
|
||||
// Move array parameters in functions into constant pool
|
||||
portp->unlinkFrBack();
|
||||
|
|
@ -1264,7 +1267,8 @@ private:
|
|||
// "Normal" variable, mark inside function
|
||||
portp->funcLocal(true);
|
||||
}
|
||||
AstVarScope* newvscp = new AstVarScope{portp->fileline(), m_scopep, portp};
|
||||
AstVarScope* const newvscp
|
||||
= new AstVarScope{portp->fileline(), m_scopep, portp};
|
||||
m_scopep->addVarp(newvscp);
|
||||
portp->user2p(newvscp);
|
||||
}
|
||||
|
|
@ -1278,7 +1282,7 @@ private:
|
|||
if (rtnvarp) cfuncp->addArgsp(rtnvarp);
|
||||
|
||||
// Move body
|
||||
AstNode* bodysp = nodep->stmtsp();
|
||||
AstNode* const bodysp = nodep->stmtsp();
|
||||
if (bodysp) {
|
||||
bodysp->unlinkFrBackWithNext();
|
||||
cfuncp->addStmtsp(bodysp);
|
||||
|
|
@ -1293,8 +1297,8 @@ private:
|
|||
// Replace variable refs
|
||||
// Iteration requires a back, so put under temporary node
|
||||
{
|
||||
AstBegin* tempp = new AstBegin(cfuncp->fileline(), "[EditWrapper]", cfuncp);
|
||||
TaskRelinkVisitor visitor{tempp};
|
||||
AstBegin* const tempp = new AstBegin(cfuncp->fileline(), "[EditWrapper]", cfuncp);
|
||||
const TaskRelinkVisitor visitor{tempp};
|
||||
tempp->stmtsp()->unlinkFrBackWithNext();
|
||||
VL_DO_DANGLING(tempp->deleteTree(), tempp);
|
||||
}
|
||||
|
|
@ -1367,7 +1371,7 @@ private:
|
|||
m_insStmtp->addNextHere(newp);
|
||||
} else if (m_insMode == IM_WHILE_PRECOND) {
|
||||
UINFO(5, " IM_While_Precond " << m_insStmtp << endl);
|
||||
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);
|
||||
visitp = newp;
|
||||
|
|
@ -1430,7 +1434,7 @@ private:
|
|||
visitp = insertBeforeStmt(nodep, beginp);
|
||||
} else if (!nodep->isStatement()) {
|
||||
UASSERT_OBJ(nodep->taskp()->isFunction(), nodep, "func reference to non-function");
|
||||
AstVarRef* outrefp = new AstVarRef(nodep->fileline(), outvscp, VAccess::READ);
|
||||
AstVarRef* const outrefp = new AstVarRef(nodep->fileline(), outvscp, VAccess::READ);
|
||||
nodep->replaceWith(outrefp);
|
||||
// Insert new statements
|
||||
visitp = insertBeforeStmt(nodep, beginp);
|
||||
|
|
@ -1482,10 +1486,10 @@ private:
|
|||
if (m_statep->ftaskNoInline(nodep) && !nodep->classMethod()) {
|
||||
m_statep->checkPurity(nodep);
|
||||
}
|
||||
AstNodeFTask* clonedFuncp = nodep->cloneTree(false);
|
||||
AstNodeFTask* const clonedFuncp = nodep->cloneTree(false);
|
||||
if (nodep->isConstructor()) m_statep->remapFuncClassp(nodep, clonedFuncp);
|
||||
|
||||
AstCFunc* cfuncp = makeUserFunc(clonedFuncp, m_statep->ftaskNoInline(nodep));
|
||||
AstCFunc* const cfuncp = makeUserFunc(clonedFuncp, m_statep->ftaskNoInline(nodep));
|
||||
if (cfuncp) {
|
||||
nodep->addNextHere(cfuncp);
|
||||
if (nodep->dpiImport() || m_statep->ftaskNoInline(nodep)) {
|
||||
|
|
@ -1498,16 +1502,16 @@ private:
|
|||
// Any variables inside the function still have varscopes pointing to them.
|
||||
// We're going to delete the vars, so delete the varscopes.
|
||||
if (nodep->isFunction()) {
|
||||
if (AstVar* portp = VN_CAST(nodep->fvarp(), Var)) {
|
||||
AstVarScope* vscp = m_statep->findVarScope(m_scopep, portp);
|
||||
if (AstVar* const portp = VN_CAST(nodep->fvarp(), Var)) {
|
||||
AstVarScope* const vscp = m_statep->findVarScope(m_scopep, portp);
|
||||
UINFO(9, " funcremovevsc " << vscp << endl);
|
||||
VL_DO_DANGLING(pushDeletep(vscp->unlinkFrBack()), vscp);
|
||||
}
|
||||
}
|
||||
for (AstNode *nextp, *stmtp = nodep->stmtsp(); stmtp; stmtp = nextp) {
|
||||
nextp = stmtp->nextp();
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
AstVarScope* vscp = m_statep->findVarScope(m_scopep, portp);
|
||||
if (AstVar* const portp = VN_CAST(stmtp, Var)) {
|
||||
AstVarScope* const vscp = m_statep->findVarScope(m_scopep, portp);
|
||||
UINFO(9, " funcremovevsc " << vscp << endl);
|
||||
VL_DO_DANGLING(pushDeletep(vscp->unlinkFrBack()), vscp);
|
||||
}
|
||||
|
|
@ -1578,7 +1582,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
|
|||
int tpinnum = 0;
|
||||
AstVar* sformatp = nullptr;
|
||||
for (AstNode* stmtp = taskStmtsp; stmtp; stmtp = stmtp->nextp()) {
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (AstVar* const portp = VN_CAST(stmtp, Var)) {
|
||||
if (portp->isIO()) {
|
||||
tconnects.push_back(std::make_pair(portp, static_cast<AstArg*>(nullptr)));
|
||||
nameToIndex.insert(
|
||||
|
|
@ -1599,7 +1603,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
|
|||
bool reorganize = false;
|
||||
for (AstNode *nextp, *pinp = nodep->pinsp(); pinp; pinp = nextp) {
|
||||
nextp = pinp->nextp();
|
||||
AstArg* argp = VN_AS(pinp, Arg);
|
||||
AstArg* const argp = VN_AS(pinp, Arg);
|
||||
UASSERT_OBJ(argp, pinp, "Non-arg under ftask reference");
|
||||
if (argp->name() != "") {
|
||||
// By name
|
||||
|
|
@ -1640,7 +1644,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
|
|||
|
||||
// Connect missing ones
|
||||
for (int i = 0; i < tpinnum; ++i) {
|
||||
AstVar* portp = tconnects[i].first;
|
||||
AstVar* const portp = tconnects[i].first;
|
||||
if (!tconnects[i].second || !tconnects[i].second->exprp()) {
|
||||
AstNode* newvaluep = nullptr;
|
||||
if (!portp->valuep()) {
|
||||
|
|
@ -1671,7 +1675,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
|
|||
// To avoid problems with callee needing to know to deleteTree
|
||||
// or not, we make this into a pin
|
||||
UINFO(9, "Default pin for " << portp << endl);
|
||||
AstArg* newp = new AstArg(nodep->fileline(), portp->name(), newvaluep);
|
||||
AstArg* const newp = new AstArg(nodep->fileline(), portp->name(), newvaluep);
|
||||
if (tconnects[i].second) { // Have a "nullptr" pin already defined for it
|
||||
VL_DO_CLEAR(tconnects[i].second->unlinkFrBack()->deleteTree(),
|
||||
tconnects[i].second = nullptr);
|
||||
|
|
@ -1693,7 +1697,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
|
|||
nodep->pinsp()->unlinkFrBack();
|
||||
}
|
||||
for (int i = 0; i < tpinnum; ++i) {
|
||||
AstArg* argp = tconnects[i].second;
|
||||
AstArg* const argp = tconnects[i].second;
|
||||
UASSERT_OBJ(argp, nodep, "Lost argument in func conversion");
|
||||
nodep->addPinsp(argp);
|
||||
}
|
||||
|
|
@ -1721,7 +1725,8 @@ string V3Task::assignInternalToDpi(AstVar* portp, bool isPtr, const string& frSu
|
|||
const string toName = portp->name() + toSuffix;
|
||||
size_t unpackSize = 1; // non-unpacked array is treated as size 1
|
||||
int unpackDim = 0;
|
||||
if (AstUnpackArrayDType* unpackp = VN_CAST(portp->dtypep()->skipRefp(), UnpackArrayDType)) {
|
||||
if (AstUnpackArrayDType* const unpackp
|
||||
= VN_CAST(portp->dtypep()->skipRefp(), UnpackArrayDType)) {
|
||||
unpackSize = unpackp->arrayUnpackedElements();
|
||||
unpackDim = unpackp->dimensions(false).second;
|
||||
if (unpackDim > 0) UASSERT_OBJ(unpackSize > 0, portp, "size must be greater than 0");
|
||||
|
|
@ -1825,7 +1830,7 @@ void V3Task::taskAll(AstNetlist* nodep) {
|
|||
UINFO(2, __FUNCTION__ << ": " << endl);
|
||||
{
|
||||
TaskStateVisitor visitors{nodep};
|
||||
TaskVisitor visitor{nodep, &visitors};
|
||||
const TaskVisitor visitor{nodep, &visitors};
|
||||
} // Destruct before checking
|
||||
V3Global::dumpCheckGlobalTree("task", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ private:
|
|||
// Find if there are any duplicates
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
|
||||
if (TraceTraceVertex* const vvertexp = dynamic_cast<TraceTraceVertex*>(itp)) {
|
||||
AstTraceDecl* const nodep = vvertexp->nodep();
|
||||
const AstTraceDecl* const nodep = vvertexp->nodep();
|
||||
if (nodep->valuep() && !vvertexp->duplicatep()) {
|
||||
const auto dupit = dupFinder.findDuplicate(nodep->valuep());
|
||||
if (dupit != dupFinder.end()) {
|
||||
|
|
@ -387,7 +387,7 @@ private:
|
|||
for (; it != end && it->first == actSet; ++it) {
|
||||
if (!it->second->duplicatep()) {
|
||||
uint32_t cost = 0;
|
||||
AstTraceDecl* const declp = it->second->nodep();
|
||||
const AstTraceDecl* const declp = it->second->nodep();
|
||||
// The number of comparisons required by tracep->chg*
|
||||
cost += declp->isWide() ? declp->codeInc() : 1;
|
||||
// Arrays are traced by element
|
||||
|
|
@ -532,7 +532,7 @@ private:
|
|||
}
|
||||
}
|
||||
// Add call to top function
|
||||
AstCCall* callp = new AstCCall(funcp->fileline(), funcp);
|
||||
AstCCall* const callp = new AstCCall(funcp->fileline(), funcp);
|
||||
callp->argTypes("tracep");
|
||||
topFuncp->addStmtsp(callp);
|
||||
}
|
||||
|
|
@ -562,7 +562,7 @@ private:
|
|||
// This is a duplicate trace node. We will assign the signal
|
||||
// number to the canonical node, and emit this as an alias, so
|
||||
// no need to create a TraceInc node.
|
||||
AstTraceDecl* const canonDeclp = canonVtxp->nodep();
|
||||
const AstTraceDecl* const canonDeclp = canonVtxp->nodep();
|
||||
UASSERT_OBJ(!canonVtxp->duplicatep(), canonDeclp,
|
||||
"Canonical node is a duplicate");
|
||||
UASSERT_OBJ(canonDeclp->code() != 0, canonDeclp,
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue