Internals: Refactor V3EmitUtil to not be base class. No functional change.
This commit is contained in:
parent
ac2859bf24
commit
5f23bf95f6
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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});
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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{}");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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});
|
||||
|
|
|
|||
|
|
@ -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});
|
||||
|
|
|
|||
|
|
@ -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)});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue