void visitModules() { // Loop on all modules left to process // Hitting a cell adds to the appropriate level of this level-sorted list, // so since cells originally exist top->bottom we process in top->bottom order too. while (!m_todoModps.empty()) { LevelModMap::iterator it = m_todoModps.begin(); AstNodeModule* nodep = it->second; m_todoModps.erase(it); if (!nodep->user5SetOnce()) { // Process once; note clone() must clear so we do it again UINFO(4," MOD "<<nodep<<endl); nodep->iterateChildren(*this); // Note above iterate may add to m_todoModps // // Process interface cells, then non-interface which may ref an interface cell for (int nonIf=0; nonIf<2; ++nonIf) { for (CellList::iterator it=m_cellps.begin(); it!=m_cellps.end(); ++it) { AstCell* nodep = *it; if ((nonIf==0 && nodep->modp()->castIface()) || (nonIf==1 && !nodep->modp()->castIface())) { visitCell(nodep); } } } m_cellps.clear(); } } }
void V3LinkLevel::wrapTopPackages(AstNetlist* netlistp) { // Instantiate all packages under the top wrapper // This way all later SCOPE based optimizations can ignore packages AstNodeModule* newmodp = netlistp->modulesp(); if (!newmodp || !newmodp->isTop()) netlistp->v3fatalSrc("No TOP module found to process"); for (AstNodeModule* modp = netlistp->modulesp(); modp; modp=modp->nextp()->castNodeModule()) { if (modp->castPackage()) { AstCell* cellp = new AstCell(modp->fileline(), // Could add __03a__03a="::" to prevent conflict // with module names/"v" modp->name(), modp->name(), NULL, NULL, NULL); cellp->modp(modp); newmodp->addStmtp(cellp); } } }
void V3LinkLevel::wrapTopCell(AstNetlist* netlistp) { AstNodeModule* newmodp = netlistp->modulesp(); if (!newmodp || !newmodp->isTop()) netlistp->v3fatalSrc("No TOP module found to process"); AstNodeModule* oldmodp = newmodp->nextp()->castNodeModule(); if (!oldmodp) netlistp->v3fatalSrc("No module found to process"); // Add instance AstCell* cellp = new AstCell(newmodp->fileline(), ((v3Global.opt.l2Name()!="") ? v3Global.opt.l2Name() : oldmodp->name()), oldmodp->name(), NULL, NULL, NULL); cellp->modp(oldmodp); newmodp->addStmtp(cellp); // Add pins for (AstNode* subnodep=oldmodp->stmtsp(); subnodep; subnodep = subnodep->nextp()) { if (AstVar* oldvarp=subnodep->castVar()) { UINFO(8,"VARWRAP "<<oldvarp<<endl); if (oldvarp->isIO()) { AstVar* varp = oldvarp->cloneTree(false); newmodp->addStmtp(varp); varp->sigPublic(true); // User needs to be able to get to it... if (oldvarp->isIO()) { oldvarp->primaryIO(true); varp->primaryIO(true); } if (varp->isIO() && v3Global.opt.systemC()) { varp->sc(true); // User can see trace one level down from the wrapper // Avoids packing & unpacking SC signals a second time varp->trace(false); } AstPin* pinp = new AstPin(oldvarp->fileline(),0,oldvarp->name(), new AstVarRef(varp->fileline(), varp, oldvarp->isOutput())); // Skip length and width comp; we know it's a direct assignment pinp->modVarp(oldvarp); cellp->addPinsp(pinp); } } } }