/**Function******************************************************************** Synopsis [Writes a blif file representing the argument BDDs.] Description [Writes a blif file representing the argument BDDs as a network of multiplexers. One multiplexer is written for each BDD node. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file system full, or an ADD with constants different from 0 and 1). Cudd_DumpBlif does not close the file: This is the caller responsibility. Cudd_DumpBlif uses a minimal unique subset of the hexadecimal address of a node as name for it. If the argument inames is non-null, it is assumed to hold the pointers to the names of the inputs. Similarly for onames.] SideEffects [None] SeeAlso [Cudd_DumpBlifBody Cudd_DumpDot Cudd_PrintDebug Cudd_DumpDDcal Cudd_DumpDaVinci Cudd_DumpFactoredForm] ******************************************************************************/ int Cudd_DumpBlif( DdManager * dd /* manager */, int n /* number of output nodes to be dumped */, DdNode ** f /* array of output nodes to be dumped */, char ** inames /* array of input names (or NULL) */, char ** onames /* array of output names (or NULL) */, char * mname /* model name (or NULL) */, FILE * fp /* pointer to the dump file */, int mv /* 0: blif, 1: blif-MV */) { DdNode *support = NULL; DdNode *scan; int *sorted = NULL; int nvars = dd->size; int retval; int i; /* Build a bit array with the support of f. */ sorted = ALLOC(int,nvars); if (sorted == NULL) { dd->errorCode = CUDD_MEMORY_OUT; goto failure; } for (i = 0; i < nvars; i++) sorted[i] = 0; /* Take the union of the supports of each output function. */ support = Cudd_VectorSupport(dd,f,n); if (support == NULL) goto failure; cuddRef(support); scan = support; while (!cuddIsConstant(scan)) { sorted[scan->index] = 1; scan = cuddT(scan); } Cudd_RecursiveDeref(dd,support); support = NULL; /* so that we do not try to free it in case of failure */ /* Write the header (.model .inputs .outputs). */ if (mname == NULL) { retval = fprintf(fp,".model DD\n.inputs"); } else { retval = fprintf(fp,".model %s\n.inputs",mname); } if (retval == EOF) { FREE(sorted); return(0); } /* Write the input list by scanning the support array. */ for (i = 0; i < nvars; i++) { if (sorted[i]) { if (inames == NULL) { retval = fprintf(fp," %d", i); } else { retval = fprintf(fp," %s", inames[i]); } if (retval == EOF) goto failure; } } FREE(sorted); sorted = NULL; /* Write the .output line. */ retval = fprintf(fp,"\n.outputs"); if (retval == EOF) goto failure; for (i = 0; i < n; i++) { if (onames == NULL) { retval = fprintf(fp," f%d", i); } else { retval = fprintf(fp," %s", onames[i]); } if (retval == EOF) goto failure; } retval = fprintf(fp,"\n"); if (retval == EOF) goto failure; retval = Cudd_DumpBlifBody(dd, n, f, inames, onames, fp, mv); if (retval == 0) goto failure; /* Write trailer and return. */ retval = fprintf(fp,".end\n"); if (retval == EOF) goto failure; return(1); failure: if (sorted != NULL) FREE(sorted); if (support != NULL) Cudd_RecursiveDeref(dd,support); return(0); } /* end of Cudd_DumpBlif */
static int DddmpCuddDdArrayStoreBlif ( DdManager *ddMgr /* IN: Manager */, int n /* IN: Number of output nodes to be dumped */, DdNode **f /* IN: Array of output nodes to be dumped */, char **inputNames /* IN: Array of input names (or NULL) */, char **outputNames /* IN: Array of output names (or NULL) */, char *modelName /* IN: Model name (or NULL) */, FILE *fp /* IN: Pointer to the dump file */ ) { DdNode *support = NULL; DdNode *scan; int *sorted = NULL; int nVars = ddMgr->size; int retValue; int i; /* Build a bit array with the support of f. */ sorted = ALLOC (int, nVars); if (sorted == NULL) { ddMgr->errorCode = CUDD_MEMORY_OUT; Dddmp_CheckAndGotoLabel (1, "Allocation Error.", failure); } for (i = 0; i < nVars; i++) { sorted[i] = 0; } /* Take the union of the supports of each output function. */ support = Cudd_VectorSupport(ddMgr,f,n); Dddmp_CheckAndGotoLabel (support==NULL, "Error in function Cudd_VectorSupport.", failure); cuddRef(support); scan = support; while (!cuddIsConstant(scan)) { sorted[scan->index] = 1; scan = cuddT(scan); } Cudd_RecursiveDeref(ddMgr,support); support = NULL; /* so that we do not try to free it in case of failure */ /* Write the header (.model .inputs .outputs). */ if (modelName == NULL) { retValue = fprintf(fp,".model DD\n.inputs"); } else { retValue = fprintf(fp,".model %s\n.inputs", modelName); } if (retValue == EOF) { return(0); } /* Write the input list by scanning the support array. */ for (i = 0; i < nVars; i++) { if (sorted[i]) { if (inputNames == NULL || (inputNames[i] == NULL)) { retValue = fprintf(fp," inNode%d", i); } else { retValue = fprintf(fp," %s", inputNames[i]); } Dddmp_CheckAndGotoLabel (retValue==EOF, "Error during file store.", failure); } } FREE(sorted); sorted = NULL; /* Write the .output line. */ retValue = fprintf(fp,"\n.outputs"); Dddmp_CheckAndGotoLabel (retValue==EOF, "Error during file store.", failure); for (i = 0; i < n; i++) { if (outputNames == NULL || (outputNames[i] == NULL)) { retValue = fprintf(fp," outNode%d", i); } else { retValue = fprintf(fp," %s", outputNames[i]); } Dddmp_CheckAndGotoLabel (retValue==EOF, "Error during file store.", failure); } retValue = fprintf(fp,"\n"); Dddmp_CheckAndGotoLabel (retValue==EOF, "Error during file store.", failure); retValue = DddmpCuddDdArrayStoreBlifBody(ddMgr, n, f, inputNames, outputNames, fp); Dddmp_CheckAndGotoLabel (retValue==0, "Error if function DddmpCuddDdArrayStoreBlifBody.", failure); /* Write trailer and return. */ retValue = fprintf (fp, ".end\n"); Dddmp_CheckAndGotoLabel (retValue==EOF, "Error during file store.", failure); return(1); failure: if (sorted != NULL) { FREE(sorted); } if (support != NULL) { Cudd_RecursiveDeref(ddMgr,support); } return(0); }