diff --git a/Changes b/Changes index 623b17f5b..02b000b81 100644 --- a/Changes +++ b/Changes @@ -11,6 +11,8 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix error when tracing public parameters, bug722. [Jonathon Donaldson] +**** Fix dpiGetContext in dotted scopes, bug740. [Geoff Barrett] + * Verilator 3.862 2014-06-10 diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 24d9b6c4b..c1fac9d39 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -515,6 +515,24 @@ string AstScopeName::scopeSymName() const { return out; } +string AstScopeName::scopeDpiName() const { + string out; + for (AstText* textp=scopeEntrp(); textp; textp=textp->nextp()->castText()) { + out += textp->text(); + } + if (out.substr(0,10) == "__DOT__TOP") out.replace(0,10,""); + if (out.substr(0,7) == "__DOT__") out.replace(0,7,""); + if (out.substr(0,1) == ".") out.replace(0,1,""); + string::size_type pos; + while ((pos=out.find(".")) != string::npos) { + out.replace(pos, 1, "__"); + } + while ((pos=out.find("__DOT__")) != string::npos) { + out.replace(pos, 7, "__"); + } + return out; +} + bool AstSenTree::hasClocked() { if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it"); for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) { diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index eb205928f..21f84cf61 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -2983,7 +2983,10 @@ public: virtual bool cleanOut() { return true; } AstText* scopeAttrp() const { return op1p()->castText(); } void scopeAttrp(AstNode* nodep) { addOp1p(nodep); } + AstText* scopeEntrp() const { return op2p()->castText(); } + void scopeEntrp(AstNode* nodep) { addOp2p(nodep); } string scopeSymName() const; // Name for __Vscope variable including children + string scopeDpiName() const; // Name for DPI import scope string scopePrettyName() const; // Name for __Vscope printing bool dpiExport() const { return m_dpiExport; } void dpiExport(bool flag) { m_dpiExport=flag; } diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 8cfc030f7..bf546a5e4 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -226,7 +226,9 @@ public: virtual void visit(AstScopeName* nodep, AstNUser*) { // For use under AstCCalls for dpiImports. ScopeNames under displays are handled in AstDisplay if (!nodep->dpiExport()) { - putbs("(&(vlSymsp->__Vscope_"+nodep->scopeSymName()+"))"); + // this is where the DPI import context scope is set + string scope = nodep->scopeDpiName(); + putbs("(&(vlSymsp->__Vscope_"+scope+"))"); } } virtual void visit(AstSFormat* nodep, AstNUser*) { diff --git a/src/V3Inline.cpp b/src/V3Inline.cpp index bcc26ba63..975443504 100644 --- a/src/V3Inline.cpp +++ b/src/V3Inline.cpp @@ -387,6 +387,10 @@ private: if (afterp) afterp->unlinkFrBackWithNext(); nodep->scopeAttrp(new AstText(nodep->fileline(), (string)"__DOT__"+m_cellp->name())); if (afterp) nodep->scopeAttrp(afterp); + afterp = nodep->scopeEntrp(); + if (afterp) afterp->unlinkFrBackWithNext(); + nodep->scopeEntrp(new AstText(nodep->fileline(), (string)"__DOT__"+m_cellp->name())); + if (afterp) nodep->scopeEntrp(afterp); nodep->iterateChildren(*this); } virtual void visit(AstCoverDecl* nodep, AstNUser*) { diff --git a/src/V3Scope.cpp b/src/V3Scope.cpp index 00ab01eed..ce2dffa88 100644 --- a/src/V3Scope.cpp +++ b/src/V3Scope.cpp @@ -270,6 +270,10 @@ private: if (afterp) afterp->unlinkFrBackWithNext(); nodep->scopeAttrp(new AstText(nodep->fileline(), prefix)); if (afterp) nodep->scopeAttrp(afterp); + afterp = nodep->scopeEntrp(); + if (afterp) afterp->unlinkFrBackWithNext(); + nodep->scopeEntrp(new AstText(nodep->fileline(), prefix)); + if (afterp) nodep->scopeEntrp(afterp); nodep->iterateChildren(*this); } virtual void visit(AstScope* nodep, AstNUser*) { diff --git a/test_regress/t/t_dpi_context.v b/test_regress/t/t_dpi_context.v index f2cff60a2..d428a94d7 100644 --- a/test_regress/t/t_dpi_context.v +++ b/test_regress/t/t_dpi_context.v @@ -27,6 +27,7 @@ module sub (input integer inst); import "DPI-C" context function int dpic_line(); import "DPI-C" context function int dpic_save(int value); import "DPI-C" context function int dpic_restore(); + import "DPI-C" context function int unsigned dpic_getcontext(); int result; @@ -49,4 +50,17 @@ module sub (input integer inst); if (dpic_restore() != 23+inst) $stop; endtask + int unsigned cntxt1; + int unsigned cntxt2; + + initial begin + cntxt1 = dpic_getcontext(); + begin : caller_context + // call from a different scope - should still get the context of the function declaration + cntxt2 = dpic_getcontext(); + end + // svContext should be the context of the function declaration, not the context of the function call + if (cntxt1 != cntxt2) $stop; + end + endmodule diff --git a/test_regress/t/t_dpi_context_c.cpp b/test_regress/t/t_dpi_context_c.cpp index 12494fcd8..29a974edf 100644 --- a/test_regress/t/t_dpi_context_c.cpp +++ b/test_regress/t/t_dpi_context_c.cpp @@ -42,6 +42,7 @@ extern "C" { extern int dpic_line(); extern int dpic_save(int value); extern int dpic_restore(); + extern unsigned dpic_getcontext(); } #endif @@ -126,3 +127,9 @@ int dpic_restore() { return 0; } } + +unsigned dpic_getcontext() { + svScope scope = svGetScope(); + printf("%%Info: svGetScope returned scope (%p) with name %s\n", scope, svGetNameFromScope(scope)); + return (unsigned) (uintptr_t) scope; +}