diff --git a/include/verilated.cpp b/include/verilated.cpp index d55ae1de6..a2fa425e0 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -308,6 +308,11 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) { case '%': output += '%'; break; + case 'N': { // "C" string with name of module, add . if needed + const char* cstrp = va_arg(ap, const char*); + if (VL_LIKELY(*cstrp)) { output += cstrp; output += '.'; } + break; + } case 'S': { // "C" string const char* cstrp = va_arg(ap, const char*); output += cstrp; @@ -957,6 +962,7 @@ const char* Verilated::catName(const char* n1, const char* n2) { len = newlen; } strcpy(strp,n1); + if (*n1) strcat(strp,"."); strcat(strp,n2); return strp; } @@ -1005,12 +1011,9 @@ void VerilatedScope::configure(VerilatedSyms* symsp, const char* prefixp, const // We don't want the space and reference-count access overhead of strings. m_symsp = symsp; char* namep = new char[strlen(prefixp)+strlen(suffixp)+2]; - if (!*prefixp && *suffixp && suffixp[0]=='.') { // Special case of top module with empty name - drop the dots - strcpy(namep, suffixp+1); - } else { - strcpy(namep, prefixp); - strcat(namep, suffixp); - } + strcpy(namep, prefixp); + if (*prefixp && *suffixp) strcat(namep,"."); + strcat(namep, suffixp); m_namep = namep; VerilatedImp::scopeInsert(this); } diff --git a/include/verilated_dpi.cpp b/include/verilated_dpi.cpp index 57c7b4912..7a77c5b20 100644 --- a/include/verilated_dpi.cpp +++ b/include/verilated_dpi.cpp @@ -39,7 +39,7 @@ // Not supported yet #define _VL_SVDPI_UNIMP() \ - vl_fatal(__FILE__,__LINE__,"",Verilated::catName("%%Error: Unsupported DPI function: ",VL_FUNC)) + vl_fatal(__FILE__,__LINE__,"",(string("%%Error: Unsupported DPI function: ")+VL_FUNC).c_str()) // Function requires a "context" in the import declaration #define _VL_SVDPI_CONTEXT_WARN() \ diff --git a/include/verilatedos.h b/include/verilatedos.h index 8f5e4a543..b09d3a975 100644 --- a/include/verilatedos.h +++ b/include/verilatedos.h @@ -34,19 +34,32 @@ // Compiler pragma abstraction #ifdef __GNUC__ -# define VL_ATTR_PRINTF(fmtArgNum) __attribute__ ((format (printf, fmtArgNum, fmtArgNum+1))) # define VL_ATTR_ALIGNED(alignment) __attribute__ ((aligned (alignment))) +# define VL_ATTR_ALWINLINE __attribute__ ((always_inline)) # define VL_ATTR_NORETURN __attribute__ ((noreturn)) +# define VL_ATTR_PRINTF(fmtArgNum) __attribute__ ((format (printf, fmtArgNum, fmtArgNum+1))) # define VL_ATTR_UNUSED __attribute__ ((unused)) # define VL_FUNC __func__ # define VL_LIKELY(x) __builtin_expect(!!(x), 1) # define VL_UNLIKELY(x) __builtin_expect(!!(x), 0) # define VL_PREFETCH_RD(p) __builtin_prefetch((p),0) # define VL_PREFETCH_RW(p) __builtin_prefetch((p),1) +#elif defined(_MSC_VER) +# define VL_ATTR_ALIGNED(alignment) +# define VL_ATTR_ALWINLINE +# define VL_ATTR_NORETURN +# define VL_ATTR_PRINTF(fmtArgNum) +# define VL_ATTR_UNUSED +# define VL_FUNC __FUNCTION__ +# define VL_LIKELY(x) (!!(x)) +# define VL_UNLIKELY(x) (!!(x)) +# define VL_PREFETCH_RD(p) +# define VL_PREFETCH_RW(p) #else -# define VL_ATTR_PRINTF(fmtArgNum) ///< Function with printf format checking # define VL_ATTR_ALIGNED(alignment) ///< Align structure to specified byte alignment +# define VL_ATTR_ALWINLINE ///< Inline, even when not optimizing # define VL_ATTR_NORETURN ///< Function does not ever return +# define VL_ATTR_PRINTF(fmtArgNum) ///< Function with printf format checking # define VL_ATTR_UNUSED ///< Function that may be never used # define VL_FUNC "__func__" ///< Name of current function for error macros # define VL_LIKELY(x) (!!(x)) ///< Boolean expression more often true than false diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index db5ff0ffa..d4e726113 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -337,6 +337,8 @@ string AstScopeName::scopePrettyName() const { } // TOP will be replaced by top->name() 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,""); return AstNode::prettyName(out); } diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 9be407c5e..6e43c6c55 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -1217,10 +1217,12 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep, case 'x': displayArg(nodep,&elistp,isScan, vfmt,'x'); break; case 's': displayArg(nodep,&elistp,isScan, vfmt,'s'); break; case 'm': { - emitDispState.pushFormat("%S"); - emitDispState.pushArg(NULL, "vlSymsp->name()"); if (!scopenamep) nodep->v3fatalSrc("Display with %m but no AstScopeName"); - emitDispState.pushFormat(scopenamep->scopePrettyName()); + string suffix = scopenamep->scopePrettyName(); + if (suffix=="") emitDispState.pushFormat("%S"); + else emitDispState.pushFormat("%N"); // Add a . when needed + emitDispState.pushArg(NULL, "vlSymsp->name()"); + emitDispState.pushFormat(suffix); break; } case 'u': diff --git a/src/V3EmitCSyms.cpp b/src/V3EmitCSyms.cpp index 359a6724a..d04a2d630 100644 --- a/src/V3EmitCSyms.cpp +++ b/src/V3EmitCSyms.cpp @@ -290,7 +290,8 @@ void EmitCSyms::emitSymImp() { } else { ofp()->printf("\t%c %-30s ", comma, scopep->nameDotless().c_str()); puts("(Verilated::catName(topp->name(),"); - putsQuoted("."+scopep->prettyName()); + // The "." is added by catName + putsQuoted(scopep->prettyName()); puts("))\n"); comma=','; }