Internals: Refactor V3EmitUtil to not be base class. No functional change.

This commit is contained in:
Wilson Snyder 2025-08-25 22:05:40 -04:00
parent ac2859bf24
commit 5f23bf95f6
24 changed files with 259 additions and 236 deletions

View File

@ -954,10 +954,10 @@ AstNodeDType::CTypeRecursed AstNodeDType::cTypeRecurse(bool compound, bool packe
info.m_type = "VlSampleQueue<" + sub.m_type + ">";
} else if (const auto* const adtypep = VN_CAST(dtypep, ClassRefDType)) {
UASSERT_OBJ(!packed, this, "Unsupported type for packed struct or union");
info.m_type = "VlClassRef<" + EmitCBase::prefixNameProtect(adtypep) + ">";
info.m_type = "VlClassRef<" + EmitCUtil::prefixNameProtect(adtypep) + ">";
} else if (const auto* const adtypep = VN_CAST(dtypep, IfaceRefDType)) {
UASSERT_OBJ(!packed, this, "Unsupported type for packed struct or union");
info.m_type = EmitCBase::prefixNameProtect(adtypep->ifaceViaCellp()) + "*";
info.m_type = EmitCUtil::prefixNameProtect(adtypep->ifaceViaCellp()) + "*";
} else if (const auto* const adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
UASSERT_OBJ(!packed, this, "Unsupported type for packed struct or union");
if (adtypep->isCompound()) compound = true;
@ -991,7 +991,7 @@ AstNodeDType::CTypeRecursed AstNodeDType::cTypeRecurse(bool compound, bool packe
const AstNodeUOrStructDType* const sdtypep = VN_AS(dtypep, NodeUOrStructDType);
UASSERT_OBJ(!packed || sdtypep->packed(), this,
"Unsupported type for packed struct or union");
info.m_type = EmitCBase::prefixNameProtect(sdtypep);
info.m_type = EmitCUtil::prefixNameProtect(sdtypep);
} 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

View File

@ -67,7 +67,7 @@ class V3CCtorsBuilder final {
funcp->slow(!m_type.isClass()); // Only classes construct on fast path
string preventUnusedStmt;
if (m_type.isClass()) {
funcp->argTypes(EmitCBase::symClassVar());
funcp->argTypes(EmitCUtil::symClassVar());
preventUnusedStmt = "(void)vlSymsp; // Prevent unused variable warning\n";
} else if (m_type.isCoverage()) {
funcp->argTypes("bool first");

View File

@ -52,7 +52,7 @@ string V3Common::makeToStringCall(AstNodeDType* nodep, const std::string& lhs) {
static void makeVlToString(AstClass* nodep) {
AstCFunc* const funcp
= new AstCFunc{nodep->fileline(), "VL_TO_STRING", nullptr, "std::string"};
funcp->argTypes("const VlClassRef<" + EmitCBase::prefixNameProtect(nodep) + ">& obj");
funcp->argTypes("const VlClassRef<" + EmitCUtil::prefixNameProtect(nodep) + ">& obj");
funcp->isMethod(false);
funcp->isConst(false);
funcp->isStatic(false);
@ -66,7 +66,7 @@ static void makeVlToString(AstClass* nodep) {
static void makeVlToString(AstIface* nodep) {
AstCFunc* const funcp
= new AstCFunc{nodep->fileline(), "VL_TO_STRING", nullptr, "std::string"};
funcp->argTypes("const " + EmitCBase::prefixNameProtect(nodep) + "* obj");
funcp->argTypes("const " + EmitCUtil::prefixNameProtect(nodep) + "* obj");
funcp->isMethod(false);
funcp->isConst(false);
funcp->isStatic(false);
@ -81,7 +81,7 @@ static void makeVlToString(AstNodeUOrStructDType* nodep) {
UASSERT_OBJ(modp, nodep, "Unlinked struct package");
AstCFunc* const funcp
= new AstCFunc{nodep->fileline(), "VL_TO_STRING", nullptr, "std::string"};
funcp->argTypes("const " + EmitCBase::prefixNameProtect(nodep) + "& obj");
funcp->argTypes("const " + EmitCUtil::prefixNameProtect(nodep) + "& obj");
funcp->isMethod(false);
funcp->isConst(false);
funcp->isStatic(false);
@ -145,7 +145,7 @@ static void makeToStringMiddle(AstClass* nodep) {
string stmt = "out += ";
if (!comma.empty()) stmt += "\", \"+ ";
// comma = ", "; // Nothing further so not needed
stmt += EmitCBase::prefixNameProtect(nodep->extendsp()->dtypep());
stmt += EmitCUtil::prefixNameProtect(nodep->extendsp()->dtypep());
stmt += "::to_string_middle();\n";
nodep->user1(true); // So what we extend dumps this
funcp->addStmtsp(new AstCStmt{nodep->fileline(), stmt});

View File

@ -57,7 +57,7 @@ class DepthBlockVisitor final : public VNVisitor {
AstCCall* const callp = new AstCCall{nodep->fileline(), funcp};
callp->dtypeSetVoid();
if (VN_IS(m_modp, Class)) {
funcp->argTypes(EmitCBase::symClassVar());
funcp->argTypes(EmitCUtil::symClassVar());
callp->argTypes("vlSymsp");
}
UINFO(6, " New " << callp);

View File

@ -36,9 +36,9 @@ EmitCParentModule::EmitCParentModule() {
}
//######################################################################
// EmitCBase implementation
// EmitCUtil implementation
string EmitCBase::prefixNameProtect(const AstNode* nodep) VL_MT_STABLE {
string EmitCUtil::prefixNameProtect(const AstNode* nodep) VL_MT_STABLE {
const string prefix = v3Global.opt.modPrefix() + "_" + VIdProtect::protect(nodep->name());
// If all-uppercase prefix conflicts with a previous usage of the
// prefix with different capitalization, rename to avoid conflict.
@ -78,13 +78,13 @@ string EmitCBaseVisitorConst::funcNameProtect(const AstCFunc* nodep, const AstNo
modp = modp ? modp : EmitCParentModule::get(nodep);
string name;
if (nodep->isConstructor()) {
name += prefixNameProtect(modp);
name += EmitCUtil::prefixNameProtect(modp);
} else if (nodep->isDestructor()) {
name += "~";
name += prefixNameProtect(modp);
name += EmitCUtil::prefixNameProtect(modp);
} else {
if (nodep->isLoose()) {
name += prefixNameProtect(modp);
name += EmitCUtil::prefixNameProtect(modp);
name += "__";
}
name += nodep->nameProtect();
@ -112,7 +112,7 @@ string EmitCBaseVisitorConst::cFuncArgs(const AstCFunc* nodep) {
string args;
if (nodep->isLoose() && !nodep->isStatic()) {
if (nodep->isConst().trueKnown()) args += "const ";
args += prefixNameProtect(EmitCParentModule::get(nodep));
args += EmitCUtil::prefixNameProtect(EmitCParentModule::get(nodep));
args += "* vlSelf";
}
if (nodep->needProcess()) {
@ -150,9 +150,9 @@ void EmitCBaseVisitorConst::emitCFuncHeader(const AstCFunc* funcp, const AstNode
}
if (withScope) {
if (funcp->dpiExportDispatcher()) {
putns(funcp, topClassName() + "::");
putns(funcp, EmitCUtil::topClassName() + "::");
} else if (funcp->isProperMethod()) {
putns(funcp, prefixNameProtect(modp) + "::");
putns(funcp, EmitCUtil::prefixNameProtect(modp) + "::");
}
}
putns(funcp, funcNameProtect(funcp, modp));
@ -313,7 +313,7 @@ std::pair<string, FileLine*> EmitCBaseVisitorConst::textSection(const AstNodeMod
string::size_type pos;
while ((pos = text.find("`systemc_class_name")) != string::npos) {
text.replace(pos, std::strlen("`systemc_class_name"),
EmitCBase::prefixNameProtect(modp));
EmitCUtil::prefixNameProtect(modp));
}
}
return std::make_pair(text, fl);

View File

@ -45,9 +45,9 @@ public:
};
//######################################################################
// Base Visitor class -- holds output file pointer
// EmitC-related utility functions
class EmitCBase VL_NOT_FINAL {
class EmitCUtil final {
public:
static string voidSelfAssign(const AstNodeModule* modp) {
const string className = prefixNameProtect(modp);
@ -81,7 +81,10 @@ public:
}
};
class EmitCBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst, public EmitCBase {
//######################################################################
// Base Visitor class -- holds output file pointer
class EmitCBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst {
public:
// STATE
V3OutCFile* m_ofp = nullptr;
@ -130,15 +133,6 @@ public:
void ensureNewLine() { ofp()->ensureNewLine(); }
bool optSystemC() { return v3Global.opt.systemC(); }
static string protect(const string& name) VL_MT_SAFE { return VIdProtect::protect(name); }
static string protectIf(const string& name, bool doIt) {
return VIdProtect::protectIf(name, doIt);
}
static string protectWordsIf(const string& name, bool doIt) {
return VIdProtect::protectWordsIf(name, doIt);
}
static string ifNoProtect(const string& in) VL_MT_SAFE {
return v3Global.opt.protectIds() ? "" : in;
}
static string funcNameProtect(const AstCFunc* nodep, const AstNodeModule* modp = nullptr);
static AstCFile* newCFile(const string& filename, bool slow, bool source);
static AstCFile* createCFile(const string& filename, bool slow, bool source) VL_MT_SAFE;
@ -153,11 +147,11 @@ public:
if (const AstCUse* const usep = VN_CAST(itemp, CUse)) {
if (usep->useType().containsAny(useType)) {
if (usep->useType().containsAny(VUseType::INT_INCLUDE)) {
action("#include \"" + prefixNameProtect(usep) + ".h\"\n");
action("#include \"" + EmitCUtil::prefixNameProtect(usep) + ".h\"\n");
continue; // Forward declaration is not necessary
}
if (usep->useType().containsAny(VUseType::INT_FWD_CLASS)) {
action("class " + prefixNameProtect(usep) + ";\n");
action("class " + EmitCUtil::prefixNameProtect(usep) + ";\n");
}
}
}

View File

@ -32,7 +32,6 @@ class EmitCConstInit VL_NOT_FINAL : public EmitCBaseVisitorConst {
bool m_inUnpacked = false;
// METHODS
uint32_t tabModulus(const AstNodeDType* dtypep) {
const uint32_t elemBytes = dtypep->widthTotalBytes();
return dtypep->isString() ? 1 // String
@ -99,6 +98,7 @@ protected:
} // LCOV_EXCL_STOP
void visit(AstConst* nodep) override {
// TODO merge with EmitCFunc::emitConstant
const V3Number& num = nodep->num();
UASSERT_OBJ(!num.isFourState(), nodep, "4-state value in constant pool");
const AstNodeDType* const dtypep = nodep->dtypep();

View File

@ -42,8 +42,8 @@ class EmitCConstPool final : public EmitCConstInit {
// METHODS
OutCFilePair newOutCFile() const {
const string fileName = v3Global.opt.makeDir() + "/" + topClassName() + "__ConstPool_"
+ cvtToStr(m_outFileCount) + ".cpp";
const string fileName = v3Global.opt.makeDir() + "/" + EmitCUtil::topClassName()
+ "__ConstPool_" + cvtToStr(m_outFileCount) + ".cpp";
AstCFile* const cfilep = newCFile(fileName, /* slow: */ true, /* source: */ true);
V3OutCFile* const ofp = new V3OutCFile{fileName};
ofp->putsHeader();
@ -84,7 +84,8 @@ class EmitCConstPool final : public EmitCConstInit {
for (const AstVar* varp : varps) {
maybeSplitCFile();
const string nameProtect = topClassName() + "__ConstPool__" + varp->nameProtect();
const string nameProtect
= EmitCUtil::topClassName() + "__ConstPool__" + varp->nameProtect();
puts("\n");
putns(varp, "extern const ");
putns(varp, varp->dtypep()->cType(nameProtect, false, false));

View File

@ -488,6 +488,7 @@ void EmitCFunc::emitCvtWideArray(AstNode* nodep, AstNode* fromp) {
void EmitCFunc::emitConstant(AstConst* nodep, AstVarRef* assigntop, const string& assignString) {
// Put out constant set to the specified variable, or given variable in a string
// TODO merge with V3EmitCConstInit::visit(AstConst)
putns(nodep, "");
if (nodep->num().isNull()) {
putns(nodep, "VlNull{}");

View File

@ -64,7 +64,7 @@ class EmitCLazyDecls final : public VNVisitorConst {
void lazyDeclareConstPoolVar(AstVar* varp) {
if (!declaredOnce(varp)) return; // Already declared
const string nameProtect
= m_emitter.topClassName() + "__ConstPool__" + varp->nameProtect();
= EmitCUtil::topClassName() + "__ConstPool__" + varp->nameProtect();
m_emitter.putns(varp, "extern const ");
m_emitter.puts(varp->dtypep()->cType(nameProtect, false, false));
m_emitter.puts(";\n");
@ -85,7 +85,7 @@ class EmitCLazyDecls final : public VNVisitorConst {
void visit(AstVarRef* nodep) override {
AstVar* const varp = nodep->varp();
// Only constant pool symbols are lazy declared for now ...
if (EmitCBase::isConstPoolMod(EmitCParentModule::get(varp))) {
if (EmitCUtil::isConstPoolMod(EmitCParentModule::get(varp))) {
lazyDeclareConstPoolVar(varp);
}
}
@ -272,7 +272,7 @@ public:
if (doneClasses.count(vbase)) continue;
puts(doneClasses.empty() ? "" : "\n , ");
doneClasses.emplace(vbase);
puts(prefixNameProtect(vbase));
puts(EmitCUtil::EmitCUtil::prefixNameProtect(vbase));
if (constructorNeedsProcess(vbase)) {
puts("(vlProcess, vlSymsp)");
} else {
@ -287,7 +287,7 @@ public:
if (doneClasses.count(extp->classp())) continue;
puts(doneClasses.empty() ? "" : "\n , ");
doneClasses.emplace(extp->classp());
puts(prefixNameProtect(extp->classp()));
puts(EmitCUtil::EmitCUtil::prefixNameProtect(extp->classp()));
if (constructorNeedsProcess(extp->classp())) {
puts("(vlProcess, vlSymsp");
} else {
@ -349,7 +349,7 @@ public:
// "+" in the debug indicates a print from the model
puts("VL_DEBUG_IF(VL_DBG_MSGF(\"+ ");
for (int i = 0; i < m_modp->level(); ++i) puts(" ");
puts(prefixNameProtect(m_modp));
puts(EmitCUtil::prefixNameProtect(m_modp));
puts(nodep->isLoose() ? "__" : "::");
puts(nodep->nameProtect() + "\\n\"); );\n");
@ -358,7 +358,7 @@ public:
if (!nodep->isStatic()) { // Standard prologue
m_useSelfForThis = true;
if (!VN_IS(m_modp, Class)) {
puts(symClassAssign()); // Uses vlSelf
puts(EmitCUtil::symClassAssign()); // Uses vlSelf
} else {
puts("(void)vlSelf; // Prevent unused variable warning\n");
}
@ -606,11 +606,11 @@ public:
putns(nodep, funcp->name());
} else if (funcp->isProperMethod() && funcp->isStatic()) {
// Call static method via the containing class
putns(funcModp, prefixNameProtect(funcModp) + "::");
putns(funcModp, EmitCUtil::prefixNameProtect(funcModp) + "::");
putns(nodep, funcp->nameProtect());
} else if (nodep->superReference()) {
// Calling superclass method
putns(funcModp, prefixNameProtect(funcModp) + "::");
putns(funcModp, EmitCUtil::prefixNameProtect(funcModp) + "::");
putns(nodep, funcp->nameProtect());
} else if (funcp->isLoose()) {
// Calling loose method
@ -642,7 +642,7 @@ public:
return;
}
// assignment case;
putns(nodep, "VL_NEW(" + prefixNameProtect(nodep->dtypep()) + ", "
putns(nodep, "VL_NEW(" + EmitCUtil::prefixNameProtect(nodep->dtypep()) + ", "
+ optionalProcArg(nodep->dtypep()) + "vlSymsp");
putCommaIterateNext(nodep->argsp(), true);
puts(")");
@ -716,11 +716,11 @@ public:
puts(cvtToStr(nodep->offset() + nodep->fileline()->firstColumn()));
puts(", ");
putsQuoted((!nodep->hier().empty() ? "." : "")
+ protectWordsIf(nodep->hier(), nodep->protect()));
+ VIdProtect::protectWordsIf(nodep->hier(), nodep->protect()));
puts(", ");
putsQuoted(protectWordsIf(nodep->page(), nodep->protect()));
putsQuoted(VIdProtect::protectWordsIf(nodep->page(), nodep->protect()));
puts(", ");
putsQuoted(protectWordsIf(nodep->comment(), nodep->protect()));
putsQuoted(VIdProtect::protectWordsIf(nodep->comment(), nodep->protect()));
puts(", ");
putsQuoted(nodep->linescov());
puts(");\n");
@ -750,11 +750,11 @@ public:
puts(cvtToStr(nodep->fileline()->firstColumn()));
puts(", ");
putsQuoted((!nodep->hier().empty() ? "." : "")
+ protectWordsIf(nodep->hier(), nodep->protect()));
+ VIdProtect::protectWordsIf(nodep->hier(), nodep->protect()));
puts(", ");
putsQuoted(protectWordsIf(nodep->page(), nodep->protect()));
putsQuoted(VIdProtect::protectWordsIf(nodep->page(), nodep->protect()));
puts(", ");
putsQuoted(protectWordsIf(nodep->comment(), nodep->protect()));
putsQuoted(VIdProtect::protectWordsIf(nodep->comment(), nodep->protect()));
puts(");\n");
}
void visit(AstCoverInc* nodep) override {
@ -1254,8 +1254,8 @@ public:
VL_RESTORER(m_inUC);
m_inUC = true;
putnbs(nodep, "");
putsDecoration(nodep,
ifNoProtect("// $c statement at " + nodep->fileline()->ascii() + "\n"));
putsDecoration(nodep, VIdProtect::ifNoProtect("// $c statement at "
+ nodep->fileline()->ascii() + "\n"));
iterateAndNextConstNull(nodep->exprsp());
puts("\n");
}
@ -1264,8 +1264,8 @@ public:
m_inUC = true;
puts("\n");
putnbs(nodep, "");
putsDecoration(nodep,
ifNoProtect("// $c function at " + nodep->fileline()->ascii() + "\n"));
putsDecoration(nodep, VIdProtect::ifNoProtect("// $c function at "
+ nodep->fileline()->ascii() + "\n"));
iterateAndNextConstNull(nodep->exprsp());
puts("\n");
}
@ -1385,7 +1385,7 @@ public:
puts(")");
}
void visit(AstNewCopy* nodep) override {
putns(nodep, "VL_NEW(" + prefixNameProtect(nodep->dtypep()));
putns(nodep, "VL_NEW(" + EmitCUtil::prefixNameProtect(nodep->dtypep()));
puts(", *"); // i.e. make into a reference
iterateAndNextConstNull(nodep->rhsp());
puts(")");
@ -1467,15 +1467,15 @@ public:
void visit(AstVarRef* nodep) override {
const AstVar* const varp = nodep->varp();
const AstNodeModule* const varModp = EmitCParentModule::get(varp);
if (isConstPoolMod(varModp)) {
if (EmitCUtil::isConstPoolMod(varModp)) {
// Reference to constant pool variable
putns(nodep, topClassName() + "__ConstPool__");
putns(nodep, EmitCUtil::topClassName() + "__ConstPool__");
} else if (varp->isStatic()) {
// Access static variable via the containing class
putns(nodep, prefixNameProtect(varModp) + "::");
putns(nodep, EmitCUtil::prefixNameProtect(varModp) + "::");
} else if (VN_IS(varModp, Class) && varModp != m_modp) {
// Superclass member reference
putns(nodep, prefixNameProtect(varModp) + "::");
putns(nodep, EmitCUtil::prefixNameProtect(varModp) + "::");
} else if (varp->isIfaceRef()) {
putns(nodep, nodep->selfPointerProtect(m_useSelfForThis));
return;

View File

@ -47,8 +47,8 @@ class EmitCHeader final : public EmitCConstInit {
for (const AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (const AstCell* const cellp = VN_CAST(nodep, Cell)) {
decorateFirst(first, "// CELLS\n");
putns(cellp,
prefixNameProtect(cellp->modp()) + "* " + cellp->nameProtect() + ";\n");
putns(cellp, EmitCUtil::prefixNameProtect(cellp->modp()) + "* "
+ cellp->nameProtect() + ";\n");
}
}
}
@ -111,7 +111,7 @@ class EmitCHeader final : public EmitCConstInit {
if (const AstVar* const varp = VN_CAST(nodep, Var)) {
if (varp->isIO() || varp->isSignal() || varp->isClassMember() || varp->isTemp()
|| varp->isGenVar()) {
const bool anon = isAnonOk(varp);
const bool anon = EmitCUtil::isAnonOk(varp);
if (anon != lastAnon) emitCurrentList();
lastAnon = anon;
varList.emplace_back(varp);
@ -130,7 +130,7 @@ class EmitCHeader final : public EmitCConstInit {
}
} else { // not class
putsDecoration(nullptr, "\n// INTERNAL VARIABLES\n");
puts(symClassName() + "* const vlSymsp;\n");
puts(EmitCUtil::symClassName() + "* const vlSymsp;\n");
}
}
void emitParamDecls(const AstNodeModule* modp) {
@ -156,9 +156,10 @@ class EmitCHeader final : public EmitCConstInit {
}
void emitCtorDtorDecls(const AstNodeModule* modp) {
if (!VN_IS(modp, Class)) { // Classes use CFuncs with isConstructor/isDestructor
const string& name = prefixNameProtect(modp);
const string& name = EmitCUtil::prefixNameProtect(modp);
putsDecoration(nullptr, "\n// CONSTRUCTORS\n");
putns(modp, name + "(" + symClassName() + "* symsp, const char* v__name);\n");
putns(modp,
name + "(" + EmitCUtil::symClassName() + "* symsp, const char* v__name);\n");
putns(modp, "~" + name + "();\n");
putns(modp, "VL_UNCOPYABLE(" + name + ");\n");
}
@ -290,7 +291,7 @@ class EmitCHeader final : public EmitCConstInit {
}
void emitUnpackedUOrSBody(AstNodeUOrStructDType* sdtypep) {
putns(sdtypep, sdtypep->verilogKwd()); // "struct"/"union"
puts(" " + EmitCBase::prefixNameProtect(sdtypep) + " {\n");
puts(" " + EmitCUtil::prefixNameProtect(sdtypep) + " {\n");
for (const AstMemberDType* itemp = sdtypep->membersp(); itemp;
itemp = VN_AS(itemp->nextp(), MemberDType)) {
putns(itemp, itemp->dtypep()->cType(itemp->nameProtect(), false, false));
@ -347,7 +348,7 @@ class EmitCHeader final : public EmitCConstInit {
}
puts(");\n}\n");
}
putns(sdtypep, "\nbool operator==(const " + EmitCBase::prefixNameProtect(sdtypep)
putns(sdtypep, "\nbool operator==(const " + EmitCUtil::prefixNameProtect(sdtypep)
+ "& rhs) const {\n");
puts("return ");
for (const AstMemberDType* itemp = sdtypep->membersp(); itemp;
@ -357,10 +358,10 @@ class EmitCHeader final : public EmitCConstInit {
}
puts(";\n");
puts("}\n");
putns(sdtypep, "bool operator!=(const " + EmitCBase::prefixNameProtect(sdtypep)
putns(sdtypep, "bool operator!=(const " + EmitCUtil::prefixNameProtect(sdtypep)
+ "& rhs) const {\n");
puts("return !(*this == rhs);\n}\n");
putns(sdtypep, "\nbool operator<(const " + EmitCBase::prefixNameProtect(sdtypep)
putns(sdtypep, "\nbool operator<(const " + EmitCUtil::prefixNameProtect(sdtypep)
+ "& rhs) const {\n");
puts("return ");
puts("std::tie(");
@ -379,7 +380,7 @@ class EmitCHeader final : public EmitCConstInit {
puts("}\n");
puts("};\n");
puts("template <>\n");
putns(sdtypep, "struct VlIsCustomStruct<" + EmitCBase::prefixNameProtect(sdtypep)
putns(sdtypep, "struct VlIsCustomStruct<" + EmitCUtil::prefixNameProtect(sdtypep)
+ "> : public std::true_type {};\n");
}
@ -457,7 +458,7 @@ class EmitCHeader final : public EmitCConstInit {
}
void emitPackedUOrSBody(AstNodeUOrStructDType* sdtypep) {
putns(sdtypep, sdtypep->verilogKwd()); // "struct"/"union"
puts(" " + EmitCBase::prefixNameProtect(sdtypep) + " {\n");
puts(" " + EmitCUtil::prefixNameProtect(sdtypep) + " {\n");
AstMemberDType* itemp;
AstMemberDType* lastItemp;
@ -553,13 +554,14 @@ class EmitCHeader final : public EmitCConstInit {
if (const AstClass* const classp = VN_CAST(modp, Class)) {
for (const AstClassExtends* extp = classp->extendsp(); extp;
extp = VN_AS(extp->nextp(), ClassExtends)) {
putns(extp, "#include \"" + prefixNameProtect(extp->classp()->classOrPackagep())
putns(extp, "#include \""
+ EmitCUtil::prefixNameProtect(extp->classp()->classOrPackagep())
+ ".h\"\n");
}
}
// Forward declarations required by this AstNodeModule
puts("\nclass " + symClassName() + ";\n");
puts("\nclass " + EmitCUtil::symClassName() + ";\n");
// From `systemc_header
emitTextSection(modp, VNType::atScHdr);
@ -570,7 +572,7 @@ class EmitCHeader final : public EmitCConstInit {
puts("\n");
putns(modp, "class ");
if (!VN_IS(modp, Class)) puts("alignas(VL_CACHE_LINE_BYTES) ");
puts(prefixNameProtect(modp));
puts(EmitCUtil::prefixNameProtect(modp));
if (const AstClass* const classp = VN_CAST(modp, Class)) {
puts(" : ");
if (classp->extendsp()) {
@ -581,7 +583,7 @@ class EmitCHeader final : public EmitCConstInit {
// Use virtual only for interfaces for class inheritance
// (extends)
puts(extp->classp()->useVirtualPublic() ? "virtual public " : "public ");
putns(extp, prefixNameProtect(extp->classp()));
putns(extp, EmitCUtil::prefixNameProtect(extp->classp()));
needComma = true;
}
} else {
@ -618,10 +620,11 @@ class EmitCHeader final : public EmitCConstInit {
}
explicit EmitCHeader(const AstNodeModule* modp) {
UINFO(5, " Emitting header for " << prefixNameProtect(modp));
UINFO(5, " Emitting header for " << EmitCUtil::prefixNameProtect(modp));
// Open output file
const string filename = v3Global.opt.makeDir() + "/" + prefixNameProtect(modp) + ".h";
const string filename
= v3Global.opt.makeDir() + "/" + EmitCUtil::prefixNameProtect(modp) + ".h";
AstCFile* const cfilep = newCFile(filename, /* slow: */ false, /* source: */ false);
V3OutCFile* const ofilep
= v3Global.opt.systemC() ? new V3OutScFile{filename} : new V3OutCFile{filename};
@ -630,7 +633,7 @@ class EmitCHeader final : public EmitCConstInit {
ofp()->putsHeader();
puts("// DESCRIPTION: Verilator output: Design internal header\n");
puts("// See " + topClassName() + ".h for the primary calling header\n");
puts("// See " + EmitCUtil::topClassName() + ".h for the primary calling header\n");
ofp()->putsGuard();

View File

@ -35,23 +35,23 @@ class EmitCGatherDependencies final : VNVisitorConst {
std::set<string> m_dependencies; // Header names to be included in output C++ file
// METHODS
void addSymsDependency() { m_dependencies.insert(EmitCBase::symClassName()); }
void addSymsDependency() { m_dependencies.insert(EmitCUtil::symClassName()); }
void addModDependency(const AstNodeModule* modp) {
if (const AstClass* const classp = VN_CAST(modp, Class)) {
m_dependencies.insert(EmitCBase::prefixNameProtect(classp->classOrPackagep()));
m_dependencies.insert(EmitCUtil::prefixNameProtect(classp->classOrPackagep()));
} else {
m_dependencies.insert(EmitCBase::prefixNameProtect(modp));
m_dependencies.insert(EmitCUtil::prefixNameProtect(modp));
}
}
void addDTypeDependency(const AstNodeDType* nodep) {
if (const AstClassRefDType* const dtypep = VN_CAST(nodep, ClassRefDType)) {
m_dependencies.insert(
EmitCBase::prefixNameProtect(dtypep->classp()->classOrPackagep()));
EmitCUtil::prefixNameProtect(dtypep->classp()->classOrPackagep()));
} else if (const AstNodeUOrStructDType* const dtypep
= VN_CAST(nodep, NodeUOrStructDType)) {
if (!dtypep->packed()) {
UASSERT_OBJ(dtypep->classOrPackagep(), nodep, "Unlinked struct package");
m_dependencies.insert(EmitCBase::prefixNameProtect(dtypep->classOrPackagep()));
m_dependencies.insert(EmitCUtil::prefixNameProtect(dtypep->classOrPackagep()));
}
}
}
@ -177,7 +177,8 @@ class EmitCImp final : EmitCFunc {
V3OutCFile* const ofilep = new V3OutCFile{filename};
setOutputFile(ofilep, filep);
} else {
string filename = v3Global.opt.makeDir() + "/" + prefixNameProtect(m_fileModp);
string filename
= v3Global.opt.makeDir() + "/" + EmitCUtil::prefixNameProtect(m_fileModp);
if (!subFileName.empty()) {
filename += "__" + subFileName;
filename = m_uniqueNames.get(filename);
@ -193,10 +194,10 @@ class EmitCImp final : EmitCFunc {
putsHeader();
puts("// DESCRIPTION: Verilator output: Design implementation internals\n");
puts("// See " + topClassName() + ".h for the primary calling header\n");
puts("// See " + EmitCUtil::topClassName() + ".h for the primary calling header\n");
puts("\n");
puts("#include \"" + pchClassName() + ".h\"\n");
puts("#include \"" + EmitCUtil::pchClassName() + ".h\"\n");
for (const string& name : headers) puts("#include \"" + name + ".h\"\n");
emitTextSection(m_modp, VNType::atScImpHdr);
@ -204,7 +205,7 @@ class EmitCImp final : EmitCFunc {
void emitStaticVarDefns(const AstNodeModule* modp) {
// Emit static variable definitions
const string modName = prefixNameProtect(modp);
const string modName = EmitCUtil::prefixNameProtect(modp);
for (const AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (const AstVar* const varp = VN_CAST(nodep, Var)) {
if (varp->isStatic()) {
@ -215,7 +216,7 @@ class EmitCImp final : EmitCFunc {
}
}
void emitParamDefns(const AstNodeModule* modp) {
const string modName = prefixNameProtect(modp);
const string modName = EmitCUtil::prefixNameProtect(modp);
bool first = true;
for (const AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (const AstVar* const varp = VN_CAST(nodep, Var)) {
@ -242,15 +243,15 @@ class EmitCImp final : EmitCFunc {
if (!first) puts("\n");
}
void emitCtorImp(const AstNodeModule* modp) {
const string modName = prefixNameProtect(modp);
const string modName = EmitCUtil::prefixNameProtect(modp);
puts("\n");
m_lazyDecls.emit("void " + modName + "__", protect("_ctor_var_reset"),
"(" + modName + "* vlSelf);");
puts("\n");
putns(modp,
modName + "::" + modName + "(" + symClassName() + "* symsp, const char* v__name)\n");
putns(modp, modName + "::" + modName + "(" + EmitCUtil::symClassName()
+ "* symsp, const char* v__name)\n");
puts(" : VerilatedModule{v__name}\n");
ofp()->indentInc();
@ -290,7 +291,7 @@ class EmitCImp final : EmitCFunc {
puts("}\n");
}
void emitConfigureImp(const AstNodeModule* modp) {
const string modName = prefixNameProtect(modp);
const string modName = EmitCUtil::prefixNameProtect(modp);
if (v3Global.opt.coverage()) {
puts("\n");
@ -312,7 +313,7 @@ class EmitCImp final : EmitCFunc {
// arguments.
if (v3Global.opt.coverage()) {
puts("\n// Coverage\n");
puts("void " + prefixNameProtect(m_modp) + "::__vlCoverInsert(");
puts("void " + EmitCUtil::prefixNameProtect(m_modp) + "::__vlCoverInsert(");
puts(v3Global.opt.threads() > 1 ? "std::atomic<uint32_t>" : "uint32_t");
puts("* countp, bool enable, const char* filenamep, int lineno, int column,\n");
puts("const char* hierp, const char* pagep, const char* commentp, const char* "
@ -344,7 +345,7 @@ class EmitCImp final : EmitCFunc {
}
if (v3Global.opt.coverageToggle()) {
puts("\n// Toggle Coverage\n");
puts("void " + prefixNameProtect(m_modp) + "::__vlCoverToggleInsert(");
puts("void " + EmitCUtil::prefixNameProtect(m_modp) + "::__vlCoverToggleInsert(");
puts("int begin, int end, bool ranged, ");
puts(v3Global.opt.threads() > 1 ? "std::atomic<uint32_t>" : "uint32_t");
puts("* countp, bool enable, const char* filenamep, int lineno, int column,\n");
@ -390,7 +391,8 @@ class EmitCImp final : EmitCFunc {
}
void emitDestructorImp(const AstNodeModule* modp) {
puts("\n");
putns(modp, prefixNameProtect(modp) + "::~" + prefixNameProtect(modp) + "() {\n");
putns(modp, EmitCUtil::prefixNameProtect(modp) + "::~" + EmitCUtil::prefixNameProtect(modp)
+ "() {\n");
emitTextSection(modp, VNType::atScDtor);
puts("}\n");
splitSizeInc(10);
@ -403,8 +405,8 @@ class EmitCImp final : EmitCFunc {
const string funcname = de ? "__Vdeserialize" : "__Vserialize";
const string op = de ? ">>" : "<<";
// NOLINTNEXTLINE(performance-inefficient-string-concatenation)
putns(modp, "void " + prefixNameProtect(modp) + "::" + protect(funcname) + "("
+ classname + "& os) {\n");
putns(modp, "void " + EmitCUtil::prefixNameProtect(modp) + "::" + protect(funcname)
+ "(" + classname + "& os) {\n");
// Place a computed checksum to ensure proper structure save/restore formatting
// OK if this hash includes some things we won't dump, since
// just looking for loading the wrong model
@ -514,8 +516,8 @@ class EmitCImp final : EmitCFunc {
if (hasCommonImp(modp) || hasCommonImp(classp)) {
std::set<string> headers;
headers.insert(prefixNameProtect(m_fileModp));
headers.insert(symClassName());
headers.insert(EmitCUtil::prefixNameProtect(m_fileModp));
headers.insert(EmitCUtil::symClassName());
openNextOutputFile(headers, "");
@ -595,7 +597,7 @@ class EmitCImp final : EmitCFunc {
: m_fileModp{modp}
, m_slow{slow}
, m_cfilesr{cfilesr} {
UINFO(5, " Emitting implementation of " << prefixNameProtect(modp));
UINFO(5, " Emitting implementation of " << EmitCUtil::prefixNameProtect(modp));
m_modp = modp;
@ -644,7 +646,7 @@ class EmitCTrace final : EmitCFunc {
m_lazyDecls.reset(); // Need to emit new lazy declarations
string filename
= (v3Global.opt.makeDir() + "/" + topClassName() + "_" + protect("_Trace"));
= (v3Global.opt.makeDir() + "/" + EmitCUtil::topClassName() + "_" + protect("_Trace"));
filename = m_uniqueNames.get(filename);
if (m_slow) filename += "__Slow";
filename += ".cpp";
@ -663,7 +665,7 @@ class EmitCTrace final : EmitCFunc {
// Includes
puts("#include \"" + v3Global.opt.traceSourceLang() + ".h\"\n");
puts("#include \"" + symClassName() + ".h\"\n");
puts("#include \"" + EmitCUtil::symClassName() + ".h\"\n");
puts("\n");
}
@ -672,8 +674,8 @@ class EmitCTrace final : EmitCFunc {
void openNextTypesFile() {
UASSERT(!m_typesFp, "Declarations output file already open");
string filename
= (v3Global.opt.makeDir() + "/" + topClassName() + "_" + protect("_TraceDecls"));
string filename = (v3Global.opt.makeDir() + "/" + EmitCUtil::topClassName() + "_"
+ protect("_TraceDecls"));
filename = m_uniqueNames.get(filename);
filename += "__Slow.cpp";
@ -694,7 +696,7 @@ class EmitCTrace final : EmitCFunc {
typesFp()->puts("#include \"" + v3Global.opt.traceSourceLang() + ".h\"\n");
typesFp()->puts("\n");
typesFp()->puts("\nvoid " + prefixNameProtect(m_modp) + "__"
typesFp()->puts("\nvoid " + EmitCUtil::prefixNameProtect(m_modp) + "__"
+ protect("traceDeclTypesSub" + cvtToStr(m_traceTypeSubs++)) + "("
+ v3Global.opt.traceClassBase() + "* tracep) {\n");
}
@ -709,15 +711,16 @@ class EmitCTrace final : EmitCFunc {
// Forward declarations for subs in other files
for (int i = 0; i < m_traceTypeSubs - 1; ++i) {
typesFp()->puts("void " + prefixNameProtect(m_modp) + "__"
typesFp()->puts("void " + EmitCUtil::prefixNameProtect(m_modp) + "__"
+ protect("traceDeclTypesSub" + cvtToStr(i)) + "("
+ v3Global.opt.traceClassBase() + "* tracep);\n");
}
typesFp()->puts("\nvoid " + prefixNameProtect(m_modp) + "__" + protect("trace_decl_types")
+ "(" + v3Global.opt.traceClassBase() + "* tracep) {\n");
typesFp()->puts("\nvoid " + EmitCUtil::prefixNameProtect(m_modp) + "__"
+ protect("trace_decl_types") + "(" + v3Global.opt.traceClassBase()
+ "* tracep) {\n");
for (int i = 0; i < m_traceTypeSubs; ++i) {
typesFp()->puts(prefixNameProtect(m_modp) + "__"
typesFp()->puts(EmitCUtil::prefixNameProtect(m_modp) + "__"
+ protect("traceDeclTypesSub" + cvtToStr(i)) + "(tracep);\n");
}
}

View File

@ -41,7 +41,8 @@ public:
private:
// MAIN METHOD
void emitInt() {
const string filename = v3Global.opt.makeDir() + "/" + topClassName() + "__main.cpp";
const string filename
= v3Global.opt.makeDir() + "/" + EmitCUtil::topClassName() + "__main.cpp";
AstCFile* const cfilep = newCFile(filename, false /*slow*/, true /*source*/);
V3OutCFile cf{filename};
setOutputFile(&cf, cfilep);
@ -59,7 +60,7 @@ private:
puts("\n");
puts("#include \"verilated.h\"\n");
puts("#include \"" + topClassName() + ".h\"\n");
puts("#include \"" + EmitCUtil::topClassName() + ".h\"\n");
puts("\n//======================\n\n");
@ -72,8 +73,8 @@ private:
puts("\n");
puts("// Construct the Verilated model, from Vtop.h generated from Verilating\n");
puts("const std::unique_ptr<" + topClassName() + "> topp{new " + topClassName()
+ "{contextp.get(), \"" + topName + "\"}};\n");
puts("const std::unique_ptr<" + EmitCUtil::topClassName() + "> topp{new "
+ EmitCUtil::topClassName() + "{contextp.get(), \"" + topName + "\"}};\n");
puts("\n");
puts("// Simulate until $finish\n");

View File

@ -55,7 +55,7 @@ class EmitCModel final : public EmitCFunc {
void emitHeader(AstNodeModule* modp) {
UASSERT(!ofp(), "Output file should not be open");
const string filename = v3Global.opt.makeDir() + "/" + topClassName() + ".h";
const string filename = v3Global.opt.makeDir() + "/" + EmitCUtil::topClassName() + ".h";
setOutputFile(v3Global.opt.systemC() ? new V3OutScFile{filename}
: new V3OutCFile{filename},
newCFile(filename, /* slow: */ false, /* source: */ false));
@ -80,15 +80,16 @@ class EmitCModel final : public EmitCFunc {
// Declare foreign instances up front to make C++ happy
puts("\n");
puts("class " + symClassName() + ";\n");
puts("class " + prefixNameProtect(modp) + ";\n"); // For rootp pointer only
puts("class " + EmitCUtil::symClassName() + ";\n");
puts("class " + EmitCUtil::prefixNameProtect(modp) + ";\n"); // For rootp pointer only
if (v3Global.opt.trace()) puts("class " + v3Global.opt.traceClassLang() + ";\n");
emitModCUse(modp, VUseType::INT_FWD_CLASS); // Note: This is needed for cell forwarding
puts("\n");
puts("// This class is the main interface to the Verilated model\n");
putns(modp, "class alignas(VL_CACHE_LINE_BYTES) " + topClassName() + " VL_NOT_FINAL : ");
putns(modp, "class alignas(VL_CACHE_LINE_BYTES) " + EmitCUtil::topClassName()
+ " VL_NOT_FINAL : ");
if (optSystemC()) {
// SC_MODULE, but with multiple-inheritance of VerilatedModel
puts("public ::sc_core::sc_module, ");
@ -98,7 +99,7 @@ class EmitCModel final : public EmitCFunc {
ofp()->putsPrivate(true); // private:
puts("// Symbol table holding complete model state (owned by this class)\n");
puts(symClassName() + "* const vlSymsp;\n");
puts(EmitCUtil::symClassName() + "* const vlSymsp;\n");
puts("\n");
ofp()->putsPrivate(false); // public:
@ -138,36 +139,36 @@ class EmitCModel final : public EmitCFunc {
"// Otherwise the application code can consider these internals.\n");
for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (const AstCell* const cellp = VN_CAST(nodep, Cell)) {
putns(cellp, prefixNameProtect(cellp->modp()) + "* const " + cellp->nameProtect()
+ ";\n");
putns(cellp, EmitCUtil::prefixNameProtect(cellp->modp()) + "* const "
+ cellp->nameProtect() + ";\n");
}
}
// root instance pointer (for access to internals, including public_flat items).
puts("\n// Root instance pointer to allow access to model internals,\n"
"// including inlined /* verilator public_flat_* */ items.\n");
puts(prefixNameProtect(modp) + "* const rootp;\n");
puts(EmitCUtil::prefixNameProtect(modp) + "* const rootp;\n");
puts("\n");
ofp()->putsPrivate(false); // public:
puts("// CONSTRUCTORS\n");
if (optSystemC()) {
puts("SC_CTOR(" + topClassName() + ");\n");
puts("virtual ~" + topClassName() + "();\n");
puts("SC_CTOR(" + EmitCUtil::topClassName() + ");\n");
puts("virtual ~" + EmitCUtil::topClassName() + "();\n");
} else {
puts("/// Construct the model; called by application code\n");
puts("/// If contextp is null, then the model will use the default global "
"context\n");
puts("/// If name is \"\", then makes a wrapper with a\n");
puts("/// single model invisible with respect to DPI scope names.\n");
puts("explicit " + topClassName() + "(VerilatedContext* contextp,"
puts("explicit " + EmitCUtil::topClassName() + "(VerilatedContext* contextp,"
+ " const char* name = \"TOP\");\n");
puts("explicit " + topClassName() + "(const char* name = \"TOP\");\n");
puts("explicit " + EmitCUtil::topClassName() + "(const char* name = \"TOP\");\n");
puts("/// Destroy the model; called (often implicitly) by application code\n");
puts("virtual ~" + topClassName() + "();\n");
puts("virtual ~" + EmitCUtil::topClassName() + "();\n");
}
ofp()->putsPrivate(true);
puts("VL_UNCOPYABLE(" + topClassName() + "); ///< Copying not allowed\n");
puts("VL_UNCOPYABLE(" + EmitCUtil::topClassName() + "); ///< Copying not allowed\n");
puts("\n");
ofp()->putsPrivate(false); // public:
@ -243,9 +244,9 @@ class EmitCModel final : public EmitCFunc {
puts("\n");
puts("// Serialization functions\n");
puts("friend VerilatedSerialize& operator<<(VerilatedSerialize& os, " //
+ topClassName() + "& rhs);\n");
+ EmitCUtil::topClassName() + "& rhs);\n");
puts("friend VerilatedDeserialize& operator>>(VerilatedDeserialize& os, "
+ topClassName() + "& rhs);\n");
+ EmitCUtil::topClassName() + "& rhs);\n");
}
puts("\n// Abstract methods from VerilatedModel\n");
@ -277,15 +278,17 @@ class EmitCModel final : public EmitCFunc {
putSectionDelimiter("Constructors");
puts("\n");
putns(modp, topClassName() + "::" + topClassName());
putns(modp, EmitCUtil::topClassName() + "::" + EmitCUtil::topClassName());
if (optSystemC()) {
puts("(sc_core::sc_module_name /* unused */)\n");
puts(" : VerilatedModel{*Verilated::threadContextp()}\n");
puts(" , vlSymsp{new " + symClassName() + "(contextp(), name(), this)}\n");
puts(" , vlSymsp{new " + EmitCUtil::symClassName()
+ "(contextp(), name(), this)}\n");
} else {
puts(+"(VerilatedContext* _vcontextp__, const char* _vcname__)\n");
puts(" : VerilatedModel{*_vcontextp__}\n");
puts(" , vlSymsp{new " + symClassName() + "(contextp(), _vcname__, this)}\n");
puts(" , vlSymsp{new " + EmitCUtil::symClassName()
+ "(contextp(), _vcname__, this)}\n");
}
// Set up IO references
@ -356,8 +359,10 @@ class EmitCModel final : public EmitCFunc {
if (!optSystemC()) {
puts("\n");
puts(topClassName() + "::" + topClassName() + "(const char* _vcname__)\n");
puts(" : " + topClassName() + "(Verilated::threadContextp(), _vcname__)\n{\n}\n");
puts(EmitCUtil::topClassName() + "::" + EmitCUtil::topClassName()
+ "(const char* _vcname__)\n");
puts(" : " + EmitCUtil::topClassName()
+ "(Verilated::threadContextp(), _vcname__)\n{\n}\n");
}
}
@ -365,7 +370,7 @@ class EmitCModel final : public EmitCFunc {
putSectionDelimiter("Destructor");
puts("\n");
puts(topClassName() + "::~" + topClassName() + "() {\n");
puts(EmitCUtil::topClassName() + "::~" + EmitCUtil::topClassName() + "() {\n");
puts("delete vlSymsp;\n");
puts("}\n");
}
@ -373,7 +378,7 @@ class EmitCModel final : public EmitCFunc {
void emitStandardMethods1(AstNodeModule* modp) {
UASSERT_OBJ(modp->isTop(), modp, "Attempting to emitWrapEval for non-top class");
const string topModNameProtected = prefixNameProtect(modp);
const string topModNameProtected = EmitCUtil::prefixNameProtect(modp);
const string selfDecl = "(" + topModNameProtected + "* vlSelf)";
putSectionDelimiter("Evaluation function");
@ -391,7 +396,7 @@ class EmitCModel final : public EmitCFunc {
if (optSystemC() && v3Global.usesTiming()) {
// ::eval
puts("\nvoid " + topClassName() + "::eval() {\n");
puts("\nvoid " + EmitCUtil::topClassName() + "::eval() {\n");
puts("eval_step();\n");
puts("if (eventsPending()) {\n");
puts("sc_core::sc_time dt = sc_core::sc_time::from_value(nextTimeSlot() - "
@ -403,14 +408,14 @@ class EmitCModel final : public EmitCFunc {
puts("}\n");
// ::eval_sens
puts("\nvoid " + topClassName() + "::eval_sens() {\n");
puts("\nvoid " + EmitCUtil::topClassName() + "::eval_sens() {\n");
puts("trigger_eval.notify();\n");
puts("}\n");
}
// ::eval_step
puts("\nvoid " + topClassName() + "::eval_step() {\n");
puts("VL_DEBUG_IF(VL_DBG_MSGF(\"+++++TOP Evaluate " + topClassName()
puts("\nvoid " + EmitCUtil::topClassName() + "::eval_step() {\n");
puts("VL_DEBUG_IF(VL_DBG_MSGF(\"+++++TOP Evaluate " + EmitCUtil::topClassName()
+ "::eval_step\\n\"); );\n");
puts("#ifdef VL_DEBUG\n");
@ -445,14 +450,14 @@ class EmitCModel final : public EmitCFunc {
}
void emitStandardMethods2(AstNodeModule* modp) {
const string topModNameProtected = prefixNameProtect(modp);
const string topModNameProtected = EmitCUtil::prefixNameProtect(modp);
const string selfDecl = "(" + topModNameProtected + "* vlSelf)";
// ::eval_end_step
if (v3Global.needTraceDumper() && !optSystemC()) {
puts("\n");
putns(modp, "void " + topClassName() + "::eval_end_step() {\n");
puts("VL_DEBUG_IF(VL_DBG_MSGF(\"+eval_end_step " + topClassName()
putns(modp, "void " + EmitCUtil::topClassName() + "::eval_end_step() {\n");
puts("VL_DEBUG_IF(VL_DBG_MSGF(\"+eval_end_step " + EmitCUtil::topClassName()
+ "::eval_end_step\\n\"); );\n");
puts("#ifdef VM_TRACE\n");
putsDecoration(nullptr, "// Tracing\n");
@ -464,16 +469,19 @@ class EmitCModel final : public EmitCFunc {
putSectionDelimiter("Events and timing");
if (auto* const delaySchedp = v3Global.rootp()->delaySchedulerp()) {
putns(modp, "bool " + topClassName() + "::eventsPending() { return !vlSymsp->TOP.");
putns(modp, "bool " + EmitCUtil::topClassName()
+ "::eventsPending() { return !vlSymsp->TOP.");
puts(delaySchedp->nameProtect());
puts(".empty(); }\n\n");
putns(modp, "uint64_t " + topClassName() + "::nextTimeSlot() { return vlSymsp->TOP.");
putns(modp, "uint64_t " + EmitCUtil::topClassName()
+ "::nextTimeSlot() { return vlSymsp->TOP.");
puts(delaySchedp->nameProtect());
puts(".nextTimeSlot(); }\n");
} else {
putns(modp, "bool " + topClassName() + "::eventsPending() { return false; }\n\n");
puts("uint64_t " + topClassName() + "::nextTimeSlot() {\n");
putns(modp,
"bool " + EmitCUtil::topClassName() + "::eventsPending() { return false; }\n\n");
puts("uint64_t " + EmitCUtil::topClassName() + "::nextTimeSlot() {\n");
puts("VL_FATAL_MT(__FILE__, __LINE__, \"\", \"No delays in the design\");\n");
puts("return 0;\n}\n");
}
@ -483,7 +491,7 @@ class EmitCModel final : public EmitCFunc {
if (!optSystemC()) {
// ::name
puts("\n");
putns(modp, "const char* " + topClassName() + "::name() const {\n");
putns(modp, "const char* " + EmitCUtil::topClassName() + "::name() const {\n");
puts(/**/ "return vlSymsp->name();\n");
puts("}\n");
}
@ -494,23 +502,23 @@ class EmitCModel final : public EmitCFunc {
putns(modp,
"void " + topModNameProtected + "__" + protect("_eval_final") + selfDecl + ";\n");
// ::final
puts("\nVL_ATTR_COLD void " + topClassName() + "::final() {\n");
puts("\nVL_ATTR_COLD void " + EmitCUtil::topClassName() + "::final() {\n");
puts(/**/ topModNameProtected + "__" + protect("_eval_final") + "(&(vlSymsp->TOP));\n");
puts("}\n");
putSectionDelimiter("Implementations of abstract methods from VerilatedModel\n");
putns(modp, "const char* " + topClassName()
putns(modp, "const char* " + EmitCUtil::topClassName()
+ "::hierName() const { return vlSymsp->name(); }\n");
putns(modp, "const char* " + topClassName() + "::modelName() const { return \""
+ topClassName() + "\"; }\n");
putns(modp, "const char* " + EmitCUtil::topClassName() + "::modelName() const { return \""
+ EmitCUtil::topClassName() + "\"; }\n");
const int threads = v3Global.opt.hierChild()
? v3Global.opt.threads()
: std::max(v3Global.opt.threads(), v3Global.opt.hierThreads());
putns(modp, "unsigned " + topClassName() + "::threads() const { return "
putns(modp, "unsigned " + EmitCUtil::topClassName() + "::threads() const { return "
+ cvtToStr(threads) + "; }\n");
putns(modp, "void " + topClassName()
putns(modp, "void " + EmitCUtil::topClassName()
+ "::prepareClone() const { contextp()->prepareClone(); }\n");
putns(modp, "void " + topClassName() + "::atClone() const {\n");
putns(modp, "void " + EmitCUtil::topClassName() + "::atClone() const {\n");
if (v3Global.opt.threads() > 1) {
puts("vlSymsp->__Vm_threadPoolp = static_cast<VlThreadPool*>(");
}
@ -519,7 +527,7 @@ class EmitCModel final : public EmitCFunc {
puts(";\n}\n");
if (v3Global.opt.trace()) {
putns(modp, "std::unique_ptr<VerilatedTraceConfig> " + topClassName()
putns(modp, "std::unique_ptr<VerilatedTraceConfig> " + EmitCUtil::topClassName()
+ "::traceConfig() const {\n");
puts("return std::unique_ptr<VerilatedTraceConfig>{new VerilatedTraceConfig{");
puts(v3Global.opt.useTraceParallel() ? "true" : "false");
@ -531,7 +539,7 @@ class EmitCModel final : public EmitCFunc {
}
void emitTraceMethods(AstNodeModule* modp) {
const string topModNameProtected = prefixNameProtect(modp);
const string topModNameProtected = EmitCUtil::prefixNameProtect(modp);
putSectionDelimiter("Trace configuration");
@ -547,8 +555,8 @@ class EmitCModel final : public EmitCFunc {
putns(modp, "VL_ATTR_COLD static void " + protect("trace_init") + "(void* voidSelf, "
+ v3Global.opt.traceClassBase() + "* tracep, uint32_t code) {\n");
putsDecoration(modp, "// Callback from tracep->open()\n");
puts(voidSelfAssign(modp));
puts(symClassAssign());
puts(EmitCUtil::voidSelfAssign(modp));
puts(EmitCUtil::symClassAssign());
puts("if (!vlSymsp->_vm_contextp__->calcUnusedSigs()) {\n");
puts("VL_FATAL_MT(__FILE__, __LINE__, __FILE__,\n");
puts("\"Turning on wave traces requires Verilated::traceEverOn(true) call before time "
@ -570,11 +578,11 @@ class EmitCModel final : public EmitCFunc {
// ::traceRegisterModel
puts("\n");
putns(modp, "VL_ATTR_COLD void " + topClassName() + "::traceBaseModel(");
putns(modp, "VL_ATTR_COLD void " + EmitCUtil::topClassName() + "::traceBaseModel(");
puts("VerilatedTraceBaseC* tfp, int levels, int options) {\n");
if (optSystemC()) {
puts(/**/ "if (!sc_core::sc_get_curr_simcontext()->elaboration_done()) {\n");
puts(/****/ "vl_fatal(__FILE__, __LINE__, name(), \"" + topClassName()
puts(/****/ "vl_fatal(__FILE__, __LINE__, name(), \"" + EmitCUtil::topClassName()
+ +"::trace() is called before sc_core::sc_start(). "
"Run sc_core::sc_start(sc_core::SC_ZERO_TIME) before trace() to complete "
"elaboration.\");\n");
@ -584,7 +592,7 @@ class EmitCModel final : public EmitCFunc {
puts(/**/ v3Global.opt.traceClassBase() + "C* const stfp = dynamic_cast<"
+ v3Global.opt.traceClassBase() + "C*>(tfp);\n");
puts(/**/ "if (VL_UNLIKELY(!stfp)) {\n");
puts(/****/ "vl_fatal(__FILE__, __LINE__, __FILE__,\"'" + topClassName()
puts(/****/ "vl_fatal(__FILE__, __LINE__, __FILE__,\"'" + EmitCUtil::topClassName()
+ "::trace()' called on non-" + v3Global.opt.traceClassBase() + "C object;\"\n"
+ "\" use --trace-fst with VerilatedFst object,"
+ " and --trace-vcd with VerilatedVcd object\");\n");
@ -600,15 +608,15 @@ class EmitCModel final : public EmitCFunc {
void emitSerializationFunctions() {
putSectionDelimiter("Model serialization");
puts("\nVerilatedSerialize& operator<<(VerilatedSerialize& os, " + topClassName()
+ "& rhs) {\n");
puts("\nVerilatedSerialize& operator<<(VerilatedSerialize& os, "
+ EmitCUtil::topClassName() + "& rhs) {\n");
puts(/**/ "Verilated::quiesce();\n");
puts(/**/ "rhs.vlSymsp->" + protect("__Vserialize") + "(os);\n");
puts(/**/ "return os;\n");
puts("}\n");
puts("\nVerilatedDeserialize& operator>>(VerilatedDeserialize& os, " + topClassName()
+ "& rhs) {\n");
puts("\nVerilatedDeserialize& operator>>(VerilatedDeserialize& os, "
+ EmitCUtil::topClassName() + "& rhs) {\n");
puts(/**/ "Verilated::quiesce();\n");
puts(/**/ "rhs.vlSymsp->" + protect("__Vdeserialize") + "(os);\n");
puts(/**/ "return os;\n");
@ -618,7 +626,7 @@ class EmitCModel final : public EmitCFunc {
void emitImplementation(AstNodeModule* modp) {
UASSERT(!ofp(), "Output file should not be open");
const string filename = v3Global.opt.makeDir() + "/" + topClassName() + ".cpp";
const string filename = v3Global.opt.makeDir() + "/" + EmitCUtil::topClassName() + ".cpp";
setOutputFile(v3Global.opt.systemC() ? new V3OutScFile{filename}
: new V3OutCFile{filename},
newCFile(filename, /* slow: */ false, /* source: */ true));
@ -628,7 +636,7 @@ class EmitCModel final : public EmitCFunc {
"Model implementation (design independent parts)\n");
puts("\n");
puts("#include \"" + pchClassName() + ".h\"\n");
puts("#include \"" + EmitCUtil::pchClassName() + ".h\"\n");
if (v3Global.opt.trace()) {
puts("#include \"" + v3Global.opt.traceSourceLang() + ".h\"\n");
}
@ -659,7 +667,8 @@ class EmitCModel final : public EmitCFunc {
}
if (!ofp()) {
string filename = v3Global.opt.makeDir() + "/" + topClassName() + "__Dpi_Export";
string filename
= v3Global.opt.makeDir() + "/" + EmitCUtil::topClassName() + "__Dpi_Export";
filename = m_uniqueNames.get(filename);
filename += ".cpp";
setOutputFile(v3Global.opt.systemC() ? new V3OutScFile{filename}
@ -671,8 +680,8 @@ class EmitCModel final : public EmitCFunc {
puts(
"// DESCRIPTION: Verilator output: Implementation of DPI export functions.\n");
puts("//\n");
puts("#include \"" + topClassName() + ".h\"\n");
puts("#include \"" + symClassName() + ".h\"\n");
puts("#include \"" + EmitCUtil::topClassName() + ".h\"\n");
puts("#include \"" + EmitCUtil::symClassName() + ".h\"\n");
puts("#include \"verilated_dpi.h\"\n");
puts("\n");
}

View File

@ -23,19 +23,19 @@ VL_DEFINE_DEBUG_FUNCTIONS;
//######################################################################
// Precompiled header emitter
class EmitCPch final : EmitCBase {
class EmitCPch final {
public:
// METHODS
void emitPch() {
// Generate the makefile
V3OutCFile of{v3Global.opt.makeDir() + "/" + pchClassName() + ".h"};
V3OutCFile of{v3Global.opt.makeDir() + "/" + EmitCUtil::pchClassName() + ".h"};
of.putsHeader();
of.puts("// DESCRIPTION: Verilator output: Precompiled header\n");
of.puts("//\n");
of.puts("// Internal details; most user sources do not need this header,\n");
of.puts("// unless using verilator public meta comments.\n");
of.puts("// Suggest use " + topClassName() + ".h instead.\n");
of.puts("// Suggest use " + EmitCUtil::topClassName() + ".h instead.\n");
of.puts("\n");
of.putsGuard();
@ -54,8 +54,8 @@ public:
if (v3Global.dpi()) of.puts("#include \"verilated_dpi.h\"\n");
of.puts("\n");
of.puts("#include \"" + symClassName() + ".h\"\n");
of.puts("#include \"" + topClassName() + ".h\"\n");
of.puts("#include \"" + EmitCUtil::symClassName() + ".h\"\n");
of.puts("#include \"" + EmitCUtil::topClassName() + ".h\"\n");
of.puts("\n// Additional include files added using '--compiler-include'\n");
for (const string& filename : v3Global.opt.compilerIncludes()) {

View File

@ -399,7 +399,7 @@ public:
void EmitCSyms::emitSymHdr() {
UINFO(6, __FUNCTION__ << ": ");
const string filename = v3Global.opt.makeDir() + "/" + symClassName() + ".h";
const string filename = v3Global.opt.makeDir() + "/" + EmitCUtil::symClassName() + ".h";
AstCFile* const cfilep = newCFile(filename, true /*slow*/, false /*source*/);
V3OutCFile* const ofilep = optSystemC() ? new V3OutScFile{filename} : new V3OutCFile{filename};
setOutputFile(ofilep, cfilep);
@ -421,13 +421,13 @@ void EmitCSyms::emitSymHdr() {
if (v3Global.opt.usesProfiler()) puts("#include \"verilated_profiler.h\"\n");
puts("\n// INCLUDE MODEL CLASS\n");
puts("\n#include \"" + topClassName() + ".h\"\n");
puts("\n#include \"" + EmitCUtil::topClassName() + ".h\"\n");
puts("\n// INCLUDE MODULE CLASSES\n");
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep;
nodep = VN_AS(nodep->nextp(), NodeModule)) {
if (VN_IS(nodep, Class)) continue; // Class included earlier
putns(nodep, "#include \"" + prefixNameProtect(nodep) + ".h\"\n");
putns(nodep, "#include \"" + EmitCUtil::prefixNameProtect(nodep) + ".h\"\n");
}
if (v3Global.dpi()) {
@ -446,12 +446,12 @@ void EmitCSyms::emitSymHdr() {
}
puts("\n// SYMS CLASS (contains all model state)\n");
puts("class alignas(VL_CACHE_LINE_BYTES)" + symClassName()
puts("class alignas(VL_CACHE_LINE_BYTES)" + EmitCUtil::symClassName()
+ " final : public VerilatedSyms {\n");
ofp()->putsPrivate(false); // public:
puts("// INTERNAL STATE\n");
puts(topClassName() + "* const __Vm_modelp;\n");
puts(EmitCUtil::topClassName() + "* const __Vm_modelp;\n");
if (v3Global.needTraceDumper()) {
// __Vm_dumperp is local, otherwise we wouldn't know what design's eval()
@ -496,9 +496,9 @@ void EmitCSyms::emitSymHdr() {
const AstScope* const scopep = i.first;
const AstNodeModule* const modp = i.second;
if (VN_IS(modp, Class)) continue;
const string name = prefixNameProtect(modp);
const string name = EmitCUtil::prefixNameProtect(modp);
ofp()->printf("%-30s ", name.c_str());
putns(scopep, protectIf(scopep->nameDotless(), scopep->protect()) + ";\n");
putns(scopep, VIdProtect::protectIf(scopep->nameDotless(), scopep->protect()) + ";\n");
}
if (m_coverBins) {
@ -528,12 +528,12 @@ void EmitCSyms::emitSymHdr() {
}
puts("\n// CONSTRUCTORS\n");
puts(symClassName() + "(VerilatedContext* contextp, const char* namep, " + topClassName()
+ "* modelp);\n");
puts("~"s + symClassName() + "();\n");
puts(EmitCUtil::symClassName() + "(VerilatedContext* contextp, const char* namep, "
+ EmitCUtil::topClassName() + "* modelp);\n");
puts("~"s + EmitCUtil::symClassName() + "();\n");
for (const auto& i : m_usesVfinal) {
puts("void " + symClassName() + "_" + cvtToStr(i.first) + "(");
puts("void " + EmitCUtil::symClassName() + "_" + cvtToStr(i.first) + "(");
if (i.second) puts("int __Vfinal");
puts(");\n");
}
@ -599,8 +599,8 @@ void EmitCSyms::checkSplit(bool usesVfinal) {
v3Global.useParallelBuild(true);
m_numStmts = 0;
const string filename
= v3Global.opt.makeDir() + "/" + symClassName() + "__" + cvtToStr(++m_funcNum) + ".cpp";
const string filename = v3Global.opt.makeDir() + "/" + EmitCUtil::symClassName() + "__"
+ cvtToStr(++m_funcNum) + ".cpp";
AstCFile* const cfilep = newCFile(filename, true /*slow*/, true /*source*/);
cfilep->support(true);
m_usesVfinal[m_funcNum] = usesVfinal;
@ -609,12 +609,13 @@ void EmitCSyms::checkSplit(bool usesVfinal) {
V3OutCFile* const ofilep = optSystemC() ? new V3OutScFile{filename} : new V3OutCFile{filename};
setOutputFile(ofilep, cfilep);
m_ofpBase->puts(symClassName() + "_" + cvtToStr(m_funcNum) + "(");
m_ofpBase->puts(EmitCUtil::symClassName() + "_" + cvtToStr(m_funcNum) + "(");
if (usesVfinal) m_ofpBase->puts("__Vfinal");
m_ofpBase->puts(");\n");
emitSymImpPreamble();
puts("void " + symClassName() + "::" + symClassName() + "_" + cvtToStr(m_funcNum) + "(");
puts("void " + EmitCUtil::symClassName() + "::" + EmitCUtil::symClassName() + "_"
+ cvtToStr(m_funcNum) + "(");
if (usesVfinal) puts("int __Vfinal");
puts(") {\n");
}
@ -626,12 +627,12 @@ void EmitCSyms::emitSymImpPreamble() {
puts("\n");
// Includes
puts("#include \"" + pchClassName() + ".h\"\n");
puts("#include \"" + topClassName() + ".h\"\n");
puts("#include \"" + EmitCUtil::pchClassName() + ".h\"\n");
puts("#include \"" + EmitCUtil::topClassName() + ".h\"\n");
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep;
nodep = VN_AS(nodep->nextp(), NodeModule)) {
if (VN_IS(nodep, Class)) continue; // Class included earlier
putns(nodep, "#include \"" + prefixNameProtect(nodep) + ".h\"\n");
putns(nodep, "#include \"" + EmitCUtil::prefixNameProtect(nodep) + ".h\"\n");
}
puts("\n");
// Declarations for DPI Export implementation functions
@ -683,7 +684,7 @@ void EmitCSyms::emitScopeHier(bool destroy) {
void EmitCSyms::emitSymImp() {
UINFO(6, __FUNCTION__ << ": ");
const string filename = v3Global.opt.makeDir() + "/" + symClassName() + ".cpp";
const string filename = v3Global.opt.makeDir() + "/" + EmitCUtil::symClassName() + ".cpp";
AstCFile* const cfilep = newCFile(filename, true /*slow*/, true /*source*/);
cfilep->support(true);
@ -699,7 +700,7 @@ void EmitCSyms::emitSymImp() {
const string funcname = de ? "__Vdeserialize" : "__Vserialize";
const string op = de ? ">>" : "<<";
// NOLINTNEXTLINE(performance-inefficient-string-concatenation)
puts("void " + symClassName() + "::" + protect(funcname) + "(" + classname
puts("void " + EmitCUtil::symClassName() + "::" + protect(funcname) + "(" + classname
+ "& os) {\n");
puts("// Internal state\n");
if (v3Global.opt.trace()) puts("os" + op + "__Vm_activity;\n");
@ -707,8 +708,8 @@ void EmitCSyms::emitSymImp() {
puts("// Module instance state\n");
for (const auto& pair : m_scopes) {
const AstScope* const scopep = pair.first;
puts(protectIf(scopep->nameDotless(), scopep->protect()) + "." + protect(funcname)
+ "(os);\n");
puts(VIdProtect::protectIf(scopep->nameDotless(), scopep->protect()) + "."
+ protect(funcname) + "(os);\n");
}
puts("}\n");
}
@ -718,7 +719,7 @@ void EmitCSyms::emitSymImp() {
puts("// FUNCTIONS\n");
// Destructor
puts(symClassName() + "::~" + symClassName() + "()\n");
puts(EmitCUtil::symClassName() + "::~" + EmitCUtil::symClassName() + "()\n");
puts("{\n");
emitScopeHier(true);
if (v3Global.needTraceDumper()) {
@ -730,21 +731,21 @@ void EmitCSyms::emitSymImp() {
// Do not overwrite data during the last hierarchical stage.
const string firstHierCall
= (v3Global.opt.hierBlocks().empty() || v3Global.opt.hierChild()) ? "true" : "false";
puts("_vm_pgoProfiler.write(\"" + topClassName()
puts("_vm_pgoProfiler.write(\"" + EmitCUtil::topClassName()
+ "\", _vm_contextp__->profVltFilename(), " + firstHierCall + ");\n");
}
puts("}\n");
if (v3Global.needTraceDumper()) {
if (!optSystemC()) {
puts("\nvoid " + symClassName() + "::_traceDump() {\n");
puts("\nvoid " + EmitCUtil::symClassName() + "::_traceDump() {\n");
// Caller checked for __Vm_dumperp non-nullptr
puts("const VerilatedLockGuard lock{__Vm_dumperMutex};\n");
puts("__Vm_dumperp->dump(VL_TIME_Q());\n");
puts("}\n");
}
puts("\nvoid " + symClassName() + "::_traceDumpOpen() {\n");
puts("\nvoid " + EmitCUtil::symClassName() + "::_traceDumpOpen() {\n");
puts("const VerilatedLockGuard lock{__Vm_dumperMutex};\n");
puts("if (VL_UNLIKELY(!__Vm_dumperp)) {\n");
puts("__Vm_dumperp = new " + v3Global.opt.traceClassLang() + "();\n");
@ -755,7 +756,7 @@ void EmitCSyms::emitSymImp() {
puts("}\n");
puts("}\n");
puts("\nvoid " + symClassName() + "::_traceDumpClose() {\n");
puts("\nvoid " + EmitCUtil::symClassName() + "::_traceDumpClose() {\n");
puts("const VerilatedLockGuard lock{__Vm_dumperMutex};\n");
puts("__Vm_dumping = false;\n");
puts("VL_DO_CLEAR(delete __Vm_dumperp, __Vm_dumperp = nullptr);\n");
@ -764,8 +765,9 @@ void EmitCSyms::emitSymImp() {
puts("\n");
// Constructor
puts(symClassName() + "::" + symClassName()
+ "(VerilatedContext* contextp, const char* namep, " + topClassName() + "* modelp)\n");
puts(EmitCUtil::symClassName() + "::" + EmitCUtil::symClassName()
+ "(VerilatedContext* contextp, const char* namep, " + EmitCUtil::topClassName()
+ "* modelp)\n");
puts(" : VerilatedSyms{contextp}\n");
puts(" // Setup internal state of the Syms class\n");
puts(" , __Vm_modelp{modelp}\n");
@ -813,7 +815,7 @@ void EmitCSyms::emitSymImp() {
} else {
// The "." is added by catName
puts(", Verilated::catName(namep, ");
putsQuoted(protectWordsIf(scopep->prettyName(), scopep->protect()));
putsQuoted(VIdProtect::protectWordsIf(scopep->prettyName(), scopep->protect()));
puts(")");
}
puts("}\n");
@ -862,17 +864,18 @@ void EmitCSyms::emitSymImp() {
const AstNodeModule* const modp = i.second;
if (const AstScope* const aboveScopep = scopep->aboveScopep()) {
checkSplit(false);
const string protName = protectWordsIf(scopep->name(), scopep->protect());
const string protName = VIdProtect::protectWordsIf(scopep->name(), scopep->protect());
if (VN_IS(modp, ClassPackage)) {
// ClassPackage modules seem to be a bit out of place, so hard code...
putns(scopep, "TOP");
} else {
putns(scopep, protectIf(aboveScopep->nameDotless(), aboveScopep->protect()));
putns(scopep,
VIdProtect::protectIf(aboveScopep->nameDotless(), aboveScopep->protect()));
}
puts(".");
puts(protName.substr(protName.rfind('.') + 1));
puts(" = &");
puts(protectIf(scopep->nameDotless(), scopep->protect()) + ";\n");
puts(VIdProtect::protectIf(scopep->nameDotless(), scopep->protect()) + ";\n");
++m_numStmts;
}
}
@ -885,7 +888,7 @@ void EmitCSyms::emitSymImp() {
// first is used by AstCoverDecl's call to __vlCoverInsert
const bool first = !modp->user1();
modp->user1(true);
putns(scopep, protectIf(scopep->nameDotless(), scopep->protect()) + "."
putns(scopep, VIdProtect::protectIf(scopep->nameDotless(), scopep->protect()) + "."
+ protect("__Vconfigure") + "(" + (first ? "true" : "false") + ");\n");
++m_numStmts;
}
@ -896,7 +899,7 @@ void EmitCSyms::emitSymImp() {
checkSplit(false);
putns(it->second.m_nodep,
protect("__Vscope_" + it->second.m_symName) + ".configure(this, name(), ");
putsQuoted(protectWordsIf(it->second.m_prettyName, true));
putsQuoted(VIdProtect::protectWordsIf(it->second.m_prettyName, true));
puts(", ");
putsQuoted(protect(scopeDecodeIdentifier(it->second.m_prettyName)));
puts(", ");
@ -926,7 +929,7 @@ void EmitCSyms::emitSymImp() {
protect("__Vscope_" + scopep->scopeSymName()) + ".exportInsert(__Vfinal, ");
putsQuoted(funcp->cname()); // Not protected - user asked for import/export
puts(", (void*)(&");
puts(prefixNameProtect(modp));
puts(EmitCUtil::prefixNameProtect(modp));
puts("__");
puts(funcp->nameProtect());
puts("));\n");
@ -975,7 +978,7 @@ void EmitCSyms::emitSymImp() {
putsQuoted(protect(it->second.m_varBasePretty));
std::string varName;
varName += protectIf(scopep->nameDotless(), scopep->protect()) + ".";
varName += VIdProtect::protectIf(scopep->nameDotless(), scopep->protect()) + ".";
varName += protect(varp->name());
if (varp->isParam()) {
@ -1022,7 +1025,7 @@ void EmitCSyms::emitSymImp() {
void EmitCSyms::emitDpiHdr() {
UINFO(6, __FUNCTION__ << ": ");
const string filename = v3Global.opt.makeDir() + "/" + topClassName() + "__Dpi.h";
const string filename = v3Global.opt.makeDir() + "/" + EmitCUtil::topClassName() + "__Dpi.h";
AstCFile* const cfilep = newCFile(filename, false /*slow*/, false /*source*/);
cfilep->support(true);
V3OutCFile hf{filename};
@ -1051,14 +1054,16 @@ void EmitCSyms::emitDpiHdr() {
for (AstCFunc* nodep : m_dpis) {
if (nodep->dpiExportDispatcher()) {
if (!firstExp++) puts("\n// DPI EXPORTS\n");
putsDecoration(nodep, "// DPI export"
+ ifNoProtect(" at " + nodep->fileline()->ascii()) + "\n");
putsDecoration(
nodep, "// DPI export"
+ VIdProtect::ifNoProtect(" at " + nodep->fileline()->ascii()) + "\n");
putns(nodep, "extern " + nodep->rtnTypeVoid() + " " + nodep->nameProtect() + "("
+ cFuncArgs(nodep) + ");\n");
} else if (nodep->dpiImportPrototype()) {
if (!firstImp++) puts("\n// DPI IMPORTS\n");
putsDecoration(nodep, "// DPI import"
+ ifNoProtect(" at " + nodep->fileline()->ascii()) + "\n");
putsDecoration(
nodep, "// DPI import"
+ VIdProtect::ifNoProtect(" at " + nodep->fileline()->ascii()) + "\n");
putns(nodep, "extern " + nodep->rtnTypeVoid() + " " + nodep->nameProtect() + "("
+ cFuncArgs(nodep) + ");\n");
}
@ -1077,7 +1082,7 @@ void EmitCSyms::emitDpiHdr() {
void EmitCSyms::emitDpiImp() {
UINFO(6, __FUNCTION__ << ": ");
const string filename = v3Global.opt.makeDir() + "/" + topClassName() + "__Dpi.cpp";
const string filename = v3Global.opt.makeDir() + "/" + EmitCUtil::topClassName() + "__Dpi.cpp";
AstCFile* const cfilep = newCFile(filename, false /*slow*/, true /*source*/);
cfilep->support(true);
V3OutCFile hf(filename);
@ -1092,14 +1097,14 @@ void EmitCSyms::emitDpiImp() {
puts("// function names, you will get multiple definition link errors from here.\n");
puts("// This is an unfortunate result of the DPI specification.\n");
puts("// To solve this, either\n");
puts("// 1. Call " + topClassName() + "::{export_function} instead,\n");
puts("// 1. Call " + EmitCUtil::topClassName() + "::{export_function} instead,\n");
puts("// and do not even bother to compile this file\n");
puts("// or 2. Compile all __Dpi.cpp files in the same compiler run,\n");
puts("// and #ifdefs already inserted here will sort everything out.\n");
puts("\n");
puts("#include \"" + topClassName() + "__Dpi.h\"\n");
puts("#include \"" + topClassName() + ".h\"\n");
puts("#include \"" + EmitCUtil::topClassName() + "__Dpi.h\"\n");
puts("#include \"" + EmitCUtil::topClassName() + ".h\"\n");
puts("\n");
for (AstCFunc* nodep : m_dpis) {
@ -1109,8 +1114,9 @@ void EmitCSyms::emitDpiImp() {
puts("#define VL_DPIDECL_" + nodep->name() + "_\n");
putns(nodep,
nodep->rtnTypeVoid() + " " + nodep->name() + "(" + cFuncArgs(nodep) + ") {\n");
puts("// DPI export" + ifNoProtect(" at " + nodep->fileline()->ascii()) + "\n");
putns(nodep, "return " + topClassName() + "::" + nodep->name() + "(");
puts("// DPI export" + VIdProtect::ifNoProtect(" at " + nodep->fileline()->ascii())
+ "\n");
putns(nodep, "return " + EmitCUtil::topClassName() + "::" + nodep->name() + "(");
string comma;
for (AstNode* stmtp = nodep->argsp(); stmtp; stmtp = stmtp->nextp()) {
if (const AstVar* const portp = VN_CAST(stmtp, Var)) {

View File

@ -73,7 +73,7 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst {
// VISITORS
void visit(AstNetlist* nodep) override { iterateAndNextConstNull(nodep->modulesp()); }
void visit(AstNodeModule* nodep) override {
putfs(nodep, nodep->verilogKwd() + " " + EmitCBase::prefixNameProtect(nodep) + ";\n");
putfs(nodep, nodep->verilogKwd() + " " + EmitCUtil::prefixNameProtect(nodep) + ";\n");
iterateChildrenConst(nodep);
putqs(nodep, "end" + nodep->verilogKwd() + "\n");
}

View File

@ -982,8 +982,8 @@ const std::vector<AstCFunc*> createThreadFunctions(const ThreadSchedule& schedul
funcp->argTypes("void* voidSelf, bool even_cycle");
// Setup vlSelf and vlSyms
funcp->addStmtsp(new AstCStmt{fl, EmitCBase::voidSelfAssign(modp)});
funcp->addStmtsp(new AstCStmt{fl, EmitCBase::symClassAssign()});
funcp->addStmtsp(new AstCStmt{fl, EmitCUtil::voidSelfAssign(modp)});
funcp->addStmtsp(new AstCStmt{fl, EmitCUtil::symClassAssign()});
// Invoke each mtask scheduled to this thread from the thread function
for (const ExecMTask* const mtaskp : thread) {

View File

@ -1118,6 +1118,9 @@ private:
}
};
string VIdProtect::ifNoProtect(const string& in) VL_MT_SAFE {
return v3Global.opt.protectIds() ? "" : in;
}
string VIdProtect::protectIf(const string& old, bool doIt) VL_MT_SAFE {
return VIdProtectImp::singleton().protectIf(old, doIt);
}

View File

@ -461,6 +461,8 @@ class VIdProtectImp;
class VIdProtect final {
public:
// METHODS
// Return 'in' only if not protecting (e.g. for emitting a comment)
static string ifNoProtect(const string& in) VL_MT_SAFE;
// Rename to a new encoded string (unless earlier passthru'ed)
static string protect(const string& old) VL_MT_SAFE { return protectIf(old, true); }
static string protectIf(const string& old, bool doIt = true) VL_MT_SAFE;

View File

@ -390,7 +390,7 @@ void transformForks(AstNetlist* const netlistp) {
// If we're in a class, add a vlSymsp arg
if (m_inClass) {
newfuncp->addInitsp(new AstCStmt{nodep->fileline(), "VL_KEEP_THIS;\n"});
newfuncp->argTypes(EmitCBase::symClassVar());
newfuncp->argTypes(EmitCUtil::symClassVar());
callp->argTypes("vlSymsp");
}
// Put the begin's statements in the function, delete the begin

View File

@ -897,7 +897,7 @@ class TaskVisitor final : public VNVisitor {
// Convert input/inout DPI arguments to Internal types
string args;
args += ("(" + EmitCBase::symClassName()
args += ("(" + EmitCUtil::symClassName()
+ "*)(__Vscopep->symsp())"); // Upcast w/o overhead
AstNode* argnodesp = nullptr;
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
@ -1284,7 +1284,7 @@ class TaskVisitor final : public VNVisitor {
if (!nodep->dpiImport() && !nodep->taskPublic()) {
// Need symbol table
cfuncp->argTypes(EmitCBase::symClassVar());
cfuncp->argTypes(EmitCUtil::symClassVar());
if (cfuncp->name() == "new") {
const string stmt = VIdProtect::protect("_ctor_var_reset") + "(vlSymsp);\n";
cfuncp->addInitsp(new AstCStmt{nodep->fileline(), stmt});

View File

@ -519,8 +519,8 @@ class TraceVisitor final : public VNVisitor {
if (isTopFunc) {
// Top functions
funcp->argTypes("void* voidSelf, " + bufArg);
addInitStr(EmitCBase::voidSelfAssign(m_topModp));
addInitStr(EmitCBase::symClassAssign());
addInitStr(EmitCUtil::voidSelfAssign(m_topModp));
addInitStr(EmitCUtil::symClassAssign());
// Add global activity check to change dump functions
if (traceType == VTraceType::CHANGE) { //
addInitStr("if (VL_UNLIKELY(!vlSymsp->__Vm_activity)) return;\n");
@ -732,8 +732,8 @@ class TraceVisitor final : public VNVisitor {
cleanupFuncp->isStatic(true);
cleanupFuncp->isLoose(true);
m_topScopep->addBlocksp(cleanupFuncp);
cleanupFuncp->addInitsp(new AstCStmt{fl, EmitCBase::voidSelfAssign(m_topModp)});
cleanupFuncp->addInitsp(new AstCStmt{fl, EmitCBase::symClassAssign()});
cleanupFuncp->addInitsp(new AstCStmt{fl, EmitCUtil::voidSelfAssign(m_topModp)});
cleanupFuncp->addInitsp(new AstCStmt{fl, EmitCUtil::symClassAssign()});
// Register it
m_regFuncp->addStmtsp(new AstText{fl, "tracep->addCleanupCb(", true});

View File

@ -231,7 +231,7 @@ class VariableOrder final {
: (sigbytes == 2) ? 3
: (sigbytes == 1) ? 2
: 10;
m_attributes.emplace(varp, VarAttributes{stratum, EmitCBase::isAnonOk(varp)});
m_attributes.emplace(varp, VarAttributes{stratum, EmitCUtil::isAnonOk(varp)});
}
}