Example #1
0
    // VISITORS
    virtual void visit(AstNodeModule* nodep, AstNUser*) {
	m_stmtCnt = 0;
	m_modp = nodep;
	m_modp->user2(CIL_MAYBE);
	if (m_modp->castIface()) {
	    // Inlining an interface means we no longer have a cell handle to resolve to.
	    // If inlining moves post-scope this can perhaps be relaxed.
	    cantInline("modIface",true);
	}
	if (m_modp->modPublic()) cantInline("modPublic",false);
	//
	nodep->iterateChildren(*this);
	//
	bool userinline = nodep->user1();
	int allowed = nodep->user2();
	int refs = nodep->user3();
	// Should we automatically inline this module?
	// inlineMult = 2000 by default.  If a mod*#instances is < this # nodes, can inline it
	bool doit = ((allowed == CIL_NOTSOFT || allowed == CIL_MAYBE)
		     && (userinline
			 || ((allowed == CIL_MAYBE)
			     && (refs==1
				 || m_stmtCnt < INLINE_MODS_SMALLER
				 || v3Global.opt.inlineMult() < 1
				 || refs*m_stmtCnt < v3Global.opt.inlineMult()))));
	// Packages aren't really "under" anything so they confuse this algorithm
	if (nodep->castPackage()) doit = false;
	UINFO(4, " Inline="<<doit<<" Possible="<<allowed<<" Usr="******" Refs="<<refs<<" Stmts="<<m_stmtCnt
	      <<"  "<<nodep<<endl);
	nodep->user1(doit);
	m_modp = NULL;
    }
    virtual void visit(AstVar* nodep, AstNUser*) {
	nodep->iterateChildren(*this);
	if (m_ftaskp) nodep->funcLocal(true);
	if (nodep->isSigModPublic()) {
	    nodep->sigModPublic(false);  // We're done with this attribute
	    m_modp->modPublic(true);	// Avoid flattening if signals are exposed
	}
    }
    virtual void visit(AstPragma* nodep, AstNUser*) {
	if (nodep->pragType() == AstPragmaType::PUBLIC_MODULE) {
	    if (!m_modp) nodep->v3fatalSrc("PUBLIC_MODULE not under a module\n");
	    m_modp->modPublic(true);
	    nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
	}
	else if (nodep->pragType() == AstPragmaType::PUBLIC_TASK) {
	    if (!m_ftaskp) nodep->v3fatalSrc("PUBLIC_TASK not under a task\n");
	    m_ftaskp->taskPublic(true);
	    m_modp->modPublic(true);  // Need to get to the task...
	    nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
	}
	else if (nodep->pragType() == AstPragmaType::COVERAGE_BLOCK_OFF) {
	    if (!v3Global.opt.coverageLine()) {  // No need for block statements; may optimize better without
		nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
	    }
	}
	else {
	    nodep->iterateChildren(*this);
	}
    }
void V3LinkLevel::wrapTop(AstNetlist* netlistp) {
    UINFO(2,__FUNCTION__<<": "<<endl);
    // We do ONLY the top module
    AstNodeModule* oldmodp = netlistp->modulesp();
    if (!oldmodp) netlistp->v3fatalSrc("No module found to process");
    AstNodeModule* newmodp = new AstModule(oldmodp->fileline(), (string)"TOP_"+oldmodp->name());
    // Make the new module first in the list
    oldmodp->unlinkFrBackWithNext();
    newmodp->addNext(oldmodp);
    newmodp->level(1);
    newmodp->modPublic(true);
    netlistp->addModulep(newmodp);

    // TODO the module creation above could be done after linkcells, but
    // the rest must be done after data type resolution
    wrapTopCell(netlistp);
    wrapTopPackages(netlistp);
}
    virtual void visit(AstCell* nodep, AstNUser*) {
	// Parent module inherits child's publicity
	if (nodep->modp()->modPublic()) m_modp->modPublic(true);
	//** No iteration for speed
    }
    virtual void visit(AstScInt* nodep, AstNUser*) {
	// Special class info means the module must remain public
	m_modp->modPublic(true);
	nodep->iterateChildren(*this);
    }
    virtual void visit(AstScDtor* nodep, AstNUser*) {
	// Destructor info means the module must remain public
	m_modp->modPublic(true);
	nodep->iterateChildren(*this);
    }