Exemplo n.º 1
0
    // VISITORS
    virtual void visit(AstNodeVarRef* nodep, AstNUser*) {
	nodep->iterateChildren(*this);
	// We only allow a LHS ref for the var being set, and a RHS ref for something else being read.
	if (nodep->varScopep()->varp()->isSc()) {
	    clearSimple("SystemC sig");  // Don't want to eliminate the VL_ASSIGN_SI's
	}
	if (nodep->lvalue()) {
	    if (m_lhsVarRef) clearSimple(">1 lhs varRefs");
	    m_lhsVarRef = nodep;
	} else {
	    if (m_rhsVarRefs.size()>1) {
		AstNodeVarRef* lastRefp = m_rhsVarRefs.back();
		if (0) { // Diable the multiple-input optimization
		    clearSimple(">1 rhs varRefs");
		} else {
		    if (m_buffersOnly) clearSimple(">1 rhs varRefs");
		    if (!nodep->varScopep()->varp()->gateMultiInputOptimizable()
			// We didn't check multiInput on the first varref, so check it here
			|| !lastRefp->varScopep()->varp()->gateMultiInputOptimizable()) {
			clearSimple("!gateMultiInputOptimizable");
		    }
		}
	    }
	    m_rhsVarRefs.push_back(nodep);
	}
    }
Exemplo n.º 2
0
    virtual void visit(AstNodeAssign* nodep, AstNUser*) {
	m_substTreep = nodep->rhsp();
	if (!nodep->lhsp()->castNodeVarRef())
	    clearSimple("ASSIGN(non-VARREF)");
	else nodep->iterateChildren(*this);
	// We don't push logic other then assignments/NOTs into SenItems
	// This avoids a mess in computing what exactly a POSEDGE is
	// V3Const cleans up any NOTs by flipping the edges for us
	if (m_buffersOnly
	    && !(nodep->rhsp()->castVarRef()
		 // Avoid making non-clocked logic into clocked,
		 // as it slows down the verilator_sim_benchmark
		 || (nodep->rhsp()->castNot()
		     && nodep->rhsp()->castNot()->lhsp()->castVarRef()
		     && nodep->rhsp()->castNot()->lhsp()->castVarRef()->varp()->isUsedClock())
		)) {
	    clearSimple("Not a buffer (goes to a clock)");
	}
    }
Exemplo n.º 3
0
    //--------------------
    // Default
    virtual void visit(AstNode* nodep, AstNUser*) {
	// *** Special iterator
	if (!m_isSimple) return;	// Fastpath
	if (!(m_dedupe ? nodep->isGateDedupable() : nodep->isGateOptimizable())
	    || !nodep->isPure()
	    || nodep->isBrancher()) {
	    UINFO(5, "Non optimizable type: "<<nodep<<endl);
	    clearSimple("Non optimizable type");
	}
	else nodep->iterateChildren(*this);
    }
Exemplo n.º 4
0
    // CONSTUCTORS
    GateOkVisitor(AstNode* nodep, bool buffersOnly) {
	m_isSimple = true;
	m_substTreep = NULL;
	m_buffersOnly = buffersOnly;
	m_lhsVarRef = NULL;
	// Iterate
	nodep->accept(*this);
	// Check results
	if (!m_substTreep) {
	    clearSimple("No assignment found\n");
	}
	for (GateVarRefList::const_iterator it = rhsVarRefs().begin();
	     it != rhsVarRefs().end(); ++it) {
	    if (m_lhsVarRef && m_lhsVarRef->varScopep() == (*it)->varScopep()) {
		clearSimple("Circular logic\n");  // Oh my, we'll get a UNOPTFLAT much later.
	    }
	}
	if (debug()>=9 && !m_isSimple) {
	    nodep->dumpTree(cout,"\tgate!Ok: ");
	}
    }