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();
	    }
	}
    }
Пример #2
0
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);
	}
    }
}
Пример #3
0
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);
	    }
	}
    }
}