diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index 92973ae02..abd01de1e 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -54,7 +54,6 @@ public: virtual void loopsMessageCb(V3GraphVertex* vertexp); }; - class LinkCellsVertex : public V3GraphVertex { AstNodeModule* m_modp; public: @@ -250,7 +249,7 @@ private: // this move to post param, which would mean we do not auto-read modules // and means we cannot compute module levels until later. UINFO(4,"Link Bind: "<name()); + AstNodeModule* modp = resolveModule(nodep, nodep->name()); if (modp) { AstNode* cellsp = nodep->cellsp()->unlinkFrBackWithNext(); // Module may have already linked, so need to pick up these new cells @@ -272,11 +271,11 @@ private: UINFO(4,"Link Cell: "<modName()); - if (modp) { - nodep->modp(modp); + AstNodeModule* cellmodp = resolveModule(nodep, nodep->modName()); + if (cellmodp) { + nodep->modp(cellmodp); // Track module depths, so can sort list from parent down to children - new V3GraphEdge(&m_graph, vertex(m_modp), vertex(modp), 1, false); + new V3GraphEdge(&m_graph, vertex(m_modp), vertex(cellmodp), 1, false); } } // Remove AstCell(AstPin("",NULL)), it's a side effect of how we parse "()" diff --git a/src/V3Param.cpp b/src/V3Param.cpp index dc0bcdc3f..bc97464dd 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -248,7 +248,7 @@ private: } else if (nodep->level() <= 2 // Haven't added top yet, so level 2 is the top || nodep->castPackage()) { // Likewise haven't done wrapTopPackages yet // Add request to END of modules left to process - m_todoModps.insert(make_pair(nodep->level(),nodep)); + m_todoModps.insert(make_pair(nodep->level(), nodep)); visitModules(); } else if (nodep->user5()) { UINFO(4," MOD-done "<iterateChildren(*this); if (!nodep->modp()) nodep->v3fatalSrc("Not linked?"); - if (nodep->paramsp() - || 1 // Need to look for interfaces; could track when one exists, but should be harmless to always do this - ) { + // We always run this, even if no parameters, as need to look for interfaces, + // and remove any recursive references + { UINFO(4,"De-parameterize: "<=10) nodep->dumpTree(cout,"-cell:\t"); // Evaluate all module constants V3Const::constifyParamsEdit(nodep); + AstNodeModule* srcModp = nodep->modp(); // Make sure constification worked // Must be a separate loop, as constant conversion may have changed some pointers. //if (debug()) nodep->dumpTree(cout,"-cel2:\t"); - string longname = nodep->modp()->name(); + string longname = srcModp->name(); bool any_overrides = false; longname += "_"; if (debug()>8) nodep->paramsp()->dumpTreeAndNext(cout,"-cellparams:\t"); @@ -549,7 +550,7 @@ void ParamVisitor::visitCell(AstCell* nodep) { && modvarp->subDTypep()->castUnpackArrayDType()) { // Array assigned to array AstNode* exprp = pinp->exprp(); - longname += "_" + paramSmallName(nodep->modp(),modvarp)+paramValueNumber(exprp); + longname += "_" + paramSmallName(srcModp, modvarp) + paramValueNumber(exprp); any_overrides = true; } else { AstConst* exprp = pinp->exprp()->castConst(); @@ -565,10 +566,10 @@ void ParamVisitor::visitCell(AstCell* nodep) { } else if (exprp->num().isDouble() || exprp->num().isString() || exprp->num().isFourState()) { - longname += "_" + paramSmallName(nodep->modp(),modvarp)+paramValueNumber(exprp); + longname += "_" + paramSmallName(srcModp, modvarp) + paramValueNumber(exprp); any_overrides = true; } else { - longname += "_" + paramSmallName(nodep->modp(),modvarp)+exprp->num().ascii(false); + longname += "_" + paramSmallName(srcModp, modvarp) + exprp->num().ascii(false); any_overrides = true; } } @@ -586,7 +587,7 @@ void ParamVisitor::visitCell(AstCell* nodep) { // This prevents making additional modules, and makes coverage more // obvious as it won't show up under a unique module page name. } else { - longname += "_" + paramSmallName(nodep->modp(),modvarp)+paramValueNumber(exprp); + longname += "_" + paramSmallName(srcModp, modvarp) + paramValueNumber(exprp); any_overrides = true; } } @@ -639,7 +640,7 @@ void ParamVisitor::visitCell(AstCell* nodep) { UINFO(9," pinIfaceRef "<ifaceViaCellp() != pinIrefp->ifaceViaCellp()) { UINFO(9," IfaceRefDType needs reconnect "<modp(),pinp->modVarp())+paramValueNumber(pinIrefp); + longname += "_" + paramSmallName(srcModp, pinp->modVarp()) + paramValueNumber(pinIrefp); any_overrides = true; ifaceRefRefs.push_back(make_pair(portIrefp,pinIrefp)); } @@ -659,35 +660,35 @@ void ParamVisitor::visitCell(AstCell* nodep) { if (iter != m_longMap.end()) { newname = iter->second; } else { - newname = nodep->modp()->name(); + newname = srcModp->name(); newname += "__pi"+cvtToStr(++m_longId); // We use all upper case above, so lower here can't conflict m_longMap.insert(make_pair(longname, newname)); } } - UINFO(4,"Name: "<modp()->name()<<"->"<"<name()<<"->"<"<second.m_modp; - if (!modp) { + if (iter != m_modNameMap.end()) cellmodp = iter->second.m_modp; + if (!cellmodp) { // Deep clone of new module // Note all module internal variables will be re-linked to the new modules by clone // However links outside the module (like on the upper cells) will not. - modp = nodep->modp()->cloneTree(false); - modp->name(newname); - modp->user5(false); // We need to re-recurse this module once changed - nodep->modp()->addNextHere(modp); // Keep tree sorted by cell occurrences + cellmodp = srcModp->cloneTree(false); + cellmodp->name(newname); + cellmodp->user5(false); // We need to re-recurse this module once changed + srcModp->addNextHere(cellmodp); // Keep tree sorted by cell occurrences - m_modNameMap.insert(make_pair(modp->name(), ModInfo(modp))); + m_modNameMap.insert(make_pair(cellmodp->name(), ModInfo(cellmodp))); iter = m_modNameMap.find(newname); CloneMap* clonemapp = &(iter->second.m_cloneMap); - UINFO(4," De-parameterize to new: "<paramsp()); @@ -728,17 +729,17 @@ void ParamVisitor::visitCell(AstCell* nodep) { } } else { - UINFO(4," De-parameterize to old: "<modp(modp); + nodep->modp(cellmodp); nodep->modName(newname); // We need to relink the pins to the new module CloneMap* clonemapp = &(iter->second.m_cloneMap); relinkPins(clonemapp, nodep->pinsp()); - UINFO(8," Done with "<modp()->level(),nodep->modp())); + m_todoModps.insert(make_pair(nodep->modp()->level(), nodep->modp())); } //######################################################################