Example #1
0
    void visitEqNeqCase(AstNodeBiop* nodep) {
	UINFO(4," N/EQCASE->EQ "<<nodep<<endl);
	V3Const::constifyEdit(nodep->lhsp());  // lhsp may change
	V3Const::constifyEdit(nodep->rhsp());  // rhsp may change
	if (nodep->lhsp()->castConst() && nodep->rhsp()->castConst()) {
	    // Both sides are constant, node can be constant
	    V3Const::constifyEdit(nodep); VL_DANGLING(nodep);
	    return;
	} else {
	    AstNode* lhsp = nodep->lhsp()->unlinkFrBack();
	    AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
	    AstNode* newp;
	    // If we got ==1'bx it can never be true (but 1'bx==1'bx can be!)
	    if (((lhsp->castConst() && lhsp->castConst()->num().isFourState())
		 || (rhsp->castConst() && rhsp->castConst()->num().isFourState()))) {
		V3Number num (nodep->fileline(), 1, (nodep->castEqCase()?0:1));
		newp = new AstConst (nodep->fileline(), num);
		lhsp->deleteTree(); VL_DANGLING(lhsp);
		rhsp->deleteTree(); VL_DANGLING(rhsp);
	    } else {
		if (nodep->castEqCase())
		newp = new AstEq (nodep->fileline(), lhsp, rhsp);
		else newp = new AstNeq (nodep->fileline(), lhsp, rhsp);
	    }
	    nodep->replaceWith(newp);
	    nodep->deleteTree(); VL_DANGLING(nodep);
	    // Iterate tree now that we may have gotten rid of Xs
	    newp->iterateChildren(*this);
	}
    }
Example #2
0
    virtual void visit(AstCoverToggle* nodep, AstNUser*) {
	// Add to list of blocks under this scope
	UINFO(4,"    Move "<<nodep<<endl);
	AstNode* clonep = nodep->cloneTree(false);
	nodep->user2p(clonep);
	m_scopep->addActivep(clonep);
	clonep->iterateChildren(*this);	// We iterate under the *clone*
    }
Example #3
0
    virtual void visit(AstAssignVarScope* nodep, AstNUser*) {
	// Copy under the scope but don't recurse
	UINFO(4,"    Move "<<nodep<<endl);
	AstNode* clonep = nodep->cloneTree(false);
	nodep->user2p(clonep);
	m_scopep->addActivep(clonep);
	clonep->iterateChildren(*this);	// We iterate under the *clone*
    }
Example #4
0
    void visitEqNeqWild(AstNodeBiop* nodep) {
	UINFO(4," N/EQWILD->EQ "<<nodep<<endl);
	V3Const::constifyEdit(nodep->lhsp());  // lhsp may change
	V3Const::constifyEdit(nodep->rhsp());  // rhsp may change
	if (nodep->lhsp()->castConst() && nodep->rhsp()->castConst()) {
	    // Both sides are constant, node can be constant
	    V3Const::constifyEdit(nodep); VL_DANGLING(nodep);
	    return;
	} else {
	    AstNode* lhsp = nodep->lhsp()->unlinkFrBack();
	    AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
	    AstNode* newp;
	    if (!rhsp->castConst()) {
		nodep->v3error("Unsupported: RHS of ==? or !=? must be constant to be synthesizable");  // Says spec.
		// Replace with anything that won't cause more errors
		newp = new AstEq (nodep->fileline(), lhsp, rhsp);
	    } else {
		// X or Z's become mask, ala case statements.
		V3Number nummask  (rhsp->fileline(), rhsp->width());
		nummask.opBitsNonX(rhsp->castConst()->num());
		V3Number numval   (rhsp->fileline(), rhsp->width());
		numval.opBitsOne  (rhsp->castConst()->num());
		AstNode* and1p = new AstAnd(nodep->fileline(), lhsp,
					    new AstConst(nodep->fileline(), nummask));
		AstNode* and2p = new AstConst(nodep->fileline(), numval);
		if (nodep->castEqWild())
		    newp  = new AstEq  (nodep->fileline(), and1p, and2p);
		else newp = new AstNeq (nodep->fileline(), and1p, and2p);
		rhsp->deleteTree(); VL_DANGLING(rhsp);
	    }
	    nodep->replaceWith(newp);
	    nodep->deleteTree(); VL_DANGLING(nodep);
	    // Iterate tree now that we may have gotten rid of the compare
	    newp->iterateChildren(*this);
	}
    }