Internals: Add VL_MT_SAFE attribute to functions that requires locking. (#3805)

This commit is contained in:
Kamil Rakoczy 2023-03-18 01:24:15 +01:00 committed by GitHub
parent d6c5d40f9b
commit 798d7346cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 185 additions and 143 deletions

View File

@ -68,7 +68,7 @@ public:
: V3GraphVertex{graphp} : V3GraphVertex{graphp}
, m_name{name} , m_name{name}
, m_type{type} {} , m_type{type} {}
string name() const override { return m_name + " " + typestr(); } string name() const override VL_MT_STABLE { return m_name + " " + typestr(); }
string dotColor() const override { return user() ? "green" : "black"; } string dotColor() const override { return user() ? "green" : "black"; }
virtual int type() const { return m_type; } virtual int type() const { return m_type; }
}; };

View File

@ -125,7 +125,9 @@ string AstNode::encodeNumber(int64_t num) {
} }
} }
string AstNode::nameProtect() const { return VIdProtect::protectIf(name(), protect()); } string AstNode::nameProtect() const VL_MT_STABLE {
return VIdProtect::protectIf(name(), protect());
}
string AstNode::origNameProtect() const { return VIdProtect::protectIf(origName(), protect()); } string AstNode::origNameProtect() const { return VIdProtect::protectIf(origName(), protect()); }
string AstNode::shortName() const { string AstNode::shortName() const {

View File

@ -1670,7 +1670,7 @@ public:
static constexpr int INSTR_COUNT_PLI = 20; // PLI routines static constexpr int INSTR_COUNT_PLI = 20; // PLI routines
// ACCESSORS // ACCESSORS
virtual string name() const VL_MT_SAFE { return ""; } virtual string name() const VL_MT_STABLE { return ""; }
virtual string origName() const { return ""; } virtual string origName() const { return ""; }
virtual void name(const string& name) { virtual void name(const string& name) {
this->v3fatalSrc("name() called on object without name() method"); this->v3fatalSrc("name() called on object without name() method");
@ -1678,7 +1678,7 @@ public:
virtual void tag(const string& text) {} virtual void tag(const string& text) {}
virtual string tag() const { return ""; } virtual string tag() const { return ""; }
virtual string verilogKwd() const { return ""; } virtual string verilogKwd() const { return ""; }
string nameProtect() const; // Name with --protect-id applied string nameProtect() const VL_MT_STABLE; // Name with --protect-id applied
string origNameProtect() const; // origName with --protect-id applied string origNameProtect() const; // origName with --protect-id applied
string shortName() const; // Name with __PVT__ removed for concatenating scopes string shortName() const; // Name with __PVT__ removed for concatenating scopes
static string dedotName(const string& namein); // Name with dots removed static string dedotName(const string& namein); // Name with dots removed
@ -1691,7 +1691,7 @@ public:
encodeName(const string& namein); // Encode user name into internal C representation encodeName(const string& namein); // Encode user name into internal C representation
static string encodeNumber(int64_t num); // Encode number into internal C representation static string encodeNumber(int64_t num); // Encode number into internal C representation
static string vcdName(const string& namein); // Name for printing out to vcd files static string vcdName(const string& namein); // Name for printing out to vcd files
string prettyName() const VL_MT_SAFE { return prettyName(name()); } string prettyName() const VL_MT_STABLE { return prettyName(name()); }
string prettyNameQ() const { return prettyNameQ(name()); } string prettyNameQ() const { return prettyNameQ(name()); }
string prettyTypeName() const; // "VARREF" for error messages (NOT dtype's pretty name) string prettyTypeName() const; // "VARREF" for error messages (NOT dtype's pretty name)
virtual string prettyOperatorName() const { return "operator " + prettyTypeName(); } virtual string prettyOperatorName() const { return "operator " + prettyTypeName(); }

View File

@ -242,7 +242,7 @@ public:
bool similarDType(const AstNodeDType* samep) const override { bool similarDType(const AstNodeDType* samep) const override {
return this == samep; // We don't compare members, require exact equivalence return this == samep; // We don't compare members, require exact equivalence
} }
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
void name(const string& flag) override { m_name = flag; } void name(const string& flag) override { m_name = flag; }
bool packed() const VL_MT_SAFE { return m_packed; } bool packed() const VL_MT_SAFE { return m_packed; }
void packed(bool flag) { m_packed = flag; } void packed(bool flag) { m_packed = flag; }
@ -281,7 +281,7 @@ public:
this->valuep(valuep); this->valuep(valuep);
} }
ASTGEN_MEMBERS_AstEnumItem; ASTGEN_MEMBERS_AstEnumItem;
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
bool maybePointedTo() const override { return true; } bool maybePointedTo() const override { return true; }
bool hasDType() const override { return true; } bool hasDType() const override { return true; }
void name(const string& flag) override { m_name = flag; } void name(const string& flag) override { m_name = flag; }
@ -409,7 +409,7 @@ public:
bool similarDType(const AstNodeDType* samep) const override { bool similarDType(const AstNodeDType* samep) const override {
return type() == samep->type() && same(samep); return type() == samep->type() && same(samep);
} }
string name() const override { return m.m_keyword.ascii(); } string name() const override VL_MT_STABLE { return m.m_keyword.ascii(); }
string prettyDTypeName() const override; string prettyDTypeName() const override;
const char* broken() const override { const char* broken() const override {
BROKEN_RTN(dtypep() != this); BROKEN_RTN(dtypep() != this);
@ -531,7 +531,7 @@ public:
} }
void dump(std::ostream& str = std::cout) const override; void dump(std::ostream& str = std::cout) const override;
void dumpSmall(std::ostream& str) const override; void dumpSmall(std::ostream& str) const override;
string name() const override; string name() const override VL_MT_STABLE;
AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; }
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
@ -543,7 +543,7 @@ public:
AstNodeDType* subDTypep() const override VL_MT_SAFE { return nullptr; } AstNodeDType* subDTypep() const override VL_MT_SAFE { return nullptr; }
AstNodeModule* classOrPackagep() const { return m_classOrPackagep; } AstNodeModule* classOrPackagep() const { return m_classOrPackagep; }
void classOrPackagep(AstNodeModule* nodep) { m_classOrPackagep = nodep; } void classOrPackagep(AstNodeModule* nodep) { m_classOrPackagep = nodep; }
AstClass* classp() const { return m_classp; } AstClass* classp() const VL_MT_STABLE { return m_classp; }
void classp(AstClass* nodep) { m_classp = nodep; } void classp(AstClass* nodep) { m_classp = nodep; }
bool isCompound() const override { return true; } bool isCompound() const override { return true; }
}; };
@ -641,7 +641,7 @@ public:
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
int widthAlignBytes() const override { return dtypep()->widthAlignBytes(); } int widthAlignBytes() const override { return dtypep()->widthAlignBytes(); }
int widthTotalBytes() const override { return dtypep()->widthTotalBytes(); } int widthTotalBytes() const override { return dtypep()->widthTotalBytes(); }
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
void name(const string& flag) override { m_name = flag; } void name(const string& flag) override { m_name = flag; }
bool isCompound() const override { return false; } bool isCompound() const override { return false; }
}; };
@ -767,7 +767,7 @@ public:
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; } AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); } void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
void name(const string& flag) override { m_name = flag; } void name(const string& flag) override { m_name = flag; }
void dump(std::ostream& str = std::cout) const override; void dump(std::ostream& str = std::cout) const override;
void dumpSmall(std::ostream& str) const override; void dumpSmall(std::ostream& str) const override;
@ -879,7 +879,7 @@ public:
} }
ASTGEN_MEMBERS_AstMemberDType; ASTGEN_MEMBERS_AstMemberDType;
void dumpSmall(std::ostream& str) const override; void dumpSmall(std::ostream& str) const override;
string name() const override { return m_name; } // * = Var name string name() const override VL_MT_STABLE { return m_name; } // * = Var name
bool hasDType() const override { return true; } bool hasDType() const override { return true; }
bool maybePointedTo() const override { return true; } bool maybePointedTo() const override { return true; }
const char* broken() const override { const char* broken() const override {
@ -955,7 +955,7 @@ public:
int widthAlignBytes() const override { return dtypep()->widthAlignBytes(); } int widthAlignBytes() const override { return dtypep()->widthAlignBytes(); }
int widthTotalBytes() const override { return dtypep()->widthTotalBytes(); } int widthTotalBytes() const override { return dtypep()->widthTotalBytes(); }
// METHODS // METHODS
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
bool maybePointedTo() const override { return true; } bool maybePointedTo() const override { return true; }
bool hasDType() const override { return true; } bool hasDType() const override { return true; }
void name(const string& flag) override { m_name = flag; } void name(const string& flag) override { m_name = flag; }
@ -1093,7 +1093,7 @@ public:
} }
void dump(std::ostream& str = std::cout) const override; void dump(std::ostream& str = std::cout) const override;
void dumpSmall(std::ostream& str) const override; void dumpSmall(std::ostream& str) const override;
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
string prettyDTypeName() const override { string prettyDTypeName() const override {
return subDTypep() ? prettyName(subDTypep()->name()) : prettyName(); return subDTypep() ? prettyName(subDTypep()->name()) : prettyName();
} }

View File

@ -236,7 +236,7 @@ public:
const char* broken() const override; const char* broken() const override;
void cloneRelink() override; void cloneRelink() override;
void dump(std::ostream& str = std::cout) const override; void dump(std::ostream& str = std::cout) const override;
string name() const override { return m_name; } // * = Var name string name() const override VL_MT_STABLE { return m_name; } // * = Var name
bool isGateOptimizable() const override; bool isGateOptimizable() const override;
string dotted() const { return m_dotted; } // * = Scope name or "" string dotted() const { return m_dotted; } // * = Scope name or ""
string inlinedDots() const { return m_inlinedDots; } string inlinedDots() const { return m_inlinedDots; }
@ -474,7 +474,7 @@ public:
const char* broken() const override; const char* broken() const override;
int instrCount() const override { return widthInstrs(); } int instrCount() const override { return widthInstrs(); }
void cloneRelink() override; void cloneRelink() override;
string name() const override { return m_name; } // * = Var name string name() const override VL_MT_STABLE { return m_name; } // * = Var name
void name(const string& name) override { m_name = name; } void name(const string& name) override { m_name = name; }
VAccess access() const { return m_access; } VAccess access() const { return m_access; }
void access(const VAccess& flag) { m_access = flag; } // Avoid using this; Set in constructor void access(const VAccess& flag) { m_access = flag; } // Avoid using this; Set in constructor
@ -532,7 +532,7 @@ public:
} }
ASTGEN_MEMBERS_AstArg; ASTGEN_MEMBERS_AstArg;
bool hasDType() const override { return false; } bool hasDType() const override { return false; }
string name() const override { return m_name; } // * = Pin name, ""=go by number string name() const override VL_MT_STABLE { return m_name; } // * = Pin name, ""=go by number
void name(const string& name) override { m_name = name; } void name(const string& name) override { m_name = name; }
bool emptyConnectNoNext() const { return !exprp() && name() == "" && !nextp(); } bool emptyConnectNoNext() const { return !exprp() && name() == "" && !nextp(); }
@ -610,7 +610,7 @@ public:
this->addPinsp(pinsp); this->addPinsp(pinsp);
} }
ASTGEN_MEMBERS_AstCMethodHard; ASTGEN_MEMBERS_AstCMethodHard;
string name() const override { return m_name; } // * = Var name string name() const override VL_MT_STABLE { return m_name; } // * = Var name
void name(const string& name) override { m_name = name; } void name(const string& name) override { m_name = name; }
bool same(const AstNode* samep) const override { bool same(const AstNode* samep) const override {
const AstCMethodHard* asamep = static_cast<const AstCMethodHard*>(samep); const AstCMethodHard* asamep = static_cast<const AstCMethodHard*>(samep);
@ -689,7 +689,7 @@ public:
} }
ASTGEN_MEMBERS_AstCellArrayRef; ASTGEN_MEMBERS_AstCellArrayRef;
// ACCESSORS // ACCESSORS
string name() const override { return m_name; } // * = Array name string name() const override VL_MT_STABLE { return m_name; } // * = Array name
string emitVerilog() override { V3ERROR_NA_RETURN(""); } string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); } string emitC() override { V3ERROR_NA_RETURN(""); }
@ -710,7 +710,7 @@ public:
} }
ASTGEN_MEMBERS_AstCellRef; ASTGEN_MEMBERS_AstCellRef;
// ACCESSORS // ACCESSORS
string name() const override { return m_name; } // * = Array name string name() const override VL_MT_STABLE { return m_name; } // * = Array name
string emitVerilog() override { V3ERROR_NA_RETURN(""); } string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); } string emitC() override { V3ERROR_NA_RETURN(""); }
@ -746,7 +746,7 @@ public:
== static_cast<const AstClassOrPackageRef*>(samep)->m_classOrPackageNodep); == static_cast<const AstClassOrPackageRef*>(samep)->m_classOrPackageNodep);
} }
void dump(std::ostream& str = std::cout) const override; void dump(std::ostream& str = std::cout) const override;
string name() const override { return m_name; } // * = Var name string name() const override VL_MT_STABLE { return m_name; } // * = Var name
AstNode* classOrPackageNodep() const { return m_classOrPackageNodep; } AstNode* classOrPackageNodep() const { return m_classOrPackageNodep; }
void classOrPackageNodep(AstNode* nodep) { m_classOrPackageNodep = nodep; } void classOrPackageNodep(AstNode* nodep) { m_classOrPackageNodep = nodep; }
AstNodeModule* classOrPackagep() const; AstNodeModule* classOrPackagep() const;
@ -990,7 +990,7 @@ public:
initWithNumber(); initWithNumber();
} }
ASTGEN_MEMBERS_AstConst; ASTGEN_MEMBERS_AstConst;
string name() const override { return num().ascii(); } // * = Value string name() const override VL_MT_STABLE { return num().ascii(); } // * = Value
const V3Number& num() const VL_MT_SAFE { return m_num; } // * = Value const V3Number& num() const VL_MT_SAFE { return m_num; } // * = Value
V3Number& num() { return m_num; } // * = Value V3Number& num() { return m_num; } // * = Value
uint32_t toUInt() const { return num().toUInt(); } uint32_t toUInt() const { return num().toUInt(); }
@ -1058,7 +1058,7 @@ public:
} }
ASTGEN_MEMBERS_AstEnumItemRef; ASTGEN_MEMBERS_AstEnumItemRef;
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;
string name() const override { return itemp()->name(); } string name() const override VL_MT_STABLE { return itemp()->name(); }
int instrCount() const override { return 0; } int instrCount() const override { return 0; }
const char* broken() const override; const char* broken() const override;
void cloneRelink() override { void cloneRelink() override {
@ -1068,7 +1068,7 @@ public:
const AstEnumItemRef* const sp = static_cast<const AstEnumItemRef*>(samep); const AstEnumItemRef* const sp = static_cast<const AstEnumItemRef*>(samep);
return itemp() == sp->itemp(); return itemp() == sp->itemp();
} }
AstEnumItem* itemp() const { return m_itemp; } AstEnumItem* itemp() const VL_MT_STABLE { return m_itemp; }
string emitVerilog() override { V3ERROR_NA_RETURN(""); } string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); } string emitC() override { V3ERROR_NA_RETURN(""); }
bool cleanOut() const override { return true; } bool cleanOut() const override { return true; }
@ -1209,7 +1209,7 @@ public:
this->filep(filep); this->filep(filep);
} }
ASTGEN_MEMBERS_AstFScanF; ASTGEN_MEMBERS_AstFScanF;
string name() const override { return m_text; } string name() const override VL_MT_STABLE { return m_text; }
string verilogKwd() const override { return "$fscanf"; } string verilogKwd() const override { return "$fscanf"; }
string emitVerilog() override { V3ERROR_NA_RETURN(""); } string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); } string emitC() override { V3ERROR_NA_RETURN(""); }
@ -1406,7 +1406,7 @@ public:
string emitC() override { V3ERROR_NA_RETURN(""); } string emitC() override { V3ERROR_NA_RETURN(""); }
bool cleanOut() const override { return true; } bool cleanOut() const override { return true; }
int instrCount() const override { return widthInstrs(); } int instrCount() const override { return widthInstrs(); }
string name() const override { return m_name; } // * = Var name string name() const override VL_MT_STABLE { return m_name; } // * = Var name
void name(const string& name) override { m_name = name; } void name(const string& name) override { m_name = name; }
bool index() const { return m_index; } bool index() const { return m_index; }
}; };
@ -1432,7 +1432,7 @@ public:
void cloneRelink() override; void cloneRelink() override;
const char* broken() const override; const char* broken() const override;
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
void name(const string& name) override { m_name = name; } void name(const string& name) override { m_name = name; }
string emitVerilog() override { V3ERROR_NA_RETURN(""); } string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); } string emitC() override { V3ERROR_NA_RETURN(""); }
@ -1497,7 +1497,7 @@ public:
} }
ASTGEN_MEMBERS_AstParseRef; ASTGEN_MEMBERS_AstParseRef;
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;
string name() const override { return m_name; } // * = Var name string name() const override VL_MT_STABLE { return m_name; } // * = Var name
bool same(const AstNode* samep) const override { bool same(const AstNode* samep) const override {
const AstParseRef* const asamep = static_cast<const AstParseRef*>(samep); const AstParseRef* const asamep = static_cast<const AstParseRef*>(samep);
return (expect() == asamep->expect() && m_name == asamep->m_name); return (expect() == asamep->expect() && m_name == asamep->m_name);
@ -1671,7 +1671,7 @@ public:
addExprsp(exprsp); addExprsp(exprsp);
} }
ASTGEN_MEMBERS_AstSFormatF; ASTGEN_MEMBERS_AstSFormatF;
string name() const override { return m_text; } string name() const override VL_MT_STABLE { return m_text; }
int instrCount() const override { return INSTR_COUNT_PLI; } int instrCount() const override { return INSTR_COUNT_PLI; }
bool same(const AstNode* samep) const override { bool same(const AstNode* samep) const override {
return text() == static_cast<const AstSFormatF*>(samep)->text(); return text() == static_cast<const AstSFormatF*>(samep)->text();
@ -1706,7 +1706,7 @@ public:
this->fromp(fromp); this->fromp(fromp);
} }
ASTGEN_MEMBERS_AstSScanF; ASTGEN_MEMBERS_AstSScanF;
string name() const override { return m_text; } string name() const override VL_MT_STABLE { return m_text; }
string verilogKwd() const override { return "$sscanf"; } string verilogKwd() const override { return "$sscanf"; }
string emitVerilog() override { V3ERROR_NA_RETURN(""); } string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); } string emitC() override { V3ERROR_NA_RETURN(""); }
@ -1891,7 +1891,7 @@ public:
dtypep(nullptr); // V3Width will resolve dtypep(nullptr); // V3Width will resolve
} }
ASTGEN_MEMBERS_AstStructSel; ASTGEN_MEMBERS_AstStructSel;
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
void name(const string& name) override { m_name = name; } void name(const string& name) override { m_name = name; }
string emitVerilog() override { V3ERROR_NA_RETURN(""); } string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); } string emitC() override { V3ERROR_NA_RETURN(""); }
@ -2200,7 +2200,7 @@ public:
void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
out.opCompareNN(lhs, rhs, m_ignoreCase); out.opCompareNN(lhs, rhs, m_ignoreCase);
} }
string name() const override { return m_ignoreCase ? "icompare" : "compare"; } string name() const override VL_MT_STABLE { return m_ignoreCase ? "icompare" : "compare"; }
string emitVerilog() override { string emitVerilog() override {
return m_ignoreCase ? "%k(%l.icompare(%r))" : "%k(%l.compare(%r))"; return m_ignoreCase ? "%k(%l.icompare(%r))" : "%k(%l.compare(%r))";
} }
@ -2424,7 +2424,7 @@ public:
void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override { void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
out.opGetcN(lhs, rhs); out.opGetcN(lhs, rhs);
} }
string name() const override { return "getc"; } string name() const override VL_MT_STABLE { return "getc"; }
string emitVerilog() override { return "%k(%l.getc(%r))"; } string emitVerilog() override { return "%k(%l.getc(%r))"; }
string emitC() override { return "VL_GETC_N(%li,%ri)"; } string emitC() override { return "VL_GETC_N(%li,%ri)"; }
string emitSimpleOperator() override { return ""; } string emitSimpleOperator() override { return ""; }
@ -4304,7 +4304,7 @@ public:
const V3Number& ths) override { const V3Number& ths) override {
out.opPutcN(lhs, rhs, ths); out.opPutcN(lhs, rhs, ths);
} }
string name() const override { return "putc"; } string name() const override VL_MT_STABLE { return "putc"; }
string emitVerilog() override { return "%k(%l.putc(%r,%t))"; } string emitVerilog() override { return "%k(%l.putc(%r,%t))"; }
string emitC() override { return "VL_PUTC_N(%li,%ri,%ti)"; } string emitC() override { return "VL_PUTC_N(%li,%ri,%ti)"; }
string emitSimpleOperator() override { return ""; } string emitSimpleOperator() override { return ""; }
@ -4411,7 +4411,7 @@ public:
const V3Number& ths) override { const V3Number& ths) override {
out.opSubstrN(lhs, rhs, ths); out.opSubstrN(lhs, rhs, ths);
} }
string name() const override { return "substr"; } string name() const override VL_MT_STABLE { return "substr"; }
string emitVerilog() override { return "%k(%l.substr(%r,%t))"; } string emitVerilog() override { return "%k(%l.substr(%r,%t))"; }
string emitC() override { return "VL_SUBSTR_N(%li,%ri,%ti)"; } string emitC() override { return "VL_SUBSTR_N(%li,%ri,%ti)"; }
string emitSimpleOperator() override { return ""; } string emitSimpleOperator() override { return ""; }
@ -4488,7 +4488,7 @@ public:
} }
ASTGEN_MEMBERS_AstAtoN; ASTGEN_MEMBERS_AstAtoN;
void numberOperate(V3Number& out, const V3Number& lhs) override { out.opAtoN(lhs, m_fmt); } void numberOperate(V3Number& out, const V3Number& lhs) override { out.opAtoN(lhs, m_fmt); }
string name() const override { string name() const override VL_MT_STABLE {
switch (m_fmt) { switch (m_fmt) {
case ATOI: return "atoi"; case ATOI: return "atoi";
case ATOHEX: return "atohex"; case ATOHEX: return "atohex";

View File

@ -48,7 +48,7 @@ protected:
public: public:
ASTGEN_MEMBERS_AstNodeBlock; ASTGEN_MEMBERS_AstNodeBlock;
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;
string name() const override { return m_name; } // * = Block name string name() const override VL_MT_STABLE { return m_name; } // * = Block name
void name(const string& name) override { m_name = name; } void name(const string& name) override { m_name = name; }
bool unnamed() const { return m_unnamed; } bool unnamed() const { return m_unnamed; }
bool isFirstInMyListOfStatements(AstNode* nodep) const override { return nodep == stmtsp(); } bool isFirstInMyListOfStatements(AstNode* nodep) const override { return nodep == stmtsp(); }
@ -118,7 +118,7 @@ protected:
public: public:
ASTGEN_MEMBERS_AstNodeFTask; ASTGEN_MEMBERS_AstNodeFTask;
void dump(std::ostream& str = std::cout) const override; void dump(std::ostream& str = std::cout) const override;
string name() const override { return m_name; } // * = Var name string name() const override VL_MT_STABLE { return m_name; } // * = Var name
bool maybePointedTo() const override { return true; } bool maybePointedTo() const override { return true; }
bool isGateOptimizable() const override { return !((m_dpiExport || m_dpiImport) && !m_pure); } bool isGateOptimizable() const override { return !((m_dpiExport || m_dpiImport) && !m_pure); }
// {AstFunc only} op1 = Range output variable // {AstFunc only} op1 = Range output variable
@ -186,7 +186,7 @@ public:
, m_name{name} {} , m_name{name} {}
ASTGEN_MEMBERS_AstNodeFile; ASTGEN_MEMBERS_AstNodeFile;
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
bool same(const AstNode* /*samep*/) const override { return true; } bool same(const AstNode* /*samep*/) const override { return true; }
}; };
class AstNodeModule VL_NOT_FINAL : public AstNode { class AstNodeModule VL_NOT_FINAL : public AstNode {
@ -234,7 +234,7 @@ public:
ASTGEN_MEMBERS_AstNodeModule; ASTGEN_MEMBERS_AstNodeModule;
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;
bool maybePointedTo() const override { return true; } bool maybePointedTo() const override { return true; }
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
virtual bool timescaleMatters() const = 0; virtual bool timescaleMatters() const = 0;
// ACCESSORS // ACCESSORS
void name(const string& name) override { m_name = name; } void name(const string& name) override { m_name = name; }
@ -373,7 +373,7 @@ public:
this->addPasssp(passsp); this->addPasssp(passsp);
} }
ASTGEN_MEMBERS_AstNodeCoverOrAssert; ASTGEN_MEMBERS_AstNodeCoverOrAssert;
string name() const override { return m_name; } // * = Var name string name() const override VL_MT_STABLE { return m_name; } // * = Var name
bool same(const AstNode* samep) const override { return samep->name() == name(); } bool same(const AstNode* samep) const override { return samep->name() == name(); }
void name(const string& name) override { m_name = name; } void name(const string& name) override { m_name = name; }
void dump(std::ostream& str = std::cout) const override; void dump(std::ostream& str = std::cout) const override;
@ -512,7 +512,7 @@ public:
} }
ASTGEN_MEMBERS_AstActive; ASTGEN_MEMBERS_AstActive;
void dump(std::ostream& str = std::cout) const override; void dump(std::ostream& str = std::cout) const override;
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
const char* broken() const override; const char* broken() const override;
void cloneRelink() override; void cloneRelink() override;
// Statements are broken into pieces, as some must come before others. // Statements are broken into pieces, as some must come before others.
@ -537,7 +537,7 @@ public:
} }
ASTGEN_MEMBERS_AstBind; ASTGEN_MEMBERS_AstBind;
// ACCESSORS // ACCESSORS
string name() const override { return m_name; } // * = Bind Target name string name() const override VL_MT_STABLE { return m_name; } // * = Bind Target name
void name(const string& name) override { m_name = name; } void name(const string& name) override { m_name = name; }
}; };
class AstCFunc final : public AstNode { class AstCFunc final : public AstNode {
@ -607,7 +607,7 @@ public:
m_dpiTraceInit = false; m_dpiTraceInit = false;
} }
ASTGEN_MEMBERS_AstCFunc; ASTGEN_MEMBERS_AstCFunc;
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
const char* broken() const override; const char* broken() const override;
void cloneRelink() override; void cloneRelink() override;
bool maybePointedTo() const override { return true; } bool maybePointedTo() const override { return true; }
@ -702,7 +702,7 @@ public:
, m_useType{useType} {} , m_useType{useType} {}
ASTGEN_MEMBERS_AstCUse; ASTGEN_MEMBERS_AstCUse;
void dump(std::ostream& str = std::cout) const override; void dump(std::ostream& str = std::cout) const override;
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
VUseType useType() const { return m_useType; } VUseType useType() const { return m_useType; }
}; };
class AstCaseItem final : public AstNode { class AstCaseItem final : public AstNode {
@ -755,7 +755,7 @@ public:
const char* broken() const override; const char* broken() const override;
bool maybePointedTo() const override { return true; } bool maybePointedTo() const override { return true; }
// ACCESSORS // ACCESSORS
string name() const override { return m_name; } // * = Cell name string name() const override VL_MT_STABLE { return m_name; } // * = Cell name
void name(const string& name) override { m_name = name; } void name(const string& name) override { m_name = name; }
string origName() const override { return m_origName; } // * = Original name string origName() const override { return m_origName; } // * = Original name
void origName(const string& name) { m_origName = name; } void origName(const string& name) { m_origName = name; }
@ -794,7 +794,7 @@ public:
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;
const char* broken() const override; const char* broken() const override;
// ACCESSORS // ACCESSORS
string name() const override { return m_name; } // * = Cell name string name() const override VL_MT_STABLE { return m_name; } // * = Cell name
string origModName() const { return m_origModName; } // * = modp()->origName() before inlining string origModName() const { return m_origModName; } // * = modp()->origName() before inlining
void name(const string& name) override { m_name = name; } void name(const string& name) override { m_name = name; }
void scopep(AstScope* scp) { m_scopep = scp; } void scopep(AstScope* scp) { m_scopep = scp; }
@ -845,7 +845,7 @@ public:
} }
ASTGEN_MEMBERS_AstClocking; ASTGEN_MEMBERS_AstClocking;
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;
std::string name() const override { return m_name; } std::string name() const override VL_MT_STABLE { return m_name; }
bool isDefault() const { return m_isDefault; } bool isDefault() const { return m_isDefault; }
bool isGlobal() const { return m_isGlobal; } bool isGlobal() const { return m_isGlobal; }
}; };
@ -916,7 +916,7 @@ public:
, m_path{path} { , m_path{path} {
this->rhsp(rhsp); this->rhsp(rhsp);
} }
string name() const override { return m_name; } // * = Scope name string name() const override VL_MT_STABLE { return m_name; } // * = Scope name
ASTGEN_MEMBERS_AstDefParam; ASTGEN_MEMBERS_AstDefParam;
bool same(const AstNode*) const override { return true; } bool same(const AstNode*) const override { return true; }
string path() const { return m_path; } string path() const { return m_path; }
@ -934,7 +934,7 @@ public:
, m_name{vname} , m_name{vname}
, m_cname{cname} {} , m_cname{cname} {}
ASTGEN_MEMBERS_AstDpiExport; ASTGEN_MEMBERS_AstDpiExport;
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
void name(const string& name) override { m_name = name; } void name(const string& name) override { m_name = name; }
string cname() const { return m_cname; } string cname() const { return m_cname; }
void cname(const string& cname) { m_cname = cname; } void cname(const string& cname) { m_cname = cname; }
@ -995,7 +995,7 @@ public:
BROKEN_RTN(!m_depGraphp); BROKEN_RTN(!m_depGraphp);
return nullptr; return nullptr;
} }
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
V3Graph* depGraphp() { return m_depGraphp; } V3Graph* depGraphp() { return m_depGraphp; }
const V3Graph* depGraphp() const { return m_depGraphp; } const V3Graph* depGraphp() const { return m_depGraphp; }
}; };
@ -1033,7 +1033,7 @@ public:
AstIntfRef(FileLine* fl, const string& name) AstIntfRef(FileLine* fl, const string& name)
: ASTGEN_SUPER_IntfRef(fl) : ASTGEN_SUPER_IntfRef(fl)
, m_name{name} {} , m_name{name} {}
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
ASTGEN_MEMBERS_AstIntfRef; ASTGEN_MEMBERS_AstIntfRef;
}; };
class AstMTaskBody final : public AstNode { class AstMTaskBody final : public AstNode {
@ -1070,7 +1070,7 @@ public:
, m_name{name} { , m_name{name} {
this->addVarsp(varsp); this->addVarsp(varsp);
} }
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
bool maybePointedTo() const override { return true; } bool maybePointedTo() const override { return true; }
ASTGEN_MEMBERS_AstModport; ASTGEN_MEMBERS_AstModport;
}; };
@ -1092,7 +1092,7 @@ public:
const char* broken() const override; const char* broken() const override;
void cloneRelink() override; void cloneRelink() override;
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
bool isImport() const { return !m_export; } bool isImport() const { return !m_export; }
bool isExport() const { return m_export; } bool isExport() const { return m_export; }
AstNodeFTask* ftaskp() const { return m_ftaskp; } // [After Link] Pointer to variable AstNodeFTask* ftaskp() const { return m_ftaskp; } // [After Link] Pointer to variable
@ -1115,7 +1115,7 @@ public:
const char* broken() const override; const char* broken() const override;
void cloneRelink() override; void cloneRelink() override;
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
void direction(const VDirection& flag) { m_direction = flag; } void direction(const VDirection& flag) { m_direction = flag; }
VDirection direction() const { return m_direction; } VDirection direction() const { return m_direction; }
AstVar* varp() const { return m_varp; } // [After Link] Pointer to variable AstVar* varp() const { return m_varp; } // [After Link] Pointer to variable
@ -1149,7 +1149,7 @@ public:
ASTGEN_MEMBERS_AstNetlist; ASTGEN_MEMBERS_AstNetlist;
const char* broken() const override; const char* broken() const override;
void cloneRelink() override { V3ERROR_NA; } void cloneRelink() override { V3ERROR_NA; }
string name() const override { return "$root"; } string name() const override VL_MT_STABLE { return "$root"; }
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;
AstNodeModule* topModulep() const { // Top module in hierarchy AstNodeModule* topModulep() const { // Top module in hierarchy
return modulesp(); // First one in the list, for now return modulesp(); // First one in the list, for now
@ -1198,7 +1198,7 @@ public:
const char* broken() const override; const char* broken() const override;
void cloneRelink() override; void cloneRelink() override;
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
AstPackage* packagep() const { return m_packagep; } AstPackage* packagep() const { return m_packagep; }
void packagep(AstPackage* nodep) { m_packagep = nodep; } void packagep(AstPackage* nodep) { m_packagep = nodep; }
}; };
@ -1224,7 +1224,7 @@ public:
const char* broken() const override; const char* broken() const override;
void cloneRelink() override; void cloneRelink() override;
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
AstPackage* packagep() const { return m_packagep; } AstPackage* packagep() const { return m_packagep; }
void packagep(AstPackage* nodep) { m_packagep = nodep; } void packagep(AstPackage* nodep) { m_packagep = nodep; }
}; };
@ -1250,7 +1250,7 @@ public:
ASTGEN_MEMBERS_AstPin; ASTGEN_MEMBERS_AstPin;
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;
const char* broken() const override; const char* broken() const override;
string name() const override { return m_name; } // * = Pin name, ""=go by number string name() const override VL_MT_STABLE { return m_name; } // * = Pin name, ""=go by number
void name(const string& name) override { m_name = name; } void name(const string& name) override { m_name = name; }
string prettyOperatorName() const override; string prettyOperatorName() const override;
bool dotStar() const { return name() == ".*"; } // Fake name for .* connections until linked bool dotStar() const { return name() == ".*"; } // Fake name for .* connections until linked
@ -1278,7 +1278,7 @@ public:
, m_pinNum{pinnum} , m_pinNum{pinnum}
, m_name{name} {} , m_name{name} {}
ASTGEN_MEMBERS_AstPort; ASTGEN_MEMBERS_AstPort;
string name() const override { return m_name; } // * = Port name string name() const override VL_MT_STABLE { return m_name; } // * = Port name
int pinNum() const { return m_pinNum; } // * = Pin number, for order based instantiation int pinNum() const { return m_pinNum; } // * = Pin number, for order based instantiation
}; };
class AstPragma final : public AstNode { class AstPragma final : public AstNode {
@ -1356,7 +1356,7 @@ public:
void cloneRelink() override; void cloneRelink() override;
const char* broken() const override; const char* broken() const override;
bool maybePointedTo() const override { return true; } bool maybePointedTo() const override { return true; }
string name() const override { return m_name; } // * = Scope name string name() const override VL_MT_STABLE { return m_name; } // * = Scope name
void name(const string& name) override { m_name = name; } void name(const string& name) override { m_name = name; }
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;
string nameDotless() const; string nameDotless() const;
@ -1548,7 +1548,7 @@ public:
return dtypep() ? dtypep() : childDTypep(); return dtypep() ? dtypep() : childDTypep();
} }
// METHODS // METHODS
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
bool maybePointedTo() const override { return true; } bool maybePointedTo() const override { return true; }
bool hasDType() const override { return true; } bool hasDType() const override { return true; }
void name(const string& flag) override { m_name = flag; } void name(const string& flag) override { m_name = flag; }
@ -1568,7 +1568,7 @@ public:
, m_name{name} {} , m_name{name} {}
ASTGEN_MEMBERS_AstTypedefFwd; ASTGEN_MEMBERS_AstTypedefFwd;
// METHODS // METHODS
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
bool maybePointedTo() const override { return true; } bool maybePointedTo() const override { return true; }
}; };
class AstUdpTable final : public AstNode { class AstUdpTable final : public AstNode {
@ -1588,7 +1588,7 @@ public:
: ASTGEN_SUPER_UdpTableLine(fl) : ASTGEN_SUPER_UdpTableLine(fl)
, m_text{text} {} , m_text{text} {}
ASTGEN_MEMBERS_AstUdpTableLine; ASTGEN_MEMBERS_AstUdpTableLine;
string name() const override { return m_text; } string name() const override VL_MT_STABLE { return m_text; }
string text() const { return m_text; } string text() const { return m_text; }
}; };
class AstVar final : public AstNode { class AstVar final : public AstNode {
@ -1758,7 +1758,7 @@ public:
} }
ASTGEN_MEMBERS_AstVar; ASTGEN_MEMBERS_AstVar;
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;
string name() const override VL_MT_SAFE { return m_name; } // * = Var name string name() const override VL_MT_STABLE VL_MT_SAFE { return m_name; } // * = Var name
bool hasDType() const override { return true; } bool hasDType() const override { return true; }
bool maybePointedTo() const override { return true; } bool maybePointedTo() const override { return true; }
string origName() const override { return m_origName; } // * = Original name string origName() const override { return m_origName; } // * = Original name
@ -1998,7 +1998,7 @@ public:
return nullptr; return nullptr;
} }
bool maybePointedTo() const override { return true; } bool maybePointedTo() const override { return true; }
string name() const override { return scopep()->name() + "->" + varp()->name(); } string name() const override VL_MT_STABLE { return scopep()->name() + "->" + varp()->name(); }
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;
bool hasDType() const override { return true; } bool hasDType() const override { return true; }
AstVar* varp() const { return m_varp; } // [After Link] Pointer to variable AstVar* varp() const { return m_varp; } // [After Link] Pointer to variable
@ -2452,7 +2452,7 @@ public:
, m_name{name} , m_name{name}
, m_showAt{showAt} {} , m_showAt{showAt} {}
ASTGEN_MEMBERS_AstComment; ASTGEN_MEMBERS_AstComment;
string name() const override { return m_name; } // * = Text string name() const override VL_MT_STABLE { return m_name; } // * = Text
bool same(const AstNode* samep) const override { return true; } // Ignore name in comments bool same(const AstNode* samep) const override { return true; } // Ignore name in comments
virtual bool showAt() const { return m_showAt; } virtual bool showAt() const { return m_showAt; }
}; };
@ -2593,7 +2593,7 @@ public:
: ASTGEN_SUPER_Disable(fl) : ASTGEN_SUPER_Disable(fl)
, m_name{name} {} , m_name{name} {}
ASTGEN_MEMBERS_AstDisable; ASTGEN_MEMBERS_AstDisable;
string name() const override { return m_name; } // * = Block name string name() const override VL_MT_STABLE { return m_name; } // * = Block name
void name(const string& flag) override { m_name = flag; } void name(const string& flag) override { m_name = flag; }
bool isBrancher() const override { bool isBrancher() const override {
return true; // SPECIAL: We don't process code after breaks return true; // SPECIAL: We don't process code after breaks
@ -2884,7 +2884,7 @@ public:
: ASTGEN_SUPER_PrintTimeScale(fl) {} : ASTGEN_SUPER_PrintTimeScale(fl) {}
ASTGEN_MEMBERS_AstPrintTimeScale; ASTGEN_MEMBERS_AstPrintTimeScale;
void name(const string& name) override { m_name = name; } void name(const string& name) override { m_name = name; }
string name() const override { return m_name; } // * = Var name string name() const override VL_MT_STABLE { return m_name; } // * = Var name
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;
string verilogKwd() const override { return "$printtimescale"; } string verilogKwd() const override { return "$printtimescale"; }
bool isGateOptimizable() const override { return false; } bool isGateOptimizable() const override { return false; }
@ -3103,7 +3103,7 @@ public:
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;
int instrCount() const override { return 100; } // Large... int instrCount() const override { return 100; } // Large...
ASTGEN_MEMBERS_AstTraceDecl; ASTGEN_MEMBERS_AstTraceDecl;
string name() const override { return m_showname; } string name() const override VL_MT_STABLE { return m_showname; }
bool maybePointedTo() const override { return true; } bool maybePointedTo() const override { return true; }
bool hasDType() const override { return true; } bool hasDType() const override { return true; }
bool same(const AstNode* samep) const override { return false; } bool same(const AstNode* samep) const override { return false; }

View File

@ -40,25 +40,31 @@ template <typename T>
class V3ConfigWildcardResolver final { class V3ConfigWildcardResolver final {
using Map = std::map<const std::string, T>; using Map = std::map<const std::string, T>;
Map m_mapWildcard; // Wildcard strings to entities mutable VerilatedMutex m_mutex; // protects members
Map m_mapResolved; // Resolved strings to converged entities Map m_mapWildcard VL_GUARDED_BY(m_mutex); // Wildcard strings to entities
Map m_mapResolved VL_GUARDED_BY(m_mutex); // Resolved strings to converged entities
public: public:
V3ConfigWildcardResolver() = default; V3ConfigWildcardResolver() = default;
~V3ConfigWildcardResolver() = default; ~V3ConfigWildcardResolver() = default;
/// Update into maps from other /// Update into maps from other
void update(const V3ConfigWildcardResolver& other) { void update(const V3ConfigWildcardResolver& other) VL_MT_SAFE_EXCLUDES(m_mutex)
VL_EXCLUDES(other.m_mutex) {
VerilatedLockGuard lock{m_mutex};
VerilatedLockGuard otherLock{other.m_mutex};
for (const auto& itr : other.m_mapResolved) m_mapResolved[itr.first].update(itr.second); for (const auto& itr : other.m_mapResolved) m_mapResolved[itr.first].update(itr.second);
for (const auto& itr : other.m_mapWildcard) m_mapWildcard[itr.first].update(itr.second); for (const auto& itr : other.m_mapWildcard) m_mapWildcard[itr.first].update(itr.second);
} }
// Access and create a (wildcard) entity // Access and create a (wildcard) entity
T& at(const string& name) { T& at(const string& name) VL_MT_SAFE_EXCLUDES(m_mutex) {
VerilatedLockGuard lock{m_mutex};
// Don't store into wildcards if the name is not a wildcard string // Don't store into wildcards if the name is not a wildcard string
return m_mapWildcard[name]; return m_mapWildcard[name];
} }
// Access an entity and resolve wildcards that match it // Access an entity and resolve wildcards that match it
T* resolve(const string& name) { T* resolve(const string& name) VL_MT_SAFE_EXCLUDES(m_mutex) {
VerilatedLockGuard lock{m_mutex};
// Lookup if it was resolved before, typically not // Lookup if it was resolved before, typically not
auto it = m_mapResolved.find(name); auto it = m_mapResolved.find(name);
if (VL_UNLIKELY(it != m_mapResolved.end())) return &it->second; if (VL_UNLIKELY(it != m_mapResolved.end())) return &it->second;
@ -78,7 +84,10 @@ public:
return newp; return newp;
} }
// Flush on update // Flush on update
void flush() { m_mapResolved.clear(); } void flush() VL_MT_SAFE_EXCLUDES(m_mutex) {
VerilatedLockGuard lock{m_mutex};
m_mapResolved.clear();
}
}; };
// Only public_flat_rw has the sensitity tree // Only public_flat_rw has the sensitity tree

View File

@ -63,7 +63,9 @@ public:
void putsQuoted(const string& str) { ofp()->putsQuoted(str); } void putsQuoted(const string& str) { ofp()->putsQuoted(str); }
void ensureNewLine() { ofp()->ensureNewLine(); } void ensureNewLine() { ofp()->ensureNewLine(); }
bool optSystemC() { return v3Global.opt.systemC(); } bool optSystemC() { return v3Global.opt.systemC(); }
static string protect(const string& name) { return VIdProtect::protectIf(name, true); } static string protect(const string& name) VL_MT_SAFE {
return VIdProtect::protectIf(name, true);
}
static string protectIf(const string& name, bool doIt) { static string protectIf(const string& name, bool doIt) {
return VIdProtect::protectIf(name, doIt); return VIdProtect::protectIf(name, doIt);
} }
@ -84,7 +86,7 @@ public:
return symClassName() + "* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;\n"; return symClassName() + "* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;\n";
} }
static string funcNameProtect(const AstCFunc* nodep, const AstNodeModule* modp = nullptr); static string funcNameProtect(const AstCFunc* nodep, const AstNodeModule* modp = nullptr);
static string prefixNameProtect(const AstNode* nodep) { // C++ name with prefix static string prefixNameProtect(const AstNode* nodep) VL_MT_SAFE { // C++ name with prefix
return v3Global.opt.modPrefix() + "_" + protect(nodep->name()); return v3Global.opt.modPrefix() + "_" + protect(nodep->name());
} }
static string topClassName() VL_MT_SAFE { // Return name of top wrapper module static string topClassName() VL_MT_SAFE { // Return name of top wrapper module

View File

@ -108,7 +108,8 @@ class V3FileDependImp final {
}; };
// MEMBERS // MEMBERS
std::set<string> m_filenameSet; // Files generated (elim duplicates) VerilatedMutex m_mutex; // Protects members
std::set<string> m_filenameSet VL_GUARDED_BY(m_mutex); // Files generated (elim duplicates)
std::set<DependFile> m_filenameList; // Files sourced/generated std::set<DependFile> m_filenameList; // Files sourced/generated
static string stripQuotes(const string& in) { static string stripQuotes(const string& in) {
@ -121,7 +122,8 @@ class V3FileDependImp final {
public: public:
// ACCESSOR METHODS // ACCESSOR METHODS
void addSrcDepend(const string& filename) { void addSrcDepend(const string& filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
const VerilatedLockGuard lock{m_mutex};
const auto itFoundPair = m_filenameSet.insert(filename); const auto itFoundPair = m_filenameSet.insert(filename);
if (itFoundPair.second) { if (itFoundPair.second) {
DependFile df{filename, false}; DependFile df{filename, false};
@ -129,7 +131,8 @@ public:
m_filenameList.insert(df); m_filenameList.insert(df);
} }
} }
void addTgtDepend(const string& filename) { void addTgtDepend(const string& filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
const VerilatedLockGuard lock{m_mutex};
const auto itFoundPair = m_filenameSet.insert(filename); const auto itFoundPair = m_filenameSet.insert(filename);
if (itFoundPair.second) m_filenameList.insert(DependFile{filename, true}); if (itFoundPair.second) m_filenameList.insert(DependFile{filename, true});
} }
@ -297,8 +300,8 @@ bool V3FileDependImp::checkTimes(const string& filename, const string& cmdlineIn
//###################################################################### //######################################################################
// V3File // V3File
void V3File::addSrcDepend(const string& filename) { dependImp.addSrcDepend(filename); } void V3File::addSrcDepend(const string& filename) VL_MT_SAFE { dependImp.addSrcDepend(filename); }
void V3File::addTgtDepend(const string& filename) { dependImp.addTgtDepend(filename); } void V3File::addTgtDepend(const string& filename) VL_MT_SAFE { dependImp.addTgtDepend(filename); }
void V3File::writeDepend(const string& filename) { dependImp.writeDepend(filename); } void V3File::writeDepend(const string& filename) { dependImp.writeDepend(filename); }
std::vector<string> V3File::getAllDeps() { return dependImp.getAllDeps(); } std::vector<string> V3File::getAllDeps() { return dependImp.getAllDeps(); }
void V3File::writeTimes(const string& filename, const string& cmdlineIn) { void V3File::writeTimes(const string& filename, const string& cmdlineIn) {
@ -954,12 +957,13 @@ void V3OutCFile::putsGuard() {
class VIdProtectImp final { class VIdProtectImp final {
// MEMBERS // MEMBERS
VerilatedMutex m_mutex; // Protects members
std::map<const std::string, std::string> m_nameMap; // Map of old name into new name std::map<const std::string, std::string> m_nameMap; // Map of old name into new name
std::unordered_set<std::string> m_newIdSet; // Which new names exist std::unordered_set<std::string> m_newIdSet VL_GUARDED_BY(m_mutex); // Which new names exist
protected: protected:
// CONSTRUCTORS // CONSTRUCTORS
friend class VIdProtect; friend class VIdProtect;
static VIdProtectImp& singleton() { static VIdProtectImp& singleton() VL_MT_SAFE {
static VIdProtectImp s; static VIdProtectImp s;
return s; return s;
} }
@ -973,8 +977,9 @@ public:
} }
~VIdProtectImp() = default; ~VIdProtectImp() = default;
// METHODS // METHODS
string passthru(const string& old) { string passthru(const string& old) VL_MT_SAFE_EXCLUDES(m_mutex) {
if (!v3Global.opt.protectIds()) return old; if (!v3Global.opt.protectIds()) return old;
const VerilatedLockGuard lock{m_mutex};
const auto it = m_nameMap.find(old); const auto it = m_nameMap.find(old);
if (it != m_nameMap.end()) { if (it != m_nameMap.end()) {
// No way to go back and correct the older crypt name // No way to go back and correct the older crypt name
@ -986,8 +991,9 @@ public:
} }
return old; return old;
} }
string protectIf(const string& old, bool doIt) { string protectIf(const string& old, bool doIt) VL_MT_SAFE_EXCLUDES(m_mutex) {
if (!v3Global.opt.protectIds() || old.empty() || !doIt) return old; if (!v3Global.opt.protectIds() || old.empty() || !doIt) return old;
const VerilatedLockGuard lock{m_mutex};
const auto it = m_nameMap.find(old); const auto it = m_nameMap.find(old);
if (it != m_nameMap.end()) { if (it != m_nameMap.end()) {
return it->second; return it->second;
@ -1017,7 +1023,7 @@ public:
return out; return out;
} }
} }
string protectWordsIf(const string& old, bool doIt) { string protectWordsIf(const string& old, bool doIt) VL_MT_SAFE {
// Split at " " (for traces), "." (for scopes), "->", "(", "&", ")" (for self pointers) // Split at " " (for traces), "." (for scopes), "->", "(", "&", ")" (for self pointers)
if (!(doIt && v3Global.opt.protectIds())) return old; if (!(doIt && v3Global.opt.protectIds())) return old;
string out; string out;
@ -1056,7 +1062,7 @@ public:
private: private:
void trySep(const string& old, string::size_type start, const string& trySep, void trySep(const string& old, string::size_type start, const string& trySep,
string::size_type& posr, string& separatorr) { string::size_type& posr, string& separatorr) VL_PURE {
const string::size_type trypos = old.find(trySep, start); const string::size_type trypos = old.find(trySep, start);
if (trypos != string::npos) { if (trypos != string::npos) {
if (posr == string::npos || (posr > trypos)) { if (posr == string::npos || (posr > trypos)) {
@ -1067,10 +1073,10 @@ private:
} }
}; };
string VIdProtect::protectIf(const string& old, bool doIt) { string VIdProtect::protectIf(const string& old, bool doIt) VL_MT_SAFE {
return VIdProtectImp::singleton().protectIf(old, doIt); return VIdProtectImp::singleton().protectIf(old, doIt);
} }
string VIdProtect::protectWordsIf(const string& old, bool doIt) { string VIdProtect::protectWordsIf(const string& old, bool doIt) VL_MT_SAFE {
return VIdProtectImp::singleton().protectWordsIf(old, doIt); return VIdProtectImp::singleton().protectWordsIf(old, doIt);
} }
void VIdProtect::writeMapFile(const string& filename) { void VIdProtect::writeMapFile(const string& filename) {

View File

@ -61,8 +61,8 @@ public:
} }
// Dependencies // Dependencies
static void addSrcDepend(const string& filename); static void addSrcDepend(const string& filename) VL_MT_SAFE;
static void addTgtDepend(const string& filename); static void addTgtDepend(const string& filename) VL_MT_SAFE;
static void writeDepend(const string& filename); static void writeDepend(const string& filename);
static std::vector<string> getAllDeps(); static std::vector<string> getAllDeps();
static void writeTimes(const string& filename, const string& cmdlineIn); static void writeTimes(const string& filename, const string& cmdlineIn);
@ -318,10 +318,10 @@ class VIdProtect final {
public: public:
// METHODS // METHODS
// Rename to a new encoded string (unless earlier passthru'ed) // Rename to a new encoded string (unless earlier passthru'ed)
static string protect(const string& old) { return protectIf(old, true); } static string protect(const string& old) VL_MT_SAFE { return protectIf(old, true); }
static string protectIf(const string& old, bool doIt = true); static string protectIf(const string& old, bool doIt = true) VL_MT_SAFE;
// Rename words to a new encoded string // Rename words to a new encoded string
static string protectWordsIf(const string& old, bool doIt = true); static string protectWordsIf(const string& old, bool doIt = true) VL_MT_SAFE;
// Write map of renames to output file // Write map of renames to output file
static void writeMapFile(const string& filename); static void writeMapFile(const string& filename);
}; };

View File

@ -87,7 +87,9 @@ void FileLineSingleton::fileNameNumMapDumpXml(std::ostream& os) {
os << "</files>\n"; os << "</files>\n";
} }
FileLineSingleton::msgEnSetIdx_t FileLineSingleton::addMsgEnBitSet(const MsgEnBitSet& bitSet) { FileLineSingleton::msgEnSetIdx_t FileLineSingleton::addMsgEnBitSet(const MsgEnBitSet& bitSet)
VL_MT_SAFE_EXCLUDES(m_mutex) {
VerilatedLockGuard lock{m_mutex};
const auto pair = m_internedMsgEnIdxs.emplace(bitSet, 0); const auto pair = m_internedMsgEnIdxs.emplace(bitSet, 0);
msgEnSetIdx_t& idx = pair.first->second; msgEnSetIdx_t& idx = pair.first->second;
if (pair.second) { if (pair.second) {
@ -100,7 +102,7 @@ FileLineSingleton::msgEnSetIdx_t FileLineSingleton::addMsgEnBitSet(const MsgEnBi
return idx; return idx;
} }
FileLineSingleton::msgEnSetIdx_t FileLineSingleton::defaultMsgEnIndex() { FileLineSingleton::msgEnSetIdx_t FileLineSingleton::defaultMsgEnIndex() VL_MT_SAFE {
MsgEnBitSet msgEnBitSet; MsgEnBitSet msgEnBitSet;
for (int i = V3ErrorCode::EC_MIN; i < V3ErrorCode::_ENUM_MAX; ++i) { for (int i = V3ErrorCode::EC_MIN; i < V3ErrorCode::_ENUM_MAX; ++i) {
msgEnBitSet.set(i, !V3ErrorCode{i}.defaultsOff()); msgEnBitSet.set(i, !V3ErrorCode{i}.defaultsOff());

View File

@ -20,6 +20,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include "verilated_threads.h"
#include "V3Error.h" #include "V3Error.h"
#include "V3LangCode.h" #include "V3LangCode.h"
@ -50,12 +52,13 @@ class FileLineSingleton final {
using MsgEnBitSet = std::bitset<V3ErrorCode::_ENUM_MAX>; using MsgEnBitSet = std::bitset<V3ErrorCode::_ENUM_MAX>;
// MEMBERS // MEMBERS
VerilatedMutex m_mutex; // protects members
std::map<const std::string, fileNameIdx_t> m_namemap; // filenameno for each filename std::map<const std::string, fileNameIdx_t> m_namemap; // filenameno for each filename
std::deque<string> m_names; // filename text for each filenameno std::deque<string> m_names; // filename text for each filenameno
std::deque<V3LangCode> m_languages; // language for each filenameno std::deque<V3LangCode> m_languages; // language for each filenameno
// Map from flag set to the index in m_internedMsgEns for interning // Map from flag set to the index in m_internedMsgEns for interning
std::unordered_map<MsgEnBitSet, msgEnSetIdx_t> m_internedMsgEnIdxs; std::unordered_map<MsgEnBitSet, msgEnSetIdx_t> m_internedMsgEnIdxs VL_GUARDED_BY(m_mutex);
// Interned message enablement flag sets // Interned message enablement flag sets
std::vector<MsgEnBitSet> m_internedMsgEns; std::vector<MsgEnBitSet> m_internedMsgEns;
@ -78,9 +81,9 @@ class FileLineSingleton final {
static string filenameLetters(fileNameIdx_t fileno) VL_PURE; static string filenameLetters(fileNameIdx_t fileno) VL_PURE;
// Add given bitset to the interned bitsets, return interned index // Add given bitset to the interned bitsets, return interned index
msgEnSetIdx_t addMsgEnBitSet(const MsgEnBitSet& bitSet); msgEnSetIdx_t addMsgEnBitSet(const MsgEnBitSet& bitSet) VL_MT_SAFE_EXCLUDES(m_mutex);
// Add index of default bitset // Add index of default bitset
msgEnSetIdx_t defaultMsgEnIndex(); msgEnSetIdx_t defaultMsgEnIndex() VL_MT_SAFE;
// Set bitIdx to value in bitset at interned index setIdx, return interned index of result // Set bitIdx to value in bitset at interned index setIdx, return interned index of result
msgEnSetIdx_t msgEnSetBit(msgEnSetIdx_t setIdx, size_t bitIdx, bool value); msgEnSetIdx_t msgEnSetBit(msgEnSetIdx_t setIdx, size_t bitIdx, bool value);
// Return index to intersection set // Return index to intersection set

View File

@ -134,7 +134,9 @@ public:
~GateVarVertex() override = default; ~GateVarVertex() override = default;
// ACCESSORS // ACCESSORS
AstVarScope* varScp() const { return m_varScp; } AstVarScope* varScp() const { return m_varScp; }
string name() const override { return (cvtToHex(m_varScp) + " " + varScp()->name()); } string name() const override VL_MT_STABLE {
return (cvtToHex(m_varScp) + " " + varScp()->name());
}
string dotColor() const override { return "blue"; } string dotColor() const override { return "blue"; }
bool isTop() const { return m_isTop; } bool isTop() const { return m_isTop; }
void setIsTop() { m_isTop = true; } void setIsTop() { m_isTop = true; }
@ -174,7 +176,9 @@ public:
, m_slow{slow} {} , m_slow{slow} {}
~GateLogicVertex() override = default; ~GateLogicVertex() override = default;
// ACCESSORS // ACCESSORS
string name() const override { return (cvtToHex(m_nodep) + "@" + scopep()->prettyName()); } string name() const override VL_MT_STABLE {
return (cvtToHex(m_nodep) + "@" + scopep()->prettyName());
}
string dotColor() const override { return "purple"; } string dotColor() const override { return "purple"; }
FileLine* fileline() const override { return nodep()->fileline(); } FileLine* fileline() const override { return nodep()->fileline(); }
AstNode* nodep() const { return m_nodep; } AstNode* nodep() const { return m_nodep; }

View File

@ -98,7 +98,7 @@ class V3Global final {
VWidthMinUsage m_widthMinUsage VWidthMinUsage m_widthMinUsage
= VWidthMinUsage::LINT_WIDTH; // What AstNode::widthMin() is used for = VWidthMinUsage::LINT_WIDTH; // What AstNode::widthMin() is used for
int m_debugFileNumber = 0; // Number to append to debug files created std::atomic_int m_debugFileNumber{0}; // Number to append to debug files created
bool m_assertDTypesResolved = false; // Tree should have dtypep()'s bool m_assertDTypesResolved = false; // Tree should have dtypep()'s
bool m_assertScoped = false; // Tree is scoped bool m_assertScoped = false; // Tree is scoped
bool m_constRemoveXs = false; // Const needs to strip any Xs bool m_constRemoveXs = false; // Const needs to strip any Xs
@ -143,7 +143,7 @@ public:
void widthMinUsage(const VWidthMinUsage& flag) { m_widthMinUsage = flag; } void widthMinUsage(const VWidthMinUsage& flag) { m_widthMinUsage = flag; }
bool constRemoveXs() const { return m_constRemoveXs; } bool constRemoveXs() const { return m_constRemoveXs; }
void constRemoveXs(bool flag) { m_constRemoveXs = flag; } void constRemoveXs(bool flag) { m_constRemoveXs = flag; }
string debugFilename(const string& nameComment, int newNumber = 0) VL_MT_SAFE; string debugFilename(const string& nameComment, int newNumber = 0);
static string digitsFilename(int number); static string digitsFilename(int number);
bool needTraceDumper() const { return m_needTraceDumper; } bool needTraceDumper() const { return m_needTraceDumper; }
void needTraceDumper(bool flag) { m_needTraceDumper = flag; } void needTraceDumper(bool flag) { m_needTraceDumper = flag; }

View File

@ -60,7 +60,7 @@ public:
, m_name{name} {} , m_name{name} {}
~V3GraphTestVertex() override = default; ~V3GraphTestVertex() override = default;
// ACCESSORS // ACCESSORS
string name() const override { return m_name; } string name() const override VL_MT_STABLE { return m_name; }
}; };
class V3GraphTestVarVertex final : public V3GraphTestVertex { class V3GraphTestVarVertex final : public V3GraphTestVertex {

View File

@ -59,8 +59,8 @@ public:
: V3GraphVertex{graphp} : V3GraphVertex{graphp}
, m_modp{modp} {} , m_modp{modp} {}
~LinkCellsVertex() override = default; ~LinkCellsVertex() override = default;
AstNodeModule* modp() const { return m_modp; } AstNodeModule* modp() const VL_MT_STABLE { return m_modp; }
string name() const override { return modp()->name(); } string name() const override VL_MT_STABLE { return modp()->name(); }
FileLine* fileline() const override { return modp()->fileline(); } FileLine* fileline() const override { return modp()->fileline(); }
// Recursive modules get space for maximum recursion // Recursive modules get space for maximum recursion
uint32_t rankAdder() const override { uint32_t rankAdder() const override {
@ -73,7 +73,7 @@ public:
explicit LibraryVertex(V3Graph* graphp) explicit LibraryVertex(V3Graph* graphp)
: V3GraphVertex{graphp} {} : V3GraphVertex{graphp} {}
~LibraryVertex() override = default; ~LibraryVertex() override = default;
string name() const override { return "*LIBRARY*"; } string name() const override VL_MT_STABLE { return "*LIBRARY*"; }
}; };
void LinkCellsGraph::loopsMessageCb(V3GraphVertex* vertexp) { void LinkCellsGraph::loopsMessageCb(V3GraphVertex* vertexp) {

View File

@ -498,7 +498,7 @@ V3Number& V3Number::setMask(int nbits) {
//====================================================================== //======================================================================
// ACCESSORS - as strings // ACCESSORS - as strings
string V3Number::ascii(bool prefixed, bool cleanVerilog) const { string V3Number::ascii(bool prefixed, bool cleanVerilog) const VL_MT_SAFE {
std::ostringstream out; std::ostringstream out;
if (is1Step()) { if (is1Step()) {
@ -1050,7 +1050,7 @@ bool V3Number::isEqAllOnes(int optwidth) const {
} }
return true; return true;
} }
bool V3Number::isFourState() const { bool V3Number::isFourState() const VL_MT_SAFE {
if (isDouble() || isString()) return false; if (isDouble() || isString()) return false;
for (int i = 0; i < words(); ++i) { for (int i = 0; i < words(); ++i) {
if (m_data.num()[i].m_valueX) return true; if (m_data.num()[i].m_valueX) return true;

View File

@ -583,7 +583,7 @@ public:
V3Number& setMask(int nbits); // IE if nbits=1, then 0b1, if 2->0b11, if 3->0b111 etc V3Number& setMask(int nbits); // IE if nbits=1, then 0b1, if 2->0b11, if 3->0b111 etc
// ACCESSORS // ACCESSORS
string ascii(bool prefixed = true, bool cleanVerilog = false) const; string ascii(bool prefixed = true, bool cleanVerilog = false) const VL_MT_SAFE;
string displayed(AstNode* nodep, const string& vformat) const VL_MT_SAFE; string displayed(AstNode* nodep, const string& vformat) const VL_MT_SAFE;
static bool displayedFmtLegal(char format, bool isScan); // Is this a valid format letter? static bool displayedFmtLegal(char format, bool isScan); // Is this a valid format letter?
int width() const VL_MT_SAFE { return m_data.width(); } int width() const VL_MT_SAFE { return m_data.width(); }
@ -615,7 +615,7 @@ public:
bool isNegative() const { return !isString() && bitIs1(width() - 1); } bool isNegative() const { return !isString() && bitIs1(width() - 1); }
bool is1Step() const VL_MT_SAFE { return m_data.m_is1Step; } bool is1Step() const VL_MT_SAFE { return m_data.m_is1Step; }
bool isNull() const VL_MT_SAFE { return m_data.m_isNull; } bool isNull() const VL_MT_SAFE { return m_data.m_isNull; }
bool isFourState() const; bool isFourState() const VL_MT_SAFE;
bool hasZ() const { bool hasZ() const {
if (isString()) return false; if (isString()) return false;
for (int i = 0; i < words(); i++) { for (int i = 0; i < words(); i++) {

View File

@ -880,7 +880,9 @@ string V3Options::version() VL_PURE {
return ver; return ver;
} }
string V3Options::protectKeyDefaulted() { string V3Options::protectKeyDefaulted() VL_MT_SAFE {
static VerilatedMutex mutex;
const VerilatedLockGuard lock{mutex};
if (m_protectKey.empty()) { if (m_protectKey.empty()) {
// Create a key with a human-readable symbol-like name. // Create a key with a human-readable symbol-like name.
// This conversion drops ~2 bits of entropy out of 256, shouldn't matter. // This conversion drops ~2 bits of entropy out of 256, shouldn't matter.

View File

@ -573,7 +573,7 @@ public:
string prefix() const VL_MT_SAFE { return m_prefix; } string prefix() const VL_MT_SAFE { return m_prefix; }
// Not just called protectKey() to avoid bugs of not using protectKeyDefaulted() // Not just called protectKey() to avoid bugs of not using protectKeyDefaulted()
bool protectKeyProvided() const { return !m_protectKey.empty(); } bool protectKeyProvided() const { return !m_protectKey.empty(); }
string protectKeyDefaulted(); // Set default key if not set by user string protectKeyDefaulted() VL_MT_SAFE; // Set default key if not set by user
string topModule() const { return m_topModule; } string topModule() const { return m_topModule; }
string unusedRegexp() const { return m_unusedRegexp; } string unusedRegexp() const { return m_unusedRegexp; }
string waiverOutput() const { return m_waiverOutput; } string waiverOutput() const { return m_waiverOutput; }

View File

@ -159,7 +159,7 @@ public:
AstSenTree* hybridp() const { return m_hybridp; } AstSenTree* hybridp() const { return m_hybridp; }
// LCOV_EXCL_START // Debug code // LCOV_EXCL_START // Debug code
string name() const override { string name() const override VL_MT_STABLE {
return (cvtToHex(m_nodep) + "\\n " + cvtToStr(nodep()->typeName())); return (cvtToHex(m_nodep) + "\\n " + cvtToStr(nodep()->typeName()));
} }
string dotShape() const override { return VN_IS(m_nodep, Active) ? "doubleoctagon" : "rect"; } string dotShape() const override { return VN_IS(m_nodep, Active) ? "doubleoctagon" : "rect"; }
@ -182,7 +182,7 @@ public:
// LCOV_EXCL_START // Debug code // LCOV_EXCL_START // Debug code
string dotShape() const override final { return "ellipse"; } string dotShape() const override final { return "ellipse"; }
virtual string nameSuffix() const = 0; virtual string nameSuffix() const = 0;
string name() const override final { string name() const override final VL_MT_STABLE {
return cvtToHex(m_vscp) + " " + nameSuffix() + "\\n " + m_vscp->name(); return cvtToHex(m_vscp) + " " + nameSuffix() + "\\n " + m_vscp->name();
} }
// LCOV_EXCL_STOP // LCOV_EXCL_STOP

View File

@ -64,7 +64,7 @@ public:
} }
} }
string name() const override { string name() const override VL_MT_STABLE {
string nm; string nm;
if (VL_UNCOVERABLE(!logicp())) { // Avoid crash when debugging if (VL_UNCOVERABLE(!logicp())) { // Avoid crash when debugging
nm = "nul"; // LCOV_EXCL_LINE nm = "nul"; // LCOV_EXCL_LINE

View File

@ -28,6 +28,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include "verilated_threads.h"
// Limited V3 headers here - this is a base class for Vlc etc // Limited V3 headers here - this is a base class for Vlc etc
#include "V3Os.h" #include "V3Os.h"
#include "V3String.h" #include "V3String.h"
@ -286,7 +288,7 @@ uint64_t V3Os::rand64(std::array<uint64_t, 2>& stater) {
return result; return result;
} }
string V3Os::trueRandom(size_t size) { string V3Os::trueRandom(size_t size) VL_MT_SAFE {
string result(size, '\xFF'); string result(size, '\xFF');
char* const data = const_cast<char*>(result.data()); char* const data = const_cast<char*>(result.data());
// Note: std::string.data() returns a non-const Char* from C++17 onwards. // Note: std::string.data() returns a non-const Char* from C++17 onwards.

View File

@ -59,7 +59,7 @@ public:
// METHODS (random) // METHODS (random)
static uint64_t rand64(std::array<uint64_t, 2>& stater); static uint64_t rand64(std::array<uint64_t, 2>& stater);
static string trueRandom(size_t size); static string trueRandom(size_t size) VL_MT_SAFE;
// METHODS (time & performance) // METHODS (time & performance)
static void u_sleep(int64_t usec); ///< Sleep for a given number of microseconds. static void u_sleep(int64_t usec); ///< Sleep for a given number of microseconds.

View File

@ -321,7 +321,7 @@ public:
void checkRelativesCp(GraphWay way) const; void checkRelativesCp(GraphWay way) const;
string name() const override { string name() const override VL_MT_STABLE {
// Display forward and reverse critical path costs. This gives a quick // Display forward and reverse critical path costs. This gives a quick
// read on whether graph partitioning looks reasonable or bad. // read on whether graph partitioning looks reasonable or bad.
std::ostringstream out; std::ostringstream out;

View File

@ -85,7 +85,7 @@ public:
// If this MTask maps to a C function, this should be the name // If this MTask maps to a C function, this should be the name
return std::string{"__Vmtask"} + "__" + cvtToStr(m_id); return std::string{"__Vmtask"} + "__" + cvtToStr(m_id);
} }
string name() const override { return std::string{"mt"} + cvtToStr(id()); } string name() const override VL_MT_STABLE { return std::string{"mt"} + cvtToStr(id()); }
string hashName() const { return m_hashName; } string hashName() const { return m_hashName; }
void hashName(const string& name) { m_hashName = name; } void hashName(const string& name) { m_hashName = name; }
void dump(std::ostream& str) const { void dump(std::ostream& str) const {

View File

@ -76,7 +76,7 @@ public:
AstScope* scopep() const { return m_scopep; } AstScope* scopep() const { return m_scopep; }
// LCOV_EXCL_START // Debug code // LCOV_EXCL_START // Debug code
string name() const override { return m_logicp->fileline()->ascii(); }; string name() const override VL_MT_STABLE { return m_logicp->fileline()->ascii(); };
string dotShape() const override { return "rectangle2"; } string dotShape() const override { return "rectangle2"; }
// LCOV_EXCL_STOP // LCOV_EXCL_STOP
}; };
@ -93,7 +93,7 @@ public:
V3GraphVertex* clone(V3Graph* graphp) const override { return new VarVertex{graphp, vscp()}; } V3GraphVertex* clone(V3Graph* graphp) const override { return new VarVertex{graphp, vscp()}; }
// LCOV_EXCL_START // Debug code // LCOV_EXCL_START // Debug code
string name() const override { return m_vscp->name(); } string name() const override VL_MT_STABLE { return m_vscp->name(); }
string dotShape() const override { return "ellipse"; } string dotShape() const override { return "ellipse"; }
string dotColor() const override { return "blue"; } string dotColor() const override { return "blue"; }
// LCOV_EXCL_STOP // LCOV_EXCL_STOP

View File

@ -89,7 +89,7 @@ public:
AstNode* logicp() const { return m_logicp; } AstNode* logicp() const { return m_logicp; }
// LCOV_EXCL_START // Debug code // LCOV_EXCL_START // Debug code
string name() const override { string name() const override VL_MT_STABLE {
return m_logicp->typeName() + ("\n" + m_logicp->fileline()->ascii()); return m_logicp->typeName() + ("\n" + m_logicp->fileline()->ascii());
}; };
string dotShape() const override { return "rectangle"; } string dotShape() const override { return "rectangle"; }
@ -105,7 +105,7 @@ public:
, m_vscp{vscp} {} , m_vscp{vscp} {}
// LCOV_EXCL_START // Debug code // LCOV_EXCL_START // Debug code
string name() const override { return m_vscp->name(); } string name() const override VL_MT_STABLE { return m_vscp->name(); }
string dotShape() const override { string dotShape() const override {
return m_vscp->scopep()->isTop() && m_vscp->varp()->isNonOutput() ? "invhouse" : "ellipse"; return m_vscp->scopep()->isTop() && m_vscp->varp()->isNonOutput() ? "invhouse" : "ellipse";
} }

View File

@ -109,7 +109,7 @@ public:
RegionFlags assignedRegion() const { return m_assignedRegion; } RegionFlags assignedRegion() const { return m_assignedRegion; }
// For graph dumping // For graph dumping
string name() const override { return m_logicp->fileline()->ascii(); }; string name() const override VL_MT_STABLE { return m_logicp->fileline()->ascii(); };
string dotShape() const override { return "rectangle"; } string dotShape() const override { return "rectangle"; }
}; };
@ -134,7 +134,7 @@ public:
AstScope* scopep() const { return m_vscp->scopep(); } AstScope* scopep() const { return m_vscp->scopep(); }
// For graph dumping // For graph dumping
string name() const override { return m_vscp->name(); } string name() const override VL_MT_STABLE { return m_vscp->name(); }
string dotShape() const override { return varp()->isPrimaryInish() ? "invhouse" : "ellipse"; } string dotShape() const override { return varp()->isPrimaryInish() ? "invhouse" : "ellipse"; }
}; };

View File

@ -109,7 +109,9 @@ protected:
// ACCESSORS // ACCESSORS
// Do not make accessor for nodep(), It may change due to // Do not make accessor for nodep(), It may change due to
// reordering a lower block, but we don't repair it // reordering a lower block, but we don't repair it
string name() const override { return cvtToHex(m_nodep) + ' ' + m_nodep->prettyTypeName(); } string name() const override VL_MT_STABLE {
return cvtToHex(m_nodep) + ' ' + m_nodep->prettyTypeName();
}
FileLine* fileline() const override { return nodep()->fileline(); } FileLine* fileline() const override { return nodep()->fileline(); }
public: public:
@ -121,7 +123,7 @@ public:
explicit SplitPliVertex(V3Graph* graphp, AstNode* nodep) explicit SplitPliVertex(V3Graph* graphp, AstNode* nodep)
: SplitNodeVertex{graphp, nodep} {} : SplitNodeVertex{graphp, nodep} {}
~SplitPliVertex() override = default; ~SplitPliVertex() override = default;
string name() const override { return "*PLI*"; } string name() const override VL_MT_STABLE { return "*PLI*"; }
string dotColor() const override { return "green"; } string dotColor() const override { return "green"; }
}; };
@ -146,7 +148,7 @@ public:
SplitVarPostVertex(V3Graph* graphp, AstNode* nodep) SplitVarPostVertex(V3Graph* graphp, AstNode* nodep)
: SplitNodeVertex{graphp, nodep} {} : SplitNodeVertex{graphp, nodep} {}
~SplitVarPostVertex() override = default; ~SplitVarPostVertex() override = default;
string name() const override { return string("POST ") + SplitNodeVertex::name(); } string name() const override VL_MT_STABLE { return string("POST ") + SplitNodeVertex::name(); }
string dotColor() const override { return "CadetBlue"; } string dotColor() const override { return "CadetBlue"; }
}; };

View File

@ -67,8 +67,8 @@ public:
: TaskBaseVertex{graphp} : TaskBaseVertex{graphp}
, m_nodep{nodep} {} , m_nodep{nodep} {}
~TaskFTaskVertex() override = default; ~TaskFTaskVertex() override = default;
AstNodeFTask* nodep() const { return m_nodep; } AstNodeFTask* nodep() const VL_MT_STABLE { return m_nodep; }
string name() const override { return nodep()->name(); } string name() const override VL_MT_STABLE { return nodep()->name(); }
string dotColor() const override { return pure() ? "black" : "red"; } string dotColor() const override { return pure() ? "black" : "red"; }
AstCFunc* cFuncp() const { return m_cFuncp; } AstCFunc* cFuncp() const { return m_cFuncp; }
void cFuncp(AstCFunc* nodep) { m_cFuncp = nodep; } void cFuncp(AstCFunc* nodep) { m_cFuncp = nodep; }
@ -80,7 +80,7 @@ public:
explicit TaskCodeVertex(V3Graph* graphp) explicit TaskCodeVertex(V3Graph* graphp)
: TaskBaseVertex{graphp} {} : TaskBaseVertex{graphp} {}
~TaskCodeVertex() override = default; ~TaskCodeVertex() override = default;
string name() const override { return "*CODE*"; } string name() const override VL_MT_STABLE { return "*CODE*"; }
string dotColor() const override { return "green"; } string dotColor() const override { return "green"; }
}; };

View File

@ -67,7 +67,7 @@ private:
class DependencyVertex final : public V3GraphVertex { class DependencyVertex final : public V3GraphVertex {
AstNode* const m_nodep; // AST node represented by this graph vertex AstNode* const m_nodep; // AST node represented by this graph vertex
// ACCESSORS // ACCESSORS
string name() const override { string name() const override VL_MT_STABLE {
return cvtToHex(nodep()) + ' ' + nodep()->prettyTypeName(); return cvtToHex(nodep()) + ' ' + nodep()->prettyTypeName();
} }
FileLine* fileline() const override { return nodep()->fileline(); } FileLine* fileline() const override { return nodep()->fileline(); }

View File

@ -154,7 +154,7 @@ public:
// ACCESSORS // ACCESSORS
AstNode* nodep() const { return m_nodep; } AstNode* nodep() const { return m_nodep; }
const AstVar* varp() const { return VN_CAST(nodep(), Var); } const AstVar* varp() const { return VN_CAST(nodep(), Var); }
string name() const override { string name() const override VL_MT_STABLE {
return ((isTristate() ? "tri\\n" return ((isTristate() ? "tri\\n"
: feedsTri() ? "feed\\n" : feedsTri() ? "feed\\n"
: "-\\n") : "-\\n")

View File

@ -23,8 +23,9 @@
#include <memory> #include <memory>
#include <sstream> #include <sstream>
void V3Waiver::addEntry(V3ErrorCode errorCode, const std::string& filename, void V3Waiver::addEntry(V3ErrorCode errorCode, const std::string& filename, const std::string& str)
const std::string& str) { VL_MT_SAFE_EXCLUDES(s_mutex) {
const VerilatedLockGuard lock{s_mutex};
std::stringstream entry; std::stringstream entry;
const size_t pos = str.find('\n'); const size_t pos = str.find('\n');
entry << "lint_off -rule " << errorCode.ascii() << " -file \"*" << filename << "\" -match \"" entry << "lint_off -rule " << errorCode.ascii() << " -file \"*" << filename << "\" -match \""
@ -34,7 +35,7 @@ void V3Waiver::addEntry(V3ErrorCode errorCode, const std::string& filename,
s_waiverList.push_back(entry.str()); s_waiverList.push_back(entry.str());
} }
void V3Waiver::write(const std::string& filename) { void V3Waiver::write(const std::string& filename) VL_MT_SAFE_EXCLUDES(s_mutex) {
const std::unique_ptr<std::ofstream> ofp{V3File::new_ofstream(filename)}; const std::unique_ptr<std::ofstream> ofp{V3File::new_ofstream(filename)};
if (ofp->fail()) v3fatal("Can't write " << filename); if (ofp->fail()) v3fatal("Can't write " << filename);
@ -48,9 +49,12 @@ void V3Waiver::write(const std::string& filename) {
*ofp << "// 2. Keep the waiver permanently if you are sure this is okay\n"; *ofp << "// 2. Keep the waiver permanently if you are sure this is okay\n";
*ofp << "// 3. Keep the waiver temporarily to suppress the output\n\n"; *ofp << "// 3. Keep the waiver temporarily to suppress the output\n\n";
const VerilatedLockGuard lock{s_mutex};
if (s_waiverList.empty()) *ofp << "// No waivers needed - great!\n"; if (s_waiverList.empty()) *ofp << "// No waivers needed - great!\n";
for (const auto& i : s_waiverList) *ofp << "// " << i << "\n\n"; for (const auto& i : s_waiverList) *ofp << "// " << i << "\n\n";
} }
VerilatedMutex V3Waiver::s_mutex;
V3Waiver::WaiverList V3Waiver::s_waiverList; V3Waiver::WaiverList V3Waiver::s_waiverList;

View File

@ -17,6 +17,8 @@
#ifndef VERILATOR_V3WAIVER_H_ #ifndef VERILATOR_V3WAIVER_H_
#define VERILATOR_V3WAIVER_H_ #define VERILATOR_V3WAIVER_H_
#include "verilated_threads.h"
#include "V3Error.h" #include "V3Error.h"
#include <string> #include <string>
@ -25,11 +27,13 @@
class V3Waiver final { class V3Waiver final {
// TYPES // TYPES
using WaiverList = std::vector<std::string>; using WaiverList = std::vector<std::string>;
static WaiverList s_waiverList; static VerilatedMutex s_mutex; // Protect members
static WaiverList s_waiverList VL_GUARDED_BY(s_mutex);
public: public:
static void addEntry(V3ErrorCode errorCode, const string& filename, const std::string& str); static void addEntry(V3ErrorCode errorCode, const string& filename, const std::string& str)
static void write(const std::string& filename); VL_MT_SAFE_EXCLUDES(s_mutex);
static void write(const std::string& filename) VL_MT_SAFE_EXCLUDES(s_mutex);
}; };
#endif // Guard #endif // Guard