diff --git a/include/verilated.cpp b/include/verilated.cpp index 8e1956a38..c8d6db757 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -2994,8 +2994,8 @@ VerilatedScope::~VerilatedScope() { } void VerilatedScope::configure(VerilatedSyms* symsp, const char* prefixp, const char* suffixp, - const char* identifier, int8_t timeunit, - const Type& type) VL_MT_UNSAFE { + const char* identifier, int8_t timeunit, const Type& type, + const char* defName) VL_MT_UNSAFE { // Slowpath - called once/scope at construction // We don't want the space and reference-count access overhead of strings. m_symsp = symsp; @@ -3011,6 +3011,7 @@ void VerilatedScope::configure(VerilatedSyms* symsp, const char* prefixp, const m_namep = namep; } m_identifierp = identifier; + m_defNamep = defName; Verilated::threadContextp()->impp()->scopeInsert(this); } diff --git a/include/verilated.h b/include/verilated.h index 0b4592b27..a06c6935f 100644 --- a/include/verilated.h +++ b/include/verilated.h @@ -607,18 +607,21 @@ private: const char* m_identifierp = nullptr; // Identifier of scope (with escapes removed) int8_t m_timeunit = 0; // Timeunit in negative power-of-10 Type m_type = SCOPE_OTHER; // Type of the scope + const char* m_defNamep = nullptr; // defName (module name, not instance name) public: // But internals only - called from VerilatedModule's VerilatedScope() = default; ~VerilatedScope(); void configure(VerilatedSyms* symsp, const char* prefixp, const char* suffixp, - const char* identifier, int8_t timeunit, const Type& type) VL_MT_UNSAFE; + const char* identifier, int8_t timeunit, const Type& type, + const char* defName) VL_MT_UNSAFE; void exportInsert(int finalize, const char* namep, void* cb) VL_MT_UNSAFE; void varInsert(int finalize, const char* namep, void* datap, bool isParam, VerilatedVarType vltype, int vlflags, int dims, ...) VL_MT_UNSAFE; // ACCESSORS const char* name() const VL_MT_SAFE_POSTINIT { return m_namep; } const char* identifier() const VL_MT_SAFE_POSTINIT { return m_identifierp; } + const char* defname() const VL_MT_SAFE_POSTINIT { return m_defNamep; } int8_t timeunit() const VL_MT_SAFE_POSTINIT { return m_timeunit; } VerilatedSyms* symsp() const VL_MT_SAFE_POSTINIT { return m_symsp; } VerilatedVar* varFind(const char* namep) const VL_MT_SAFE_POSTINIT; diff --git a/include/verilated_vpi.cpp b/include/verilated_vpi.cpp index 4c255ed79..1fa86eff2 100644 --- a/include/verilated_vpi.cpp +++ b/include/verilated_vpi.cpp @@ -261,6 +261,7 @@ public: const VerilatedScope* scopep() const { return m_scopep; } const char* name() const override { return m_scopep->name(); } const char* fullname() const override { return m_scopep->name(); } + const char* defname() const override { return m_scopep->defname(); } }; class VerilatedVpioVar VL_NOT_FINAL : public VerilatedVpioVarBase { diff --git a/src/V3EmitCSyms.cpp b/src/V3EmitCSyms.cpp index a4c1c9707..6a0959766 100644 --- a/src/V3EmitCSyms.cpp +++ b/src/V3EmitCSyms.cpp @@ -44,12 +44,14 @@ class EmitCSyms final : EmitCBaseVisitor { const string m_prettyName; const int m_timeunit; string m_type; + string m_defName; ScopeData(const string& symName, const string& prettyName, int timeunit, - const string& type) + const string& type, const string& defName = "") : m_symName{symName} , m_prettyName{prettyName} , m_timeunit{timeunit} - , m_type{type} {} + , m_type{type} + , m_defName{defName} {} }; struct ScopeFuncData { AstScopeName* const m_scopep; @@ -194,6 +196,7 @@ class EmitCSyms final : EmitCBaseVisitor { m_scopeNames.emplace(scpit->second.m_symName, scpit->second); } else { scopeNameit->second.m_type = scpit->second.m_type; + scopeNameit->second.m_defName = scpit->second.m_defName; } } string::size_type pos = scp.rfind("__DOT__"); @@ -314,8 +317,9 @@ class EmitCSyms final : EmitCBaseVisitor { const string name = nodep->scopep()->shortName() + "__DOT__" + nodep->name(); const string name_pretty = AstNode::vpiName(name); const int timeunit = m_modp->timeunit().powerOfTen(); - m_vpiScopeCandidates.insert(std::make_pair( - name, ScopeData(scopeSymString(name), name_pretty, timeunit, type))); + m_vpiScopeCandidates.insert( + std::make_pair(name, ScopeData(scopeSymString(name), name_pretty, timeunit, type, + nodep->origModName()))); } } void visit(AstScope* nodep) override { @@ -328,9 +332,9 @@ class EmitCSyms final : EmitCBaseVisitor { const string type = VN_IS(nodep->modp(), Package) ? "SCOPE_OTHER" : "SCOPE_MODULE"; const string name_pretty = AstNode::vpiName(nodep->shortName()); const int timeunit = m_modp->timeunit().powerOfTen(); - m_vpiScopeCandidates.insert( - std::make_pair(nodep->name(), ScopeData(scopeSymString(nodep->name()), name_pretty, - timeunit, type))); + m_vpiScopeCandidates.insert(std::make_pair( + nodep->name(), ScopeData(scopeSymString(nodep->name()), name_pretty, timeunit, + type, nodep->modp()->origName()))); } } void visit(AstScopeName* nodep) override { @@ -338,8 +342,9 @@ class EmitCSyms final : EmitCBaseVisitor { // UINFO(9,"scnameins sp "<name()<<" sp "<scopePrettySymName() // <<" ss"<timeunit().powerOfTen() : 0; - m_scopeNames.emplace( - name, ScopeData(name, nodep->scopePrettySymName(), timeunit, "SCOPE_OTHER")); + m_scopeNames.emplace(name, ScopeData(name, nodep->scopePrettySymName(), timeunit, + "SCOPE_MODULE", m_modp->origName())); + if (nodep->dpiExport()) { UASSERT_OBJ(m_cfuncp, nodep, "ScopeName not under DPI function"); m_scopeFuncs.insert(std::make_pair(name + " " + m_cfuncp->name(), @@ -867,7 +872,10 @@ void EmitCSyms::emitSymImp() { putsQuoted(protect(scopeDecodeIdentifier(it->second.m_prettyName))); puts(", "); puts(cvtToStr(it->second.m_timeunit)); - puts(", VerilatedScope::" + it->second.m_type + ");\n"); + puts(", VerilatedScope::" + it->second.m_type); + puts(", "); + putsQuoted(it->second.m_defName); + puts(");\n"); ++m_numStmts; } } diff --git a/test_regress/t/t_vpi_var.cpp b/test_regress/t/t_vpi_var.cpp index 470af16de..1125eb5ef 100644 --- a/test_regress/t/t_vpi_var.cpp +++ b/test_regress/t/t_vpi_var.cpp @@ -269,6 +269,8 @@ int _mon_check_var() { CHECK_RESULT_CSTR(p, TestSimulator::top()); p = vpi_get_str(vpiType, vh2); CHECK_RESULT_CSTR(p, "vpiModule"); + p = vpi_get_str(vpiDefName, vh2); + CHECK_RESULT_CSTR(p, "t"); TestVpiHandle vh3 = vpi_handle_by_name((PLI_BYTE8*)"onebit", vh2); CHECK_RESULT_NZ(vh3); @@ -673,6 +675,8 @@ int _mon_check_putget_str(p_cb_data cb_data) { }; } else { // setup and install + const char* p = nullptr; + for (int i = 1; i <= 6; i++) { char buf[32]; snprintf(buf, sizeof(buf), TestSimulator::rooted("arr[%d].arr"), i); @@ -683,12 +687,17 @@ int _mon_check_putget_str(p_cb_data cb_data) { = vpi_handle_by_name((PLI_BYTE8*)"check", data[i].scope)); CHECK_RESULT_NZ(data[i].verbose = vpi_handle_by_name((PLI_BYTE8*)"verbose", data[i].scope)); - } + p = vpi_get_str(vpiDefName, data[i].scope); + CHECK_RESULT_CSTR(p, "arr"); + } for (int i = 1; i <= 6; i++) { char buf[32]; snprintf(buf, sizeof(buf), TestSimulator::rooted("subs[%d].subsub"), i); CHECK_RESULT_NZ(data[i].scope = vpi_handle_by_name((PLI_BYTE8*)buf, NULL)); + + p = vpi_get_str(vpiDefName, data[i].scope); + CHECK_RESULT_CSTR(p, "sub"); } static t_cb_data cb_data;