コード例 #1
0
ファイル: V3Case.cpp プロジェクト: grg/verilator
    AstNode* replaceCaseFastRecurse(AstNode* cexprp, int msb, uint32_t upperValue) {
	if (msb<0) {
	    // There's no space for a IF.  We know upperValue is thus down to a specific
	    // exact value, so just return the tree value
	    // Note can't clone here, as we're going to check for equivelence above
	    return m_valueItem[upperValue];
	}
	else {
	    // Make left and right subtrees
	    // cexpr[msb:lsb] == 1
	    AstNode* tree0p = replaceCaseFastRecurse(cexprp, msb-1, upperValue | 0);
	    AstNode* tree1p = replaceCaseFastRecurse(cexprp, msb-1, upperValue | (1UL<<msb));

	    if (tree0p == tree1p) {
		// Same logic on both sides, so we can just return one of 'em
		return tree0p;
	    }
	    // We could have a "checkerboard" with A B A B, we can use the same IF on both edges
	    bool same = true;
	    for (uint32_t a=upperValue,
		     b=(upperValue|(1UL<<msb));
		 a < (upperValue|(1UL<<msb));
		 a++, b++) {
		if (m_valueItem[a] != m_valueItem[b]) { same=false; break; }
	    }
	    if (same) {
		tree1p->deleteTree(); tree1p=NULL;
		return tree0p;
	    }

	    // Must have differing logic, so make a selection

	    // Case expressions can't be linked twice, so clone them
	    if (tree0p && !tree0p->user3()) tree0p = tree0p->cloneTree(true);
	    if (tree1p && !tree1p->user3()) tree1p = tree1p->cloneTree(true);

	    // Alternate scheme if we ever do multiple bits at a time:
	    //V3Number nummask (cexprp->fileline(), cexprp->width(), (1UL<<msb));
	    //AstNode* and1p = new AstAnd(cexprp->fileline(), cexprp->cloneTree(false),
	    //                            new AstConst(cexprp->fileline(), nummask));
	    AstNode* and1p = new AstSel(cexprp->fileline(), cexprp->cloneTree(false),
					msb, 1);
	    AstNode* eqp = new AstNeq(cexprp->fileline(),
				      new AstConst(cexprp->fileline(), 0),
				      and1p);
	    AstIf* ifp = new AstIf(cexprp->fileline(), eqp, tree1p, tree0p);
	    ifp->user3(1);	// So we don't bother to clone it
	    return ifp;
	}
    }