int equalityc(int varIndex, int value) { int i; variable v; DdNode * node, * tmp, *var ; v=vars[varIndex]; i=v.firstBoolVar; node=NULL; tmp=Cudd_ReadOne(mgr); Cudd_Ref(tmp); for (i=v.firstBoolVar; i<v.firstBoolVar+value; i++) { var=Cudd_bddIthVar(mgr,i); node=Cudd_bddAnd(mgr,tmp,Cudd_Not(var)); Cudd_Ref(node); Cudd_RecursiveDeref(mgr,tmp); tmp=node; } if (!(value==v.nVal-1)) { var=Cudd_bddIthVar(mgr,v.firstBoolVar+value); node=Cudd_bddAnd(mgr,tmp,var); Cudd_Ref(node); Cudd_RecursiveDeref(mgr,tmp); } return (int) node; }
/**Function******************************************************************** Synopsis [Checks if the two variables are symmetric.] Description [Returns 0 if vars are not symmetric. Return 1 if vars are symmetric.] SideEffects [] SeeAlso [] ******************************************************************************/ int Extra_bddCheckVarsSymmetricNaive( DdManager * dd, /* the DD manager */ DdNode * bF, int iVar1, int iVar2) { DdNode * bCube1, * bCube2; DdNode * bCof01, * bCof10; int Res; assert( iVar1 != iVar2 ); assert( iVar1 < dd->size ); assert( iVar2 < dd->size ); bCube1 = Cudd_bddAnd( dd, Cudd_Not( dd->vars[iVar1] ), dd->vars[iVar2] ); Cudd_Ref( bCube1 ); bCube2 = Cudd_bddAnd( dd, Cudd_Not( dd->vars[iVar2] ), dd->vars[iVar1] ); Cudd_Ref( bCube2 ); bCof01 = Cudd_Cofactor( dd, bF, bCube1 ); Cudd_Ref( bCof01 ); bCof10 = Cudd_Cofactor( dd, bF, bCube2 ); Cudd_Ref( bCof10 ); Res = (int)( bCof10 == bCof01 ); Cudd_RecursiveDeref( dd, bCof01 ); Cudd_RecursiveDeref( dd, bCof10 ); Cudd_RecursiveDeref( dd, bCube1 ); Cudd_RecursiveDeref( dd, bCube2 ); return Res; } /* end of Extra_bddCheckVarsSymmetricNaive */
/* preserve the state of unaffected variables */ DdNode* bdd_same(DdManager* m, pos* postab, int var, int proc) { DdNode* ret = Cudd_ReadOne(m); DdNode* var1, *var2, *xnor, *tmp; /* XNOR gate simulates equality */ Cudd_Ref(ret); int i, j; for (i=0; i<postab->num_procs; i++) {/* iterate through all processes */ if (i == proc) continue; /* skip pc of current process */ for (j=0; j<postab->pc_size; j++) {/* iterate through all bits */ var1 = Cudd_bddIthVar(m, postab->pc[i][j]); var2 = Cudd_bddIthVar(m, postab->pc_[i][j]); xnor = Cudd_bddXnor(m, var1, var2); Cudd_Ref(xnor); tmp = Cudd_bddAnd(m, ret, xnor); Cudd_Ref(tmp); Cudd_RecursiveDeref(m, xnor); Cudd_RecursiveDeref(m, ret); ret = tmp; } } for (i=0; i<postab->num_vars; i++) { /* iterate through all globals */ if (i == var) continue; /* skip assignment variable */ var1 = Cudd_bddIthVar(m, i); var2 = Cudd_bddIthVar(m, i+postab->num_vars); xnor = Cudd_bddXnor(m, var1, var2); Cudd_Ref(xnor); tmp = Cudd_bddAnd(m, ret, xnor); Cudd_Ref(tmp); Cudd_RecursiveDeref(m, xnor); Cudd_RecursiveDeref(m, ret); ret = tmp; } return ret; }
static YAP_Bool equality(void) { YAP_Term arg1, arg2, arg3, out; int varIndex; int value; int i; variable v; DdNode *node, *tmp, *var; arg1 = YAP_ARG1; arg2 = YAP_ARG2; arg3 = YAP_ARG3; varIndex = YAP_IntOfTerm(arg1); value = YAP_IntOfTerm(arg2); v = vars_ex[ex][varIndex]; i = v.firstBoolVar; tmp = Cudd_ReadOne(mgr_ex[ex]); Cudd_Ref(tmp); node = NULL; for (i = v.firstBoolVar; i < v.firstBoolVar + value; i++) { var = Cudd_bddIthVar(mgr_ex[ex], i); node = Cudd_bddAnd(mgr_ex[ex], tmp, Cudd_Not(var)); Cudd_Ref(node); Cudd_RecursiveDeref(mgr_ex[ex], tmp); tmp = node; } if (!(value == v.nVal - 1)) { var = Cudd_bddIthVar(mgr_ex[ex], v.firstBoolVar + value); node = Cudd_bddAnd(mgr_ex[ex], tmp, var); Cudd_Ref(node); Cudd_RecursiveDeref(mgr_ex[ex], tmp); } out = YAP_MkIntTerm((YAP_Int)node); return (YAP_Unify(out, arg3)); }
/**Function************************************************************* Synopsis [Converts graph to BDD.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ DdNode * Dec_GraphDeriveBdd( DdManager * dd, Dec_Graph_t * pGraph ) { DdNode * bFunc, * bFunc0, * bFunc1; Dec_Node_t * pNode; int i; // sanity checks assert( Dec_GraphLeaveNum(pGraph) >= 0 ); assert( Dec_GraphLeaveNum(pGraph) <= pGraph->nSize ); // check for constant function if ( Dec_GraphIsConst(pGraph) ) return Cudd_NotCond( b1, Dec_GraphIsComplement(pGraph) ); // check for a literal if ( Dec_GraphIsVar(pGraph) ) return Cudd_NotCond( Cudd_bddIthVar(dd, Dec_GraphVarInt(pGraph)), Dec_GraphIsComplement(pGraph) ); // assign the elementary variables Dec_GraphForEachLeaf( pGraph, pNode, i ) pNode->pFunc = Cudd_bddIthVar( dd, i ); // compute the function for each internal node Dec_GraphForEachNode( pGraph, pNode, i ) { bFunc0 = Cudd_NotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); bFunc1 = Cudd_NotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); pNode->pFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( pNode->pFunc ); }
/**Function************************************************************* Synopsis [Starts the monolithic image computation.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Extra_ImageTree2_t * Extra_bddImageStart2( DdManager * dd, DdNode * bCare, int nParts, DdNode ** pbParts, int nVars, DdNode ** pbVars, int fVerbose ) { Extra_ImageTree2_t * pTree; DdNode * bCubeAll, * bCubeNot, * bTemp; int i; pTree = ABC_ALLOC( Extra_ImageTree2_t, 1 ); pTree->dd = dd; pTree->bImage = NULL; bCubeAll = Extra_bddComputeCube( dd, dd->vars, dd->size ); Cudd_Ref( bCubeAll ); bCubeNot = Extra_bddComputeCube( dd, pbVars, nVars ); Cudd_Ref( bCubeNot ); pTree->bCube = Cudd_bddExistAbstract( dd, bCubeAll, bCubeNot ); Cudd_Ref( pTree->bCube ); Cudd_RecursiveDeref( dd, bCubeAll ); Cudd_RecursiveDeref( dd, bCubeNot ); // derive the monolithic relation pTree->bRel = b1; Cudd_Ref( pTree->bRel ); for ( i = 0; i < nParts; i++ ) { pTree->bRel = Cudd_bddAnd( dd, bTemp = pTree->bRel, pbParts[i] ); Cudd_Ref( pTree->bRel ); Cudd_RecursiveDeref( dd, bTemp ); } Extra_bddImageCompute2( pTree, bCare ); return pTree; }
/**Function************************************************************* Synopsis [Computes the transition relation of the network.] Description [Assumes that the global BDDs are computed.] SideEffects [] SeeAlso [] ***********************************************************************/ DdNode * Abc_NtkTransitionRelation( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbose ) { DdNode * bRel, * bTemp, * bProd, * bVar, * bInputs; Abc_Obj_t * pNode; int fReorder = 1; int i; // extand the BDD manager to represent NS variables assert( dd->size == Abc_NtkCiNum(pNtk) ); Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + Abc_NtkLatchNum(pNtk) - 1 ); // enable reordering if ( fReorder ) Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT ); else Cudd_AutodynDisable( dd ); // compute the transition relation bRel = b1; Cudd_Ref( bRel ); Abc_NtkForEachLatch( pNtk, pNode, i ) { bVar = Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + i ); // bProd = Cudd_bddXnor( dd, bVar, pNtk->vFuncsGlob->pArray[i] ); Cudd_Ref( bProd ); bProd = Cudd_bddXnor( dd, bVar, Abc_ObjGlobalBdd(Abc_ObjFanin0(pNode)) ); Cudd_Ref( bProd ); bRel = Cudd_bddAnd( dd, bTemp = bRel, bProd ); Cudd_Ref( bRel ); Cudd_RecursiveDeref( dd, bTemp ); Cudd_RecursiveDeref( dd, bProd ); }
/* recursively convert an AST expression into a BDD */ DdNode* bdd_expr(DdManager* m, symbol** symtab, ast_node* expr) { int i; DdNode* ret, *tmp1, *tmp2; switch (expr->tag) { case _id_expr: /* simply return that variable's BDD */ if ((i = symtab_lookup(symtab, expr->name)) < 0) { printf("Error: variable '%s' not found in symbol table\n", expr->name); exit(1); } ret = Cudd_bddIthVar(m, symtab_lookup(symtab, expr->name)); break; case _lit_expr: /* return a BDD 1 or 0 */ ret = expr->val ? Cudd_ReadOne(m) : Cudd_ReadLogicZero(m); break; case _not_expr: /* return complement BDD */ tmp1 = bdd_expr(m, symtab, expr->children[EXPR1]); ret = Cudd_Not(tmp1); Cudd_Ref(ret); Cudd_RecursiveDeref(m, tmp1); break; case _and_expr: /* return logical AND */ tmp1 = bdd_expr(m, symtab, expr->children[EXPR1]); tmp2 = bdd_expr(m, symtab, expr->children[EXPR2]); ret = Cudd_bddAnd(m, tmp1, tmp2); Cudd_Ref(ret); Cudd_RecursiveDeref(m, tmp1); Cudd_RecursiveDeref(m, tmp2); break; case _or_expr: /* return logical OR */ tmp1 = bdd_expr(m, symtab, expr->children[EXPR1]); tmp2 = bdd_expr(m, symtab, expr->children[EXPR2]); ret = Cudd_bddOr(m, tmp1, tmp2); Cudd_Ref(ret); Cudd_RecursiveDeref(m, tmp1); Cudd_RecursiveDeref(m, tmp2); break; case _eq_expr: /* check for equality, return 1 or 0 */ tmp1 = bdd_expr(m, symtab, expr->children[EXPR1]); tmp2 = bdd_expr(m, symtab, expr->children[EXPR2]); if (Cudd_EquivDC(m, tmp1, tmp2, Cudd_ReadLogicZero(m))) ret = Cudd_ReadOne(m); else ret = Cudd_ReadLogicZero(m); Cudd_RecursiveDeref(m, tmp1); Cudd_RecursiveDeref(m, tmp2); break; case _impl_expr: /* return logical implication (!a|b) */ tmp1 = Cudd_Not(bdd_expr(m, symtab, expr->children[EXPR1])); tmp2 = bdd_expr(m, symtab, expr->children[EXPR2]); ret = Cudd_bddOr(m, tmp1, tmp2); Cudd_Ref(ret); Cudd_RecursiveDeref(m, tmp1); Cudd_RecursiveDeref(m, tmp2); break; default: printf("Error: invalid expression\n"); exit(1); } return ret; }
/**Function******************************************************************** Synopsis [Generates a BDD for the function x > y.] Description [This function generates a BDD for the function x > y. Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. The BDD is built bottom-up. It has 3*N-1 internal nodes, if the variables are ordered as follows: x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. Argument z is not used by Cudd_Xgty: it is included to make it call-compatible to Cudd_Dxygtdxz and Cudd_Dxygtdyz.] SideEffects [None] SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdxz Cudd_Dxygtdyz] ******************************************************************************/ DdNode * Cudd_Xgty( DdManager * dd /* DD manager */, int N /* number of x and y variables */, DdNode ** z /* array of z variables: unused */, DdNode ** x /* array of x variables */, DdNode ** y /* array of y variables */) { DdNode *u, *v, *w; int i; /* Build bottom part of BDD outside loop. */ u = Cudd_bddAnd(dd, x[N-1], Cudd_Not(y[N-1])); if (u == NULL) return(NULL); cuddRef(u); /* Loop to build the rest of the BDD. */ for (i = N-2; i >= 0; i--) { v = Cudd_bddAnd(dd, y[i], Cudd_Not(u)); if (v == NULL) { Cudd_RecursiveDeref(dd, u); return(NULL); } cuddRef(v); w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u); if (w == NULL) { Cudd_RecursiveDeref(dd, u); Cudd_RecursiveDeref(dd, v); return(NULL); } cuddRef(w); Cudd_RecursiveDeref(dd, u); u = Cudd_bddIte(dd, x[i], Cudd_Not(v), w); if (u == NULL) { Cudd_RecursiveDeref(dd, v); Cudd_RecursiveDeref(dd, w); return(NULL); } cuddRef(u); Cudd_RecursiveDeref(dd, v); Cudd_RecursiveDeref(dd, w); } cuddDeref(u); return(u); } /* end of Cudd_Xgty */
DdNode* compute_EF(DdManager* m, pos* postab, DdNode* R, DdNode* p) { DdNode* last = Cudd_ReadOne(m); DdNode* current = p; while (!Cudd_EquivDC(m, last, current, Cudd_ReadLogicZero(m))) { // printf("iterating\n"); last = Cudd_bddAnd(m, current, Cudd_ReadOne(m)); current = Cudd_bddOr(m, p, compute_EX(m, postab, R, current)); } return current; }
int andc(int nodea, int nodeb) { DdNode * node1, *node2,*nodeout; node1=(DdNode *)nodea; node2=(DdNode *)nodeb; nodeout=Cudd_bddAnd(mgr,node1,node2); Cudd_Ref(nodeout); return (int)nodeout; }
/** * @brief Basic test of Cudd_CountMinterm(). * @return 0 if successful; -1 otherwise. */ static int testCount(int verbosity) { DdManager *dd; DdNode *h; int i, ret; int const N = 2044; /* number of variables */ dd = Cudd_Init(N, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); if (!dd) { if (verbosity) { printf("initialization failed\n"); } return -1; } /* Build a cube with N/2 variables. */ h = Cudd_ReadOne(dd); Cudd_Ref(h); for (i = 0; i < N; i += 2) { DdNode *var, *tmp; var = Cudd_bddIthVar(dd, N-i-1); tmp = Cudd_bddAnd(dd, h, var); if (!tmp) { Cudd_Quit(dd); return -1; } Cudd_Ref(tmp); Cudd_RecursiveDeref(dd, h); h = tmp; } if (verbosity) { printf("h (dbl) "); Cudd_PrintDebug(dd, h, N, 1); printf("h (apa) "); Cudd_PrintSummary(dd, h, N, 1); } Cudd_RecursiveDeref(dd, h); if (verbosity) { printf("one[%d] (dbl) ", N); Cudd_PrintDebug(dd, Cudd_ReadOne(dd), N, 1); printf("one[%d] (apa) ", N); Cudd_PrintSummary(dd, Cudd_ReadOne(dd), N, 1); ret = Cudd_CheckZeroRef(dd); printf("one[%d] (dbl) ", N+1); Cudd_PrintDebug(dd, Cudd_ReadOne(dd), N+1, 1); printf("one[%d] (apa) ", N+1); Cudd_PrintSummary(dd, Cudd_ReadOne(dd), N+1, 1); ret = Cudd_CheckZeroRef(dd); } if (verbosity && ret != 0) { printf("%d non-zero references\n", ret); } Cudd_Quit(dd); return 0; }
DdNode* path(DdManager *manager, int* p, int vars) { DdNode *tmp, *var, *f; f = Cudd_ReadOne(manager); Cudd_Ref(f); for (int i = vars; i--;) { tmp = Cudd_bddAnd(manager,getVar(manager,i,p[i]),f); Cudd_Ref(tmp); Cudd_RecursiveDeref(manager,f); f = tmp; } return f; }
static YAP_Bool and (void) { YAP_Term arg1, arg2, arg3, out; DdNode *node1, *node2, *nodeout; arg1 = YAP_ARG1; arg2 = YAP_ARG2; arg3 = YAP_ARG3; node1 = (DdNode *)YAP_IntOfTerm(arg1); node2 = (DdNode *)YAP_IntOfTerm(arg2); nodeout = Cudd_bddAnd(mgr_ex[ex], node1, node2); Cudd_Ref(nodeout); out = YAP_MkIntTerm((YAP_Int)nodeout); return (YAP_Unify(out, arg3)); }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Converts graph to BDD.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ DdNode * Dec_GraphDeriveBdd( DdManager * dd, Dec_Graph_t * pGraph ) { DdNode * bFunc, * bFunc0, * bFunc1; Dec_Node_t * pNode = NULL; // Suppress "might be used uninitialized" int i; // sanity checks assert( Dec_GraphLeaveNum(pGraph) >= 0 ); assert( Dec_GraphLeaveNum(pGraph) <= pGraph->nSize ); // check for constant function if ( Dec_GraphIsConst(pGraph) ) return Cudd_NotCond( b1, Dec_GraphIsComplement(pGraph) ); // check for a literal if ( Dec_GraphIsVar(pGraph) ) return Cudd_NotCond( Cudd_bddIthVar(dd, Dec_GraphVarInt(pGraph)), Dec_GraphIsComplement(pGraph) ); // assign the elementary variables Dec_GraphForEachLeaf( pGraph, pNode, i ) pNode->pFunc = Cudd_bddIthVar( dd, i ); // compute the function for each internal node Dec_GraphForEachNode( pGraph, pNode, i ) { bFunc0 = Cudd_NotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); bFunc1 = Cudd_NotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); pNode->pFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( (DdNode *)pNode->pFunc ); }
/* encode the program counter in an array of boolean variables */ DdNode* bdd_encode_pc(DdManager* m, DdNode* node, int** pc_array, int pc_size, int proc, int pc) { int i; DdNode* tmp, *var; DdNode* ret = Cudd_ReadOne(m); Cudd_Ref(ret); for (i=0; i<pc_size; i++) { /* iterate for each bit in pc_size */ var = Cudd_bddIthVar(m, pc_array[proc][i]); if (pc % 2) /* encode true bit */ tmp = Cudd_bddAnd(m, var, ret); else /* encode false bit */ tmp = Cudd_bddAnd(m, Cudd_Not(var), ret); Cudd_Ref(tmp); Cudd_RecursiveDeref(m, ret); /* release the old bdd each time a new */ ret = tmp; /* one is made */ pc /= 2; } tmp = Cudd_bddAnd(m, ret, node); /* add encoding to existing edge */ Cudd_Ref(tmp); Cudd_RecursiveDeref(m, ret); Cudd_RecursiveDeref(m, node); return tmp; /* return updated edge */ }
/**Function************************************************************* Synopsis [Derives the global BDD for one AIG node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ DdNode * Bbr_NodeGlobalBdds_rec( DdManager * dd, Aig_Obj_t * pNode, int nBddSizeMax, int fDropInternal, ProgressBar * pProgress, int * pCounter, int fVerbose ) { DdNode * bFunc, * bFunc0, * bFunc1; assert( !Aig_IsComplement(pNode) ); if ( Cudd_ReadKeys(dd)-Cudd_ReadDead(dd) > (unsigned)nBddSizeMax ) { // Extra_ProgressBarStop( pProgress ); if ( fVerbose ) printf( "The number of live nodes reached %d.\n", nBddSizeMax ); fflush( stdout ); return NULL; } // if the result is available return if ( Aig_ObjGlobalBdd(pNode) == NULL ) { // compute the result for both branches bFunc0 = Bbr_NodeGlobalBdds_rec( dd, Aig_ObjFanin0(pNode), nBddSizeMax, fDropInternal, pProgress, pCounter, fVerbose ); if ( bFunc0 == NULL ) return NULL; Cudd_Ref( bFunc0 ); bFunc1 = Bbr_NodeGlobalBdds_rec( dd, Aig_ObjFanin1(pNode), nBddSizeMax, fDropInternal, pProgress, pCounter, fVerbose ); if ( bFunc1 == NULL ) return NULL; Cudd_Ref( bFunc1 ); bFunc0 = Cudd_NotCond( bFunc0, Aig_ObjFaninC0(pNode) ); bFunc1 = Cudd_NotCond( bFunc1, Aig_ObjFaninC1(pNode) ); // get the final result bFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( bFunc ); Cudd_RecursiveDeref( dd, bFunc0 ); Cudd_RecursiveDeref( dd, bFunc1 ); // add the number of used nodes (*pCounter)++; // set the result assert( Aig_ObjGlobalBdd(pNode) == NULL ); Aig_ObjSetGlobalBdd( pNode, bFunc ); // increment the progress bar // if ( pProgress ) // Extra_ProgressBarUpdate( pProgress, *pCounter, NULL ); } // prepare the return value bFunc = Aig_ObjGlobalBdd(pNode); // dereference BDD at the node if ( --pNode->nRefs == 0 && fDropInternal ) { Cudd_Deref( bFunc ); Aig_ObjSetGlobalBdd( pNode, NULL ); } return bFunc; }
DdNode* compute_EX(DdManager* m, pos* postab, DdNode* R, DdNode* p) { DdNode* tmp; /* rename variables */ int perm[2*(postab->num_procs*postab->pc_size+postab->num_vars)]; int i, j, k; for (i=0; i<postab->num_vars; i++) { perm[i] = i+postab->num_vars; perm[i+postab->num_vars] = i; } for (j=0; j<postab->num_procs; j++) { for (k=0; k<postab->pc_size; k++) { perm[postab->num_vars+i] = postab->pc_[j][k]; perm[postab->num_vars+postab->num_procs*postab->pc_size+i++] = postab->pc[j][k]; } } p = Cudd_bddPermute(m, p, perm); /* construct cube of next state variables */ DdNode* cube = Cudd_ReadOne(m); for (i=0; i<postab->num_vars; i++) { tmp = Cudd_bddAnd(m, cube, Cudd_bddIthVar(m, postab->num_vars+i)); Cudd_Ref(tmp); Cudd_RecursiveDeref(m, cube); cube = tmp; } for (i=0; i<postab->num_procs*postab->pc_size; i++) { tmp = Cudd_bddAnd(m, cube, Cudd_bddIthVar(m, 2*postab->num_vars+postab->num_procs*postab->pc_size+i)); Cudd_Ref(tmp); Cudd_RecursiveDeref(m, cube); cube = tmp; } DdNode* EX_p = Cudd_bddAndAbstract(m, R, p, cube); Cudd_Ref(EX_p); Cudd_RecursiveDeref(m, p); Cudd_RecursiveDeref(m, cube); return EX_p; }
/**Function************************************************************* Synopsis [Returns the array of constraint candidates.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ DdNode * Llb_ManComputeIndCase_rec( Aig_Man_t * p, Aig_Obj_t * pObj, DdManager * dd, Vec_Ptr_t * vBdds ) { DdNode * bBdd0, * bBdd1; DdNode * bFunc = (DdNode *)Vec_PtrEntry( vBdds, Aig_ObjId(pObj) ); if ( bFunc != NULL ) return bFunc; assert( Aig_ObjIsNode(pObj) ); bBdd0 = Llb_ManComputeIndCase_rec( p, Aig_ObjFanin0(pObj), dd, vBdds ); bBdd1 = Llb_ManComputeIndCase_rec( p, Aig_ObjFanin1(pObj), dd, vBdds ); bBdd0 = Cudd_NotCond( bBdd0, Aig_ObjFaninC0(pObj) ); bBdd1 = Cudd_NotCond( bBdd1, Aig_ObjFaninC1(pObj) ); bFunc = Cudd_bddAnd( dd, bBdd0, bBdd1 ); Cudd_Ref( bFunc ); Vec_PtrWriteEntry( vBdds, Aig_ObjId(pObj), bFunc ); return bFunc; }
/**Function************************************************************* Synopsis [Create cube with singleton variables.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ DdNode * Llb_NonlinCreateCube1( Llb_Mgr_t * p, Llb_Prt_t * pPart ) { DdNode * bCube, * bTemp; Llb_Var_t * pVar; int i, TimeStop; TimeStop = p->dd->TimeStop; p->dd->TimeStop = 0; bCube = Cudd_ReadOne(p->dd); Cudd_Ref( bCube ); Llb_PartForEachVar( p, pPart, pVar, i ) { assert( Vec_IntSize(pVar->vParts) > 0 ); if ( Vec_IntSize(pVar->vParts) != 1 ) continue; assert( Vec_IntEntry(pVar->vParts, 0) == pPart->iPart ); bCube = Cudd_bddAnd( p->dd, bTemp = bCube, Cudd_bddIthVar(p->dd, pVar->iVar) ); Cudd_Ref( bCube ); Cudd_RecursiveDeref( p->dd, bTemp ); }
/* formula for assignment: pc ^ var' <=> expr ^ pc' ^ same(pc, var) */ DdNode* bdd_mk_assign(DdManager *m, pos* postab, cfg_node* host, int proc) { DdNode* tmp1 = Cudd_bddIthVar(m, symtab_lookup(postab->vars_, host->node->name)); DdNode* tmp2 = bdd_expr(m, postab->vars, host->node->children[EXPR]); DdNode* ret = Cudd_bddXnor(m, tmp1, tmp2); Cudd_Ref(ret); /* encode assignment with XNOR */ Cudd_RecursiveDeref(m, tmp2); ret = bdd_encode_pc(m, ret, postab->pc, postab->pc_size, proc, host->node->id); /* encode program counter */ tmp1 = bdd_same(m, postab, symtab_lookup(postab->vars, host->node->name), proc); /* encode unchanging variables */ tmp2 = ret; ret = Cudd_bddAnd(m, tmp1, tmp2); Cudd_Ref(ret); Cudd_RecursiveDeref(m, tmp1); Cudd_RecursiveDeref(m, tmp2); return ret; }
/** * @brief Basic BDD test. * @return 0 if successful; -1 otherwise. */ static int testBdd(int verbosity) { DdManager *dd; DdNode *f, *var, *tmp; int i, ret; dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); if (!dd) { if (verbosity) { printf("initialization failed\n"); } return -1; } if (verbosity) { printf("Started CUDD version "); Cudd_PrintVersion(stdout); } f = Cudd_ReadOne(dd); Cudd_Ref(f); for (i = 3; i >= 0; i--) { var = Cudd_bddIthVar(dd, i); tmp = Cudd_bddAnd(dd, Cudd_Not(var), f); if (!tmp) { if (verbosity) { printf("computation failed\n"); } return -1; } Cudd_Ref(tmp); Cudd_RecursiveDeref(dd, f); f = tmp; } if (verbosity) { Cudd_bddPrintCover(dd, f, f); } Cudd_RecursiveDeref(dd, f); ret = Cudd_CheckZeroRef(dd); if (ret != 0 && verbosity) { printf("%d unexpected non-zero references\n", ret); } Cudd_Quit(dd); return 0; }
/**Function************************************************************* Synopsis [Recompute the image.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Extra_bddImageCompute_rec( Extra_ImageTree_t * pTree, Extra_ImageNode_t * pNode ) { DdManager * dd = pNode->dd; DdNode * bTemp; int nNodes; // trivial case if ( pNode->pNode1 == NULL ) { if ( pNode->bCube ) { pNode->bImage = Cudd_bddExistAbstract( dd, bTemp = pNode->bImage, pNode->bCube ); Cudd_Ref( pNode->bImage ); Cudd_RecursiveDeref( dd, bTemp ); } return; } // compute the children if ( pNode->pNode1 ) Extra_bddImageCompute_rec( pTree, pNode->pNode1 ); if ( pNode->pNode2 ) Extra_bddImageCompute_rec( pTree, pNode->pNode2 ); // clean the old image if ( pNode->bImage ) Cudd_RecursiveDeref( dd, pNode->bImage ); pNode->bImage = NULL; // compute the new image if ( pNode->bCube ) pNode->bImage = Cudd_bddAndAbstract( dd, pNode->pNode1->bImage, pNode->pNode2->bImage, pNode->bCube ); else pNode->bImage = Cudd_bddAnd( dd, pNode->pNode1->bImage, pNode->pNode2->bImage ); Cudd_Ref( pNode->bImage ); if ( pTree->fVerbose ) { nNodes = Cudd_DagSize( pNode->bImage ); if ( pTree->nNodesMax < nNodes ) pTree->nNodesMax = nNodes; } }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Computes the initial state and sets up the variable map.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ DdNode * Abc_NtkInitStateVarMap( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbose ) { DdNode ** pbVarsX, ** pbVarsY; DdNode * bTemp, * bProd, * bVar; Abc_Obj_t * pLatch; int i; // set the variable mapping for Cudd_bddVarMap() pbVarsX = ABC_ALLOC( DdNode *, dd->size ); pbVarsY = ABC_ALLOC( DdNode *, dd->size ); bProd = b1; Cudd_Ref( bProd ); Abc_NtkForEachLatch( pNtk, pLatch, i ) { pbVarsX[i] = dd->vars[ Abc_NtkPiNum(pNtk) + i ]; pbVarsY[i] = dd->vars[ Abc_NtkCiNum(pNtk) + i ]; // get the initial value of the latch bVar = Cudd_NotCond( pbVarsX[i], !Abc_LatchIsInit1(pLatch) ); bProd = Cudd_bddAnd( dd, bTemp = bProd, bVar ); Cudd_Ref( bProd ); Cudd_RecursiveDeref( dd, bTemp ); }
DdNode * DdGate::gateFuncElem(DdManager * pDdManager, DdNode * pa, DdNode * pb){ switch(__gate){ case AND: return Cudd_bddAnd(pDdManager, pa, pb); case NAND: return Cudd_bddNand(pDdManager, pa, pb); case OR: return Cudd_bddOr(pDdManager, pa, pb); case NOR: return Cudd_bddNor(pDdManager, pa, pb); case XOR: return Cudd_bddXor(pDdManager, pa, pb); case XNOR: return Cudd_bddXnor(pDdManager, pa, pb); case NOT: return Cudd_bddNand(pDdManager, pa, pa); default: return NULL; } }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ DdNode * Abc_MvReadCube( DdManager * dd, char * pLine, int nVars ) { DdNode * bCube, * bVar, * bTemp; int i; bCube = Cudd_ReadOne(dd); Cudd_Ref( bCube ); for ( i = 0; i < nVars; i++ ) { if ( pLine[i] == '-' ) continue; else if ( pLine[i] == '0' ) // 0 bVar = Cudd_Not( Cudd_bddIthVar(dd, 29-i) ); else if ( pLine[i] == '1' ) // 1 bVar = Cudd_bddIthVar(dd, 29-i); else assert(0); bCube = Cudd_bddAnd( dd, bTemp = bCube, bVar ); Cudd_Ref( bCube ); Cudd_RecursiveDeref( dd, bTemp ); } Cudd_Deref( bCube ); return bCube; }
/**Function************************************************************* Synopsis [Derive BDD of the characteristic function.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ DdNode * Abc_ResBuildBdd( Abc_Ntk_t * pNtk, DdManager * dd ) { Vec_Ptr_t * vNodes, * vBdds, * vLocals; Abc_Obj_t * pObj, * pFanin; DdNode * bFunc, * bPart, * bTemp, * bVar; int i, k; assert( Abc_NtkIsSopLogic(pNtk) ); assert( Abc_NtkCoNum(pNtk) <= 3 ); vBdds = Vec_PtrStart( Abc_NtkObjNumMax(pNtk) ); Abc_NtkForEachCi( pNtk, pObj, i ) Vec_PtrWriteEntry( vBdds, Abc_ObjId(pObj), Cudd_bddIthVar(dd, i) ); // create internal node BDDs vNodes = Abc_NtkDfs( pNtk, 0 ); vLocals = Vec_PtrAlloc( 6 ); Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i ) { if ( Abc_ObjFaninNum(pObj) == 0 ) { bFunc = Cudd_NotCond( Cudd_ReadOne(dd), Abc_SopIsConst0((char *)pObj->pData) ); Cudd_Ref( bFunc ); Vec_PtrWriteEntry( vBdds, Abc_ObjId(pObj), bFunc ); continue; } Vec_PtrClear( vLocals ); Abc_ObjForEachFanin( pObj, pFanin, k ) Vec_PtrPush( vLocals, Vec_PtrEntry(vBdds, Abc_ObjId(pFanin)) ); bFunc = Abc_ConvertSopToBdd( dd, (char *)pObj->pData, (DdNode **)Vec_PtrArray(vLocals) ); Cudd_Ref( bFunc ); Vec_PtrWriteEntry( vBdds, Abc_ObjId(pObj), bFunc ); } Vec_PtrFree( vLocals ); // create char function bFunc = Cudd_ReadOne( dd ); Cudd_Ref( bFunc ); Abc_NtkForEachCo( pNtk, pObj, i ) { bVar = Cudd_bddIthVar( dd, i + Abc_NtkCiNum(pNtk) ); bTemp = (DdNode *)Vec_PtrEntry( vBdds, Abc_ObjFaninId0(pObj) ); bPart = Cudd_bddXnor( dd, bTemp, bVar ); Cudd_Ref( bPart ); bFunc = Cudd_bddAnd( dd, bTemp = bFunc, bPart ); Cudd_Ref( bFunc ); Cudd_RecursiveDeref( dd, bTemp ); Cudd_RecursiveDeref( dd, bPart ); }
/**Function************************************************************* Synopsis [Recursively derives the truth table for the cut.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ DdNode * Fpga_TruthsCutBdd_rec( DdManager * dd, Fpga_Cut_t * pCut, Fpga_NodeVec_t * vVisited ) { DdNode * bFunc, * bFunc0, * bFunc1; assert( !Fpga_IsComplement(pCut) ); // if the cut is visited, return the result if ( pCut->uSign ) return (DdNode *)pCut->uSign; // compute the functions of the children bFunc0 = Fpga_TruthsCutBdd_rec( dd, Fpga_CutRegular(pCut->pOne), vVisited ); Cudd_Ref( bFunc0 ); bFunc0 = Cudd_NotCond( bFunc0, Fpga_CutIsComplement(pCut->pOne) ); bFunc1 = Fpga_TruthsCutBdd_rec( dd, Fpga_CutRegular(pCut->pTwo), vVisited ); Cudd_Ref( bFunc1 ); bFunc1 = Cudd_NotCond( bFunc1, Fpga_CutIsComplement(pCut->pTwo) ); // get the function of the cut bFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( bFunc ); bFunc = Cudd_NotCond( bFunc, pCut->Phase ); Cudd_RecursiveDeref( dd, bFunc0 ); Cudd_RecursiveDeref( dd, bFunc1 ); assert( pCut->uSign == 0 ); pCut->uSign = (unsigned)bFunc; // add this cut to the visited list Fpga_NodeVecPush( vVisited, (Fpga_Node_t *)pCut ); return bFunc; }
/**Function******************************************************************** Synopsis [Checks the possibility of two variables being symmetric.] Description [Returns 0 if vars are not symmetric. Return 1 if vars can be symmetric.] SideEffects [] SeeAlso [] ******************************************************************************/ int Extra_bddCheckVarsSymmetric( DdManager * dd, /* the DD manager */ DdNode * bF, int iVar1, int iVar2) { DdNode * bVars; int Res; // return 1; assert( iVar1 != iVar2 ); assert( iVar1 < dd->size ); assert( iVar2 < dd->size ); bVars = Cudd_bddAnd( dd, dd->vars[iVar1], dd->vars[iVar2] ); Cudd_Ref( bVars ); Res = (int)( extraBddCheckVarsSymmetric( dd, bF, bVars ) == b1 ); Cudd_RecursiveDeref( dd, bVars ); return Res; } /* end of Extra_bddCheckVarsSymmetric */
/**Function******************************************************************** Synopsis [Selects pairs from R using a priority function.] Description [Selects pairs from a relation R(x,y) (given as a BDD) in such a way that a given x appears in one pair only. Uses a priority function to determine which y should be paired to a given x. Cudd_PrioritySelect returns a pointer to the selected function if successful; NULL otherwise. Three of the arguments--x, y, and z--are vectors of BDD variables. The first two are the variables on which R depends. The third vectore is a vector of auxiliary variables, used during the computation. This vector is optional. If a NULL value is passed instead, Cudd_PrioritySelect will create the working variables on the fly. The sizes of x and y (and z if it is not NULL) should equal n. The priority function Pi can be passed as a BDD, or can be built by Cudd_PrioritySelect. If NULL is passed instead of a DdNode *, parameter Pifunc is used by Cudd_PrioritySelect to build a BDD for the priority function. (Pifunc is a pointer to a C function.) If Pi is not NULL, then Pifunc is ignored. Pifunc should have the same interface as the standard priority functions (e.g., Cudd_Dxygtdxz). Cudd_PrioritySelect and Cudd_CProjection can sometimes be used interchangeably. Specifically, calling Cudd_PrioritySelect with Cudd_Xgty as Pifunc produces the same result as calling Cudd_CProjection with the all-zero minterm as reference minterm. However, depending on the application, one or the other may be preferable: <ul> <li> When extracting representatives from an equivalence relation, Cudd_CProjection has the advantage of nor requiring the auxiliary variables. <li> When computing matchings in general bipartite graphs, Cudd_PrioritySelect normally obtains better results because it can use more powerful matching schemes (e.g., Cudd_Dxygtdxz). </ul> ] SideEffects [If called with z == NULL, will create new variables in the manager.] SeeAlso [Cudd_Dxygtdxz Cudd_Dxygtdyz Cudd_Xgty Cudd_bddAdjPermuteX Cudd_CProjection] ******************************************************************************/ DdNode * Cudd_PrioritySelect( DdManager * dd /* manager */, DdNode * R /* BDD of the relation */, DdNode ** x /* array of x variables */, DdNode ** y /* array of y variables */, DdNode ** z /* array of z variables (optional: may be NULL) */, DdNode * Pi /* BDD of the priority function (optional: may be NULL) */, int n /* size of x, y, and z */, DdNode * (*Pifunc)(DdManager *, int, DdNode **, DdNode **, DdNode **) /* function used to build Pi if it is NULL */) { DdNode *res = NULL; DdNode *zcube = NULL; DdNode *Rxz, *Q; int createdZ = 0; int createdPi = 0; int i; /* Create z variables if needed. */ if (z == NULL) { if (Pi != NULL) return(NULL); z = ALLOC(DdNode *,n); if (z == NULL) { dd->errorCode = CUDD_MEMORY_OUT; return(NULL); } createdZ = 1; for (i = 0; i < n; i++) { if (dd->size >= (int) CUDD_MAXINDEX - 1) goto endgame; z[i] = cuddUniqueInter(dd,dd->size,dd->one,Cudd_Not(dd->one)); if (z[i] == NULL) goto endgame; } } /* Create priority function BDD if needed. */ if (Pi == NULL) { Pi = Pifunc(dd,n,x,y,z); if (Pi == NULL) goto endgame; createdPi = 1; cuddRef(Pi); } /* Initialize abstraction cube. */ zcube = DD_ONE(dd); cuddRef(zcube); for (i = n - 1; i >= 0; i--) { DdNode *tmpp; tmpp = Cudd_bddAnd(dd,z[i],zcube); if (tmpp == NULL) goto endgame; cuddRef(tmpp); Cudd_RecursiveDeref(dd,zcube); zcube = tmpp; } /* Compute subset of (x,y) pairs. */ Rxz = Cudd_bddSwapVariables(dd,R,y,z,n); if (Rxz == NULL) goto endgame; cuddRef(Rxz); Q = Cudd_bddAndAbstract(dd,Rxz,Pi,zcube); if (Q == NULL) { Cudd_RecursiveDeref(dd,Rxz); goto endgame; } cuddRef(Q); Cudd_RecursiveDeref(dd,Rxz); res = Cudd_bddAnd(dd,R,Cudd_Not(Q)); if (res == NULL) { Cudd_RecursiveDeref(dd,Q); goto endgame; } cuddRef(res); Cudd_RecursiveDeref(dd,Q); endgame: if (zcube != NULL) Cudd_RecursiveDeref(dd,zcube); if (createdZ) { FREE(z); } if (createdPi) { Cudd_RecursiveDeref(dd,Pi); } if (res != NULL) cuddDeref(res); return(res); } /* Cudd_PrioritySelect */