diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 730a7770f..81d0dbba7 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -2785,7 +2785,7 @@ public: m_formCallTree = false; m_slow = false; m_funcPublic = false; - m_isStatic = false; + m_isStatic = true; // Note defaults to static, later we see where thisp is needed m_symProlog = false; } virtual ~AstCFunc() {} diff --git a/src/V3Changed.cpp b/src/V3Changed.cpp index e724d7ca7..4aac84e8a 100644 --- a/src/V3Changed.cpp +++ b/src/V3Changed.cpp @@ -109,6 +109,7 @@ private: m_chgFuncp = new AstCFunc(nodep->fileline(), "_change_request", scopep, "bool"); m_chgFuncp->argTypes(EmitCBaseVisitor::symClassVar()); m_chgFuncp->symProlog(true); + m_chgFuncp->declPrivate(true); m_scopetopp->addActivep(m_chgFuncp); // We need at least one change detect so we know to emit the correct code m_chgFuncp->addStmtsp(new AstChangeDet(nodep->fileline(), NULL, NULL, false)); diff --git a/src/V3Clock.cpp b/src/V3Clock.cpp index 8fed2e292..7636727f2 100644 --- a/src/V3Clock.cpp +++ b/src/V3Clock.cpp @@ -191,6 +191,7 @@ private: funcp->argTypes(EmitCBaseVisitor::symClassVar()); funcp->dontCombine(true); funcp->symProlog(true); + funcp->isStatic(true); m_scopep->addActivep(funcp); m_evalFuncp = funcp; } @@ -200,6 +201,7 @@ private: funcp->dontCombine(true); funcp->slow(true); funcp->symProlog(true); + funcp->isStatic(true); m_scopep->addActivep(funcp); m_initFuncp = funcp; } @@ -208,6 +210,7 @@ private: funcp->skipDecl(true); funcp->dontCombine(true); funcp->slow(true); + funcp->isStatic(false); funcp->addInitsp( new AstCStmt(nodep->fileline(), " "+EmitCBaseVisitor::symClassVar()+" = this->__VlSymsp;\n")); @@ -220,6 +223,7 @@ private: funcp->argTypes(EmitCBaseVisitor::symClassVar()); funcp->dontCombine(true); funcp->slow(true); + funcp->isStatic(true); funcp->symProlog(true); m_scopep->addActivep(funcp); m_settleFuncp = funcp; diff --git a/src/V3Depth.cpp b/src/V3Depth.cpp index 2c66eb6e1..af238fdde 100644 --- a/src/V3Depth.cpp +++ b/src/V3Depth.cpp @@ -23,6 +23,8 @@ // Each module: // For each wide OP, assign a temporary variable. // For each deep expression, assign expression to temporary. +// Each CFunc: +// Any statements that need "this" are marked non-static // //************************************************************************* @@ -68,6 +70,7 @@ private: // though it's one bit wide, needs the mask in the upper bits. // (Someday we'll have a valid bitmask instead of widths....) new AstRange(nodep->fileline(), nodep->width()-1, 0)); + if (!m_funcp) nodep->v3fatalSrc("Deep expression not under a function"); m_funcp->addInitsp(varp); // Replace node tree with reference to var AstVarRef* newp = new AstVarRef (nodep->fileline(), varp, false); @@ -94,14 +97,18 @@ private: m_depth = 0; m_maxdepth = 0; nodep->iterateChildren(*this); + m_funcp = NULL; } - virtual void visit(AstNodeStmt* nodep, AstNUser*) { + void visitStmt(AstNodeStmt* nodep) { m_depth = 0; m_maxdepth = 0; m_stmtp = nodep; nodep->iterateChildren(*this); m_stmtp = NULL; } + virtual void visit(AstNodeStmt* nodep, AstNUser*) { + visitStmt(nodep); + } // Operators virtual void visit(AstNodeTermop* nodep, AstNUser*) { } @@ -120,6 +127,29 @@ private: } } + //-------------------- + // Marking of non-static functions (because they might need "this") + void needNonStaticFunc(AstNode* nodep) { + if (!m_funcp) nodep->v3fatalSrc("Non-static accessor not under a function"); + if (m_funcp->isStatic()) { + UINFO(5,"Mark non-public due to "<isStatic(false); + } + } + virtual void visit(AstCoverInc* nodep, AstNUser*) { + // OPTIMIZE: For now this needs this->__Vcoverage, but could be globalized + needNonStaticFunc(nodep); + visitStmt(nodep); + } + virtual void visit(AstUCFunc* nodep, AstNUser*) { + needNonStaticFunc(nodep); + nodep->iterateChildren(*this); + } + virtual void visit(AstUCStmt* nodep, AstNUser*) { + needNonStaticFunc(nodep); + visitStmt(nodep); + } + //-------------------- // Default: Just iterate virtual void visit(AstVar* nodep, AstNUser*) {} // Don't hit varrefs under vars diff --git a/src/V3Descope.cpp b/src/V3Descope.cpp index 425ecec86..7e195eac2 100644 --- a/src/V3Descope.cpp +++ b/src/V3Descope.cpp @@ -111,6 +111,7 @@ private: if (newfuncp->stmtsp()) newfuncp->stmtsp()->unlinkFrBackWithNext()->deleteTree(); if (newfuncp->finalsp()) newfuncp->finalsp()->unlinkFrBackWithNext()->deleteTree(); newfuncp->name(name); + newfuncp->isStatic(false); newfuncp->addInitsp( new AstCStmt(newfuncp->fileline(), " "+EmitCBaseVisitor::symClassVar()+" = this->__VlSymsp;\n")); diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 7dd61714c..5a4b38f39 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -218,7 +218,7 @@ public: } virtual void visit(AstCoverInc* nodep, AstNUser*) { puts("if (VL_LIKELY(vlSymsp->__Vm_coverageRequest))"); - puts(" ++__Vcoverage["); + puts(" ++this->__Vcoverage["); puts(cvtToStr(m_coverIds.remap(nodep->declp()))); puts("];\n"); } virtual void visit(AstCReturn* nodep, AstNUser*) { @@ -592,12 +592,10 @@ class EmitCImp : EmitCStmts { puts(modClassName(m_modp)+"::"+nodep->name() +"("+cFuncArgs(nodep)+") {\n"); - puts("VL_DEBUG_IF(cout<<\""); + puts("VL_DEBUG_IF(cout<<\" "); for (int i=0;ilevel();i++) { puts(" "); } puts(modClassName(m_modp)+"::"+nodep->name() - +" \"" - +"<symProlog()) puts(EmitCBaseVisitor::symTopAssign()+"\n"); @@ -995,7 +993,7 @@ void EmitCStmts::visit(AstDisplay* nodep, AstNUser*) { case 't': displayArg(nodep,&elistp,fmt,'u'); break; case 'm': { emitDispState.pushFormat("%s"); - emitDispState.pushArg(NULL, "__VlSymsp->name("); + emitDispState.pushArg(NULL, "vlSymsp->name("); for (AstText* textp=nodep->scopeTextp(); textp; textp=textp->nextp()->castText()) { emitDispState.pushFormat(textp->text()); } @@ -1482,22 +1480,19 @@ void EmitCImp::emitInt(AstModule* modp) { puts("void\tinhibitSim(bool flag) { __Vm_inhibitSim=flag; }\t///< Set true to disable evaluation of module\n"); } ofp()->putsPrivate(true); // private: - puts("void\t_eval_initial_loop("+EmitCBaseVisitor::symClassVar()+");\n"); -#ifndef NEW_ORDERING - puts("IData\tchange_request();\n"); -#endif + puts("static void _eval_initial_loop("+EmitCBaseVisitor::symClassVar()+");\n"); } emitIntFuncDecls(modp); if (!optSystemPerl() && v3Global.opt.trace()) { ofp()->putsPrivate(false); // public: - puts("static void\ttraceInit (SpTraceVcd* vcdp, void* userthis, uint32_t code);\n"); - puts("static void\ttraceFull (SpTraceVcd* vcdp, void* userthis, uint32_t code);\n"); - puts("static void\ttraceChg (SpTraceVcd* vcdp, void* userthis, uint32_t code);\n"); + puts("static void traceInit (SpTraceVcd* vcdp, void* userthis, uint32_t code);\n"); + puts("static void traceFull (SpTraceVcd* vcdp, void* userthis, uint32_t code);\n"); + puts("static void traceChg (SpTraceVcd* vcdp, void* userthis, uint32_t code);\n"); } - puts("} VL_ATTR_ALIGNED(8);\n"); + puts("} VL_ATTR_ALIGNED(64);\n"); puts("\n"); // finish up h-file @@ -1791,10 +1786,12 @@ class EmitCTrace : EmitCStmts { puts(topClassName()+"::"+nodep->name() +"("+cFuncArgs(nodep)+") {\n"); + if (nodep->symProlog()) puts(EmitCBaseVisitor::symTopAssign()+"\n"); + puts("int c=code;\n"); puts("if (0 && vcdp && c) {} // Prevent unused\n"); if (nodep->funcType() == AstCFuncType::TRACE_INIT) { - puts("vcdp->module(name()); // Setup signal names\n"); + puts("vcdp->module(vlSymsp->name()); // Setup signal names\n"); } else if (nodep->funcType() == AstCFuncType::TRACE_FULL) { } else if (nodep->funcType() == AstCFuncType::TRACE_CHANGE) { } else nodep->v3fatalSrc("Bad Case"); diff --git a/src/V3EmitCSyms.cpp b/src/V3EmitCSyms.cpp index fb69cefdd..cf6c1e3d2 100644 --- a/src/V3EmitCSyms.cpp +++ b/src/V3EmitCSyms.cpp @@ -157,7 +157,7 @@ void EmitCSyms::emitInt() { puts("inline const char* name() { return __Vm_namep; }\n"); puts("inline bool getClearActivity() { bool r=__Vm_activity; __Vm_activity=false; return r;}\n"); puts("\n"); - puts("};\n"); + puts("} VL_ATTR_ALIGNED(64);\n"); puts("#endif /*guard*/\n"); } diff --git a/src/V3Task.cpp b/src/V3Task.cpp index d428c139e..30c564ce9 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -289,6 +289,7 @@ private: if (rtnvarp) funcp->addArgsp(rtnvarp); funcp->dontCombine(true); funcp->funcPublic(true); + funcp->isStatic(false); // We need to get a pointer to all of our variables (may have eval'ed something else earlier) funcp->addInitsp( diff --git a/src/Verilator.cpp b/src/Verilator.cpp index 68a297bf6..46b536f7f 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -413,6 +413,7 @@ void process () { } // Fix very deep expressions + // Mark evaluation functions as member functions, if needed. V3Depth::depthAll(v3Global.rootp()); //v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("depth.tree"));