⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cuddapprox.c

📁 主要进行大规模的电路综合
💻 C
📖 第 1 页 / 共 5 页
字号:
    }    /* Enqueue regular pointer to root and initialize impact. */    node = Cudd_Regular(f);    item = (GlobalQueueItem *)	cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index));    if (item == NULL) {	cuddLevelQueueQuit(queue);	cuddLevelQueueQuit(localQueue);	return(0);    }    if (Cudd_IsComplement(f)) {	item->impactP = 0.0;	item->impactN = 1.0;    } else {	item->impactP = 1.0;	item->impactN = 0.0;    }    /* The nodes retrieved here are guaranteed to be non-terminal.    ** The initial node is not terminal because constant nodes are    ** dealt with in the calling procedure. Subsequent nodes are inserted    ** only if they are not terminal. */    while (queue->first != NULL) {	/* If the size of the subset is below the threshold, quit. */	if (info->size <= threshold)	    break;	item = (GlobalQueueItem *) queue->first;	node = item->node;#ifdef DD_DEBUG	assert(item->impactP >= 0 && item->impactP <= 1.0);	assert(item->impactN >= 0 && item->impactN <= 1.0);	assert(!Cudd_IsComplement(node));	assert(!Cudd_IsConstant(node));#endif	if (!st_lookup(info->table, (char *)node, (char **)&infoN)) {	    cuddLevelQueueQuit(queue);	    cuddLevelQueueQuit(localQueue);	    return(0);	}	quality = infoN->care ? quality1 : quality0;#ifdef DD_DEBUG	assert(infoN->parity >= 1 && infoN->parity <= 3);#endif	if (infoN->parity == 3) {	    /* This node can be reached through paths of different parity.	    ** It is not safe to replace it, because remapping will give	    ** an incorrect result, while replacement by 0 may cause node	    ** splitting. */	    cuddLevelQueueDequeue(queue,cuddI(dd,node->index));	    continue;	}	T = cuddT(node);	E = cuddE(node);	shared = NULL;	impactP = item->impactP;	impactN = item->impactN;	if (Cudd_bddLeq(dd,T,E)) {	    /* Here we know that E is regular. */#ifdef DD_DEBUG	    assert(!Cudd_IsComplement(E));#endif	    (void) st_lookup(info->table, (char *)T, (char **)&infoT);	    (void) st_lookup(info->table, (char *)E, (char **)&infoE);	    if (infoN->parity == 1) {		impact = impactP;		minterms = infoE->mintermsP/2.0 - infoT->mintermsP/2.0;		if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) {		    savings = 1 + computeSavings(dd,E,NULL,info,localQueue);		    if (savings == 1) {			cuddLevelQueueQuit(queue);			cuddLevelQueueQuit(localQueue);			return(0);		    }		} else {		    savings = 1;		}		replace = REPLACE_E;	    } else {#ifdef DD_DEBUG		assert(infoN->parity == 2);#endif		impact = impactN;		minterms = infoT->mintermsN/2.0 - infoE->mintermsN/2.0;		if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) {		    savings = 1 + computeSavings(dd,T,NULL,info,localQueue);		    if (savings == 1) {			cuddLevelQueueQuit(queue);			cuddLevelQueueQuit(localQueue);			return(0);		    }		} else {		    savings = 1;		}		replace = REPLACE_T;	    }	    numOnset = impact * minterms;	} else if (Cudd_bddLeq(dd,E,T)) {	    /* Here E may be complemented. */	    DdNode *Ereg = Cudd_Regular(E);	    (void) st_lookup(info->table, (char *)T, (char **)&infoT);	    (void) st_lookup(info->table, (char *)Ereg, (char **)&infoE);	    if (infoN->parity == 1) {		impact = impactP;		minterms = infoT->mintermsP/2.0 -		    ((E == Ereg) ? infoE->mintermsP : infoE->mintermsN)/2.0;		if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) {		    savings = 1 + computeSavings(dd,T,NULL,info,localQueue);		    if (savings == 1) {			cuddLevelQueueQuit(queue);			cuddLevelQueueQuit(localQueue);			return(0);		    }		} else {		    savings = 1;		}		replace = REPLACE_T;	    } else {#ifdef DD_DEBUG		assert(infoN->parity == 2);#endif		impact = impactN;		minterms = ((E == Ereg) ? infoE->mintermsN :			    infoE->mintermsP)/2.0 - infoT->mintermsN/2.0;		if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) {		    savings = 1 + computeSavings(dd,E,NULL,info,localQueue);		    if (savings == 1) {			cuddLevelQueueQuit(queue);			cuddLevelQueueQuit(localQueue);			return(0);		    }		} else {		    savings = 1;		}		replace = REPLACE_E;	    }	    numOnset = impact * minterms;	} else {	    DdNode *Ereg = Cudd_Regular(E);	    DdNode *TT = cuddT(T);	    DdNode *ET = Cudd_NotCond(cuddT(Ereg), Cudd_IsComplement(E));	    if (T->index == Ereg->index && TT == ET) {		shared = TT;		replace = REPLACE_TT;	    } else {		DdNode *TE = cuddE(T);		DdNode *EE = Cudd_NotCond(cuddE(Ereg), Cudd_IsComplement(E));		if (T->index == Ereg->index && TE == EE) {		    shared = TE;		    replace = REPLACE_TE;		} else {		    replace = REPLACE_N;		}	    }	    numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN;	    savings = computeSavings(dd,node,shared,info,localQueue);	    if (shared != NULL) {		NodeData *infoS;		(void) st_lookup(info->table, (char *)Cudd_Regular(shared),				 (char **)&infoS);		if (Cudd_IsComplement(shared)) {		    numOnset -= (infoS->mintermsN * impactP +			infoS->mintermsP * impactN)/2.0;		} else {		    numOnset -= (infoS->mintermsP * impactP +			infoS->mintermsN * impactN)/2.0;		}		savings--;	    }	}	cuddLevelQueueDequeue(queue,cuddI(dd,node->index));#if 0	if (replace == REPLACE_T || replace == REPLACE_E)	    (void) printf("node %p: impact = %g numOnset = %g savings %d\n",			  node, impact, numOnset, savings);	else	    (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n",			  node, impactP, impactN, numOnset, savings);#endif	if ((1 - numOnset / info->minterms) >	    quality * (1 - (double) savings / info->size)) {	    infoN->replace = replace;	    info->size -= savings;	    info->minterms -=numOnset;#if 0	    (void) printf("remap(%d): new size = %d new minterms = %g\n",			  replace, info->size, info->minterms);#endif	    if (replace == REPLACE_N) {		savings -= updateRefs(dd,node,NULL,info,localQueue);	    } else if (replace == REPLACE_T) {		savings -= updateRefs(dd,node,E,info,localQueue);	    } else if (replace == REPLACE_E) {		savings -= updateRefs(dd,node,T,info,localQueue);	    } else {#ifdef DD_DEBUG		assert(replace == REPLACE_TT || replace == REPLACE_TE);#endif		savings -= updateRefs(dd,node,shared,info,localQueue) - 1;	    }	    assert(savings == 0);	} else {	    replace = NOTHING;	}	if (replace == REPLACE_N) continue;	if ((replace == REPLACE_E || replace == NOTHING) &&	    !cuddIsConstant(cuddT(node))) {	    item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node),					 cuddI(dd,cuddT(node)->index));	    if (replace == REPLACE_E) {		item->impactP += impactP;		item->impactN += impactN;	    } else {		item->impactP += impactP/2.0;		item->impactN += impactN/2.0;	    }	}	if ((replace == REPLACE_T || replace == NOTHING) &&	    !Cudd_IsConstant(cuddE(node))) {	    item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)),					 cuddI(dd,Cudd_Regular(cuddE(node))->index));	    if (Cudd_IsComplement(cuddE(node))) {		if (replace == REPLACE_T) {		    item->impactP += impactN;		    item->impactN += impactP;		} else {		    item->impactP += impactN/2.0;		    item->impactN += impactP/2.0;		}	    } else {		if (replace == REPLACE_T) {		    item->impactP += impactP;		    item->impactN += impactN;		} else {		    item->impactP += impactP/2.0;		    item->impactN += impactN/2.0;		}	    }	}	if ((replace == REPLACE_TT || replace == REPLACE_TE) &&	    !Cudd_IsConstant(shared)) {	    item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(shared),					 cuddI(dd,Cudd_Regular(shared)->index));	    if (Cudd_IsComplement(shared)) {		if (replace == REPLACE_T) {		    item->impactP += impactN;		    item->impactN += impactP;		} else {		    item->impactP += impactN/2.0;		    item->impactN += impactP/2.0;		}	    } else {		if (replace == REPLACE_T) {		    item->impactP += impactP;		    item->impactN += impactN;		} else {		    item->impactP += impactP/2.0;		    item->impactN += impactN/2.0;		}	    }	}    }    cuddLevelQueueQuit(queue);    cuddLevelQueueQuit(localQueue);    return(1);} /* end of BAmarkNodes *//**Function********************************************************************  Synopsis [Builds the subset BDD for cuddRemapUnderApprox.]  Description [Builds the subset BDDfor cuddRemapUnderApprox.  Based  on the info table, performs remapping or replacement at selected  nodes. Returns a pointer to the result if successful; NULL  otherwise.]  SideEffects [None]  SeeAlso     [cuddRemapUnderApprox]******************************************************************************/static DdNode *RAbuildSubset(  DdManager * dd /* DD manager */,  DdNode * node /* current node */,  ApproxInfo * info /* node info */){    DdNode *Nt, *Ne, *N, *t, *e, *r;    NodeData *infoN;    if (Cudd_IsConstant(node))	return(node);    N = Cudd_Regular(node);    Nt = Cudd_NotCond(cuddT(N), Cudd_IsComplement(node));    Ne = Cudd_NotCond(cuddE(N), Cudd_IsComplement(node));    if (st_lookup(info->table, (char *)N, (char **)&infoN)) {	if (N == node ) {	    if (infoN->resultP != NULL) {		return(infoN->resultP);	    }	} else {	    if (infoN->resultN != NULL) {		return(infoN->resultN);	    }	}	if (infoN->replace == REPLACE_T) {	    r = RAbuildSubset(dd, Ne, info);	    return(r);	} else if (infoN->replace == REPLACE_E) {	    r = RAbuildSubset(dd, Nt, info);	    return(r);	} else if (infoN->replace == REPLACE_N) {	    return(info->zero);	} else if (infoN->replace == REPLACE_TT) {	    DdNode *Ntt = Cudd_NotCond(cuddT(cuddT(N)),				       Cudd_IsComplement(node));	    int index = cuddT(N)->index;	    DdNode *e = info->zero;	    DdNode *t = RAbuildSubset(dd, Ntt, info);	    if (t == NULL) {		return(NULL);	    }	    cuddRef(t);	    if (Cudd_IsComplement(t)) {		t = Cudd_Not(t);		e = Cudd_Not(e);		r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);		if (r == NULL) {		    Cudd_RecursiveDeref(dd, t);		    return(NULL);		}		r = Cudd_Not(r);	    } else {		r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);		if (r == NULL) {		    Cudd_RecursiveDeref(dd, t);		    return(NULL);		}	    }	    cuddDeref(t);	    return(r);	} else if (infoN->replace == REPLACE_TE) {	    DdNode *Nte = Cudd_NotCond(cuddE(cuddT(N)),				       Cudd_IsComplement(node));	    int index = cuddT(N)->index;	    DdNode *t = info->one;	    DdNode *e = RAbuildSubset(dd, Nte, info);	    if (e == NULL) {		return(NULL);	    }	    cuddRef(e);	    e = Cudd_Not(e);	    r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);	    if (r == NULL) {		Cudd_RecursiveDeref(dd, e);		return(NULL);	    }	    r =Cudd_Not(r);	    cuddDeref(e);	    return(r);	}    } else {	(void) fprintf(dd->err,		       "Something is wrong, ought to be in info table\n");	dd->errorCode = CUDD_INTERNAL_ERROR;	return(NULL);    }    t = RAbuildSubset(dd, Nt, info);    if (t == NULL) {	return(NULL);    }    cuddRef(t);    e = RAbuildSubset(dd, Ne, info);    if (e == NULL) {	Cudd_RecursiveDeref(dd,t);	return(NULL);    }    cuddRef(e);    if (Cudd_IsComplement(t)) {	t = Cudd_Not(t);	e = Cudd_Not(e);	r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e);	if (r == NULL) {	    Cudd_RecursiveDeref(dd, e);	    Cudd_RecursiveDeref(dd, t);	    return(NULL);	}	r = Cudd_Not(r);    } else {	r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e);	if (r == NULL) {	    Cudd_RecursiveDeref(dd, e);	    Cudd_RecursiveDeref(dd, t);	    return(NULL);	}    }    cuddDeref(t);    cuddDeref(e);    if (N == node) {	infoN->resultP = r;    } else {	infoN->resultN = r;    }    return(r);} /* end of RAbuildSubset *//**Function********************************************************************  Synopsis    [Finds 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -