virtual void visit(AstSel* nodep, AstNUser*) {
     AstVarRef* varrefp = nodep->fromp()->castVarRef();
     AstConst* constp = nodep->lsbp()->castConst();
     if (varrefp && constp && !constp->num().isFourState()) {
         UndrivenVarEntry* entryp = getEntryp (varrefp->varp());
         int lsb = constp->toUInt();
         if (m_markBoth || varrefp->lvalue()) entryp->drivenBit(lsb, nodep->width());
         if (m_markBoth || !varrefp->lvalue()) entryp->usedBit(lsb, nodep->width());
     } else {
         // else other varrefs handled as unknown mess in AstVarRef
         nodep->iterateChildren(*this);
     }
 }
Example #2
0
    virtual void visit(AstSel* nodep, AstNUser*) {
	AstVarRef* varrefp = nodep->fromp()->castVarRef();
	AstConst* constp = nodep->lsbp()->castConst();
	if (varrefp && constp && !constp->num().isFourState()) {
	    for (int usr=1; usr<(m_alwaysp?3:2); ++usr) {
		UndrivenVarEntry* entryp = getEntryp (varrefp->varp(), usr);
		int lsb = constp->toUInt();
		if (m_markBoth || varrefp->lvalue()) {
		    // Don't warn if already driven earlier as "a=0; if(a) a=1;" is fine.
		    if (usr==2 && m_alwaysp && entryp->isUsedNotDrivenBit(lsb, nodep->width())) {
			UINFO(9," Select.  Entryp="<<(void*)entryp<<endl);
			warnAlwCombOrder(varrefp);
		    }
		    entryp->drivenBit(lsb, nodep->width());
		}
		if (m_markBoth || !varrefp->lvalue()) entryp->usedBit(lsb, nodep->width());
	    }
	} else {
	    // else other varrefs handled as unknown mess in AstVarRef
	    nodep->iterateChildren(*this);
	}
    }
Example #3
0
    virtual void visit(AstNodeAssign* nodep) {
        if (!m_cfuncp) return;

        // Left select WordSel or ArraySel
        AstNodeSel* lselp = VN_CAST(nodep->lhsp(), NodeSel);
        if (!lselp) { mergeEnd(); return; }  // Not ever merged
        // Of a constant index
        AstConst* lbitp = VN_CAST(lselp->bitp(), Const);
        if (!lbitp) { mergeEnd(); return; }
        uint32_t index = lbitp->toUInt();
        // Of variable
        AstNodeVarRef* lvarrefp = VN_CAST(lselp->fromp(), NodeVarRef);
        if (!lvarrefp) { mergeEnd(); return; }

        // RHS is a constant or a select
        AstConst* rconstp = VN_CAST(nodep->rhsp(), Const);
        AstNodeSel* rselp = VN_CAST(nodep->rhsp(), NodeSel);
        AstNodeVarRef* rvarrefp = NULL;
        if (rconstp) {  // Ok
        } else {
            if (!rselp) { mergeEnd(); return; }
            AstConst* rbitp = VN_CAST(rselp->bitp(), Const);
            rvarrefp = VN_CAST(rselp->fromp(), NodeVarRef);
            if (!rbitp || rbitp->toUInt() != index
                || !rvarrefp
                || lvarrefp->varp() == rvarrefp->varp()) {
                mergeEnd(); return;
            }
        }

        if (m_mgSelLp) {  // Old merge
            if (m_mgCfuncp == m_cfuncp
                && m_mgNextp == nodep
                && m_mgSelLp->same(lselp)
                && m_mgVarrefLp->same(lvarrefp)
                && (m_mgConstRp
                    ? (rconstp && m_mgConstRp->same(rconstp))
                    : (rselp
                       && m_mgSelRp->same(rselp)
                       && m_mgVarrefRp->same(rvarrefp)))
                && (index == m_mgIndexLo-1
                    || index == m_mgIndexHi+1)) {
                // Sequentially next to last assign; continue merge
                if (index == m_mgIndexLo-1) m_mgIndexLo = index;
                else if (index == m_mgIndexHi+1) m_mgIndexHi = index;
                UINFO(9, "Continue merge i="<<index
                      <<" "<<m_mgIndexHi<<":"<<m_mgIndexLo<<" "<<nodep<<endl);
                m_mgAssignps.push_back(nodep);
                m_mgNextp = nodep->nextp();
                return;
            }
            else {
                // This assign doesn't merge with previous assign,
                // but should start a new merge
                mergeEnd();
            }
        }

        // Merge start
        m_mgAssignps.push_back(nodep);
        m_mgCfuncp = m_cfuncp;
        m_mgNextp = nodep->nextp();
        m_mgSelLp = lselp;
        m_mgSelRp = rselp;
        m_mgVarrefLp = lvarrefp;
        m_mgVarrefRp = rvarrefp;
        m_mgConstRp = rconstp;
        m_mgIndexLo = index;
        m_mgIndexHi = index;
        UINFO(9, "Start merge i="<<index<<" "<<nodep<<endl);
    }