void genChangeDet(AstVarScope* vscp) { #ifdef NEW_ORDERING vscp->v3fatalSrc("Not applicable\n"); #endif AstVar* varp = vscp->varp(); vscp->v3warn(IMPERFECTSCH,"Imperfect scheduling of variable: "<<vscp); AstUnpackArrayDType* arrayp = varp->dtypeSkipRefp()->castUnpackArrayDType(); AstStructDType *structp = varp->dtypeSkipRefp()->castStructDType(); bool isArray = arrayp; bool isStruct = structp && structp->packedUnsup(); int elements = isArray ? arrayp->elementsConst() : 1; if (isArray && (elements > DETECTARRAY_MAX_INDEXES)) { vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect more than "<<cvtToStr(DETECTARRAY_MAX_INDEXES) <<" array indexes (probably with UNOPTFLAT warning suppressed): "<<varp->prettyName()<<endl <<vscp->warnMore() <<"... Could recompile with DETECTARRAY_MAX_INDEXES increased to at least "<<cvtToStr(elements)); } else if (!isArray && !isStruct && !varp->dtypeSkipRefp()->castBasicDType()) { if (debug()) varp->dumpTree(cout,"-DETECTARRAY-"); vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable (probably with UNOPTFLAT warning suppressed): "<<varp->prettyName()); } else { string newvarname = "__Vchglast__"+vscp->scopep()->nameDotless()+"__"+varp->shortName(); // Create: VARREF(_last) // ASSIGN(VARREF(_last), VARREF(var)) // ... // CHANGEDET(VARREF(_last), VARREF(var)) AstVar* newvarp = new AstVar (varp->fileline(), AstVarType::MODULETEMP, newvarname, varp); m_topModp->addStmtp(newvarp); AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopetopp, newvarp); m_scopetopp->addVarp(newvscp); for (int index=0; index<elements; ++index) { AstChangeDet* changep = new AstChangeDet (vscp->fileline(), aselIfNeeded(isArray, index, new AstVarRef(vscp->fileline(), vscp, false)), aselIfNeeded(isArray, index, new AstVarRef(vscp->fileline(), newvscp, false)), false); m_chgFuncp->addStmtsp(changep); AstAssign* initp = new AstAssign (vscp->fileline(), aselIfNeeded(isArray, index, new AstVarRef(vscp->fileline(), newvscp, true)), aselIfNeeded(isArray, index, new AstVarRef(vscp->fileline(), vscp, false))); m_chgFuncp->addFinalsp(initp); } } }
virtual void visit(AstVarScope* nodep, AstNUser*) { nodep->iterateChildren(*this); // Avoid updating this if (), instead see varp->isTrace() if (!nodep->varp()->isTemp() && !nodep->varp()->isFuncLocal()) { UINFO(5, " vsc "<<nodep<<endl); AstVar* varp = nodep->varp(); AstScope* scopep = nodep->scopep(); // Compute show name // This code assumes SPTRACEVCDC_VERSION >= 1330; // it uses spaces to separate hierarchy components. m_traShowname = AstNode::vcdName(scopep->name() + " " + varp->name()); if (m_traShowname.substr(0,4) == "TOP ") m_traShowname.replace(0,4,""); if (!m_initSubFuncp) nodep->v3fatalSrc("NULL"); m_traVscp = nodep; m_traValuep = NULL; if (varIgnoreTrace(varp)) { addIgnore(varIgnoreTrace(varp)); } else { ++m_statSigs; if (nodep->valuep()) m_traValuep = nodep->valuep()->cloneTree(true); else m_traValuep = new AstVarRef(nodep->fileline(), nodep, false); { // Recurse into data type of the signal; the visitors will call addTraceDecl() varp->dtypeSkipRefp()->accept(*this); } // Cleanup if (m_traValuep) { m_traValuep->deleteTree(); m_traValuep=NULL; } } m_traVscp = NULL; m_traValuep = NULL; m_traShowname = ""; } }