/**Function************************************************************* Synopsis [Writes reached state BDD into a BLIF file.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Llb_ManDumpReached( DdManager * ddG, DdNode * bReached, char * pModel, char * pFileName ) { FILE * pFile; Vec_Ptr_t * vNamesIn, * vNamesOut; char * pName; int i, nDigits; // reorder the BDD Cudd_ReduceHeap( ddG, CUDD_REORDER_SYMM_SIFT, 1 ); // create input names nDigits = Extra_Base10Log( Cudd_ReadSize(ddG) ); vNamesIn = Vec_PtrAlloc( Cudd_ReadSize(ddG) ); for ( i = 0; i < Cudd_ReadSize(ddG); i++ ) { pName = Llb_ManGetDummyName( "ff", i, nDigits ); Vec_PtrPush( vNamesIn, Extra_UtilStrsav(pName) ); } // create output names vNamesOut = Vec_PtrAlloc( 1 ); Vec_PtrPush( vNamesOut, Extra_UtilStrsav("Reached") ); // write the file pFile = fopen( pFileName, "wb" ); Cudd_DumpBlif( ddG, 1, &bReached, (char **)Vec_PtrArray(vNamesIn), (char **)Vec_PtrArray(vNamesOut), pModel, pFile, 0 ); fclose( pFile ); // cleanup Vec_PtrForEachEntry( char *, vNamesIn, pName, i ) ABC_FREE( pName ); Vec_PtrForEachEntry( char *, vNamesOut, pName, i ) ABC_FREE( pName ); Vec_PtrFree( vNamesIn ); Vec_PtrFree( vNamesOut ); }
/**Function************************************************************* Synopsis [Computes supports of the partitions.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Ptr_t * Llb_ImgSupports( Aig_Man_t * p, Vec_Ptr_t * vDdMans, Vec_Int_t * vStart, Vec_Int_t * vStop, int fAddPis, int fVerbose ) { Vec_Ptr_t * vSupps; Vec_Int_t * vOne; Aig_Obj_t * pObj; DdManager * dd; DdNode * bSupp, * bTemp; int i, Entry, nSize; nSize = Cudd_ReadSize( (DdManager *)Vec_PtrEntry( vDdMans, 0 ) ); vSupps = Vec_PtrAlloc( 100 ); // create initial vOne = Vec_IntStart( nSize ); Vec_IntForEachEntry( vStart, Entry, i ) Vec_IntWriteEntry( vOne, Entry, 1 ); Vec_PtrPush( vSupps, vOne ); // create intermediate Vec_PtrForEachEntry( DdManager *, vDdMans, dd, i ) { vOne = Vec_IntStart( nSize ); bSupp = Cudd_Support( dd, dd->bFunc ); Cudd_Ref( bSupp ); for ( bTemp = bSupp; bTemp != Cudd_ReadOne(dd); bTemp = cuddT(bTemp) ) Vec_IntWriteEntry( vOne, bTemp->index, 1 ); Cudd_RecursiveDeref( dd, bSupp ); Vec_PtrPush( vSupps, vOne ); }
/**Function******************************************************************** Synopsis [Reads the variable group tree from a file.] Description [Reads the variable group tree from a file. Returns 1 if successful; 0 otherwise.] SideEffects [None] SeeAlso [] *****************************************************************************/ static int ntrReadTree( DdManager * dd, char * treefile, int nvars) { FILE *fp; MtrNode *root; if (treefile == NULL) { return(1); } if ((fp = fopen(treefile,"r")) == NULL) { (void) fprintf(stderr,"Unable to open %s\n",treefile); return(0); } root = Mtr_ReadGroups(fp,ddMax(Cudd_ReadSize(dd),nvars)); if (root == NULL) { return(0); } Cudd_SetTree(dd,root); return(1); } /* end of ntrReadTree */
void BddBuilder::dotDumpC(DdNode ** ddNodes,int& number_of_diff_output,char** diff_output){ char filename[128]; DdNode * dumpdd[1]; char * dumpname[1]; int res; int * index_of_diff_output; int j=0; index_of_diff_output = new int[__outputWireCnt]; for(int i=0 ; i<__outputWireCnt ; ++i){ if(ddNodes[i] != NULL){ number_of_diff_output++; index_of_diff_output[j++] = i; printf("%s\n",__ppOutputNodesNames[i]); sprintf(filename, "./dotdump/dumpC_%s.dot", __ppOutputNodesNames[i]); FILE * fp = fopen(filename, "w"); dumpdd[0] = ddNodes[i]; dumpname[0] = __ppOutputNodesNames[i]; res = Cudd_DumpDot(__pddManager, 1, dumpdd, __ppInputNodesNames, dumpname, fp); fclose(fp); sprintf(filename, "./factored/dumpC_factored_%s", __ppOutputNodesNames[i]); fp = fopen(filename, "w"); Cudd_DumpFactoredForm(__pddManager, 1, dumpdd, __ppInputNodesNames, dumpname, fp); fclose(fp); printf("Factored form(Boolean equation) written : %s\n", filename); //Cudd_PrintDebug(__pddManager, dumpdd[0], Cudd_ReadSize(__pddManager), 4); sprintf(filename, "./sop/%s.sop", __ppOutputNodesNames[i]); FILE * fp_sop = fopen(filename, "w"); FILE * tmp; FILE* debug = fopen("debug.txt","w"); printf("%s's SOP:\n", __ppOutputNodesNames[i]); Cudd_bddPrintCover(__pddManager, dumpdd[0], dumpdd[0]); //Cudd_PrintMinterm(__pddManager,dumpdd[0]); tmp = Cudd_ReadStdout(__pddManager); Cudd_SetStdout(__pddManager, fp_sop); Cudd_bddPrintCover(__pddManager, dumpdd[0], dumpdd[0]); //Cudd_PrintMinterm(__pddManager,dumpdd[0]); //fprintf(fp_sop,"\n"); Cudd_SetStdout(__pddManager, debug); Cudd_PrintDebug(__pddManager,dumpdd[0],Cudd_ReadSize(__pddManager),4); Cudd_SetStdout(__pddManager, tmp); fseek(fp_sop,-2,SEEK_END); //fputc(0,fp_so; fclose(fp_sop); printf("SOP file written : %s\n\n", filename); /*printf("Quine-Mccluskey for %s:\n", __ppOutputNodesNames[i]); QuineMccluskey quine(filename); printf("Quine-Mccluskey for %s Done.\n", __ppOutputNodesNames[i]); */ //Cudd_PrintMinterm(__pddManager, dumpdd[0]); if(res == 1) printf("DOT dump for C's %s completed.\n", __ppOutputNodesNames[i]); else printf("DOT dump for C's %s failed.\n", __ppOutputNodesNames[i]); } else printf("DOT dump for C's %s not executed: A = B\n", __ppOutputNodesNames[i]); } for(int i=0;i<number_of_diff_output;i++){ strcpy(diff_output[i],__ppOutputNodesNames[index_of_diff_output[i]]); } delete index_of_diff_output; }
/**Function******************************************************************** Synopsis [Main program for ntr.] Description [Main program for ntr. Performs initialization. Reads command line options and network(s). Builds BDDs with reordering, and optionally does reachability analysis. Prints stats.] SideEffects [None] SeeAlso [] ******************************************************************************/ int main( int argc, char ** argv) { NtrOptions *option; /* options */ FILE *fp1; /* first network file pointer */ BnetNetwork *net1 = NULL; /* first network */ FILE *fp2; /* second network file pointer */ BnetNetwork *net2 = NULL; /* second network */ DdManager *dd; /* pointer to DD manager */ int exitval; /* return value of Cudd_CheckZeroRef */ int ok; /* overall return value from main() */ int result; /* stores the return value of functions */ BnetNode *node; /* auxiliary pointer to network node */ int i; /* loop index */ int j; /* loop index */ double *signatures; /* array of signatures */ int pr; /* verbosity level */ int reencoded; /* linear transformations attempted */ /* Initialize. */ option = mainInit(); ntrReadOptions(argc,argv,option); pr = option->verb; reencoded = option->reordering == CUDD_REORDER_LINEAR || option->reordering == CUDD_REORDER_LINEAR_CONVERGE || option->autoMethod == CUDD_REORDER_LINEAR || option->autoMethod == CUDD_REORDER_LINEAR_CONVERGE; /* Currently traversal requires global BDDs. Override whatever ** was specified for locGlob. */ if (option->traverse == TRUE || option->envelope == TRUE || option->scc == TRUE) { option->locGlob = BNET_GLOBAL_DD; } /* Read the first network... */ fp1 = open_file(option->file1, "r"); net1 = Bnet_ReadNetwork(fp1,pr); (void) fclose(fp1); if (net1 == NULL) { (void) fprintf(stderr,"Syntax error in %s.\n",option->file1); exit(2); } /* ... and optionally echo it to the standard output. */ if (pr > 2) { Bnet_PrintNetwork(net1); } /* Read the second network... */ if (option->verify == TRUE || option->second == TRUE || option->clip > 0.0 || option->dontcares) { fp2 = open_file(option->file2, "r"); net2 = Bnet_ReadNetwork(fp2,pr); (void) fclose(fp2); if (net2 == NULL) { (void) fprintf(stderr,"Syntax error in %s.\n",option->file2); exit(2); } /* ... and optionally echo it to the standard output. */ if (pr > 2) { Bnet_PrintNetwork(net2); } } /* Initialize manager. We start with 0 variables, because ** Ntr_buildDDs will create new variables rather than using ** whatever already exists. */ dd = startCudd(option,net1->ninputs); if (dd == NULL) { exit(2); } /* Build the BDDs for the nodes of the first network. */ result = Ntr_buildDDs(net1,dd,option,NULL); if (result == 0) { exit(2); } /* Build the BDDs for the nodes of the second network if requested. */ if (option->verify == TRUE || option->second == TRUE || option->clip > 0.0 || option->dontcares == TRUE) { char *nodesave = option->node; option->node = NULL; result = Ntr_buildDDs(net2,dd,option,net1); option->node = nodesave; if (result == 0) { exit(2); } } if (option->noBuild == TRUE) { Bnet_FreeNetwork(net1); if (option->verify == TRUE || option->second == TRUE || option->clip > 0.0) { Bnet_FreeNetwork(net2); } freeOption(option); exit(0); } if (option->locGlob != BNET_LOCAL_DD) { /* Print the order before the final reordering. */ (void) printf("Order before final reordering\n"); result = Bnet_PrintOrder(net1,dd); if (result == 0) exit(2); } /* Perform final reordering */ if (option->zddtest == FALSE) { result = reorder(net1,dd,option); if (result == 0) exit(2); /* Print final order. */ if ((option->reordering != CUDD_REORDER_NONE || option->gaOnOff) && option->locGlob != BNET_LOCAL_DD) { (void) printf("New order\n"); result = Bnet_PrintOrder(net1,dd); if (result == 0) exit(2); } /* Print the re-encoded inputs. */ if (pr >= 1 && reencoded == 1) { for (i = 0; i < net1->npis; i++) { if (!st_lookup(net1->hash,net1->inputs[i],&node)) { exit(2); } (void) fprintf(stdout,"%s:",node->name); Cudd_PrintDebug(dd,node->dd,Cudd_ReadSize(dd),pr); } for (i = 0; i < net1->nlatches; i++) { if (!st_lookup(net1->hash,net1->latches[i][1],&node)) { exit(2); } (void) fprintf(stdout,"%s:",node->name); Cudd_PrintDebug(dd,node->dd,Cudd_ReadSize(dd),pr); } if (pr >= 3) { result = Cudd_PrintLinear(dd); if (result == 0) exit(2); } } } /* Verify (combinational) equivalence. */ if (option->verify == TRUE) { result = Ntr_VerifyEquivalence(dd,net1,net2,option); if (result == 0) { (void) printf("Verification abnormally terminated\n"); exit(2); } else if (result == -1) { (void) printf("Combinational verification failed\n"); } else { (void) printf("Verification succeeded\n"); } } /* Traverse if requested and if the circuit is sequential. */ result = Ntr_Trav(dd,net1,option); if (result == 0) exit(2); /* Traverse with trasitive closure. */ result = Ntr_ClosureTrav(dd,net1,option); if (result == 0) exit(2); /* Compute outer envelope if requested and if the circuit is sequential. */ if (option->envelope == TRUE && net1->nlatches > 0) { NtrPartTR *T; T = Ntr_buildTR(dd,net1,option,option->image); result = Ntr_Envelope(dd,T,NULL,option); Ntr_freeTR(dd,T); } /* Compute SCCs if requested and if the circuit is sequential. */ result = Ntr_SCC(dd,net1,option); if (result == 0) exit(2); /* Test Constrain Decomposition. */ if (option->partition == TRUE && net1->nlatches > 0) { NtrPartTR *T; DdNode *product; DdNode **decomp; int sharingSize; T = Ntr_buildTR(dd,net1,option,NTR_IMAGE_MONO); decomp = Cudd_bddConstrainDecomp(dd,T->part[0]); if (decomp == NULL) exit(2); sharingSize = Cudd_SharingSize(decomp, Cudd_ReadSize(dd)); (void) fprintf(stdout, "Decomposition Size: %d components %d nodes\n", Cudd_ReadSize(dd), sharingSize); product = Cudd_ReadOne(dd); Cudd_Ref(product); for (i = 0; i < Cudd_ReadSize(dd); i++) { DdNode *intermediate = Cudd_bddAnd(dd, product, decomp[i]); if (intermediate == NULL) { exit(2); } Cudd_Ref(intermediate); Cudd_IterDerefBdd(dd, product); product = intermediate; } if (product != T->part[0]) exit(2); Cudd_IterDerefBdd(dd, product); for (i = 0; i < Cudd_ReadSize(dd); i++) { Cudd_IterDerefBdd(dd, decomp[i]); } FREE(decomp); Ntr_freeTR(dd,T); } /* Test char-to-vect conversion. */ result = Ntr_TestCharToVect(dd,net1,option); if (result == 0) exit(2); /* Test extraction of two-literal clauses. */ result = Ntr_TestTwoLiteralClauses(dd,net1,option); if (result == 0) exit(2); /* Test BDD minimization functions. */ result = Ntr_TestMinimization(dd,net1,net2,option); if (result == 0) exit(2); /* Test density-related functions. */ result = Ntr_TestDensity(dd,net1,option); if (result == 0) exit(2); /* Test decomposition functions. */ result = Ntr_TestDecomp(dd,net1,option); if (result == 0) exit(2); /* Test cofactor estimation functions. */ result = Ntr_TestCofactorEstimate(dd,net1,option); if (result == 0) exit(2); /* Test BDD clipping functions. */ result = Ntr_TestClipping(dd,net1,net2,option); if (result == 0) exit(2); /* Test BDD equivalence and containment under DC functions. */ result = Ntr_TestEquivAndContain(dd,net1,net2,option); if (result == 0) exit(2); /* Test BDD Cudd_bddClosestCube. */ result = Ntr_TestClosestCube(dd,net1,option); if (result == 0) exit(2); /* Test ZDDs if requested. */ if (option->stateOnly == FALSE && option->zddtest == TRUE) { result = Ntr_testZDD(dd,net1,option); if (result == 0) (void) fprintf(stdout,"ZDD test failed.\n"); result = Ntr_testISOP(dd,net1,option); if (result == 0) (void) fprintf(stdout,"ISOP test failed.\n"); } /* Compute maximum flow if requested and if the circuit is sequential. */ if (option->maxflow == TRUE && net1->nlatches > 0) { result = Ntr_maxflow(dd,net1,option); if (result == 0) (void) fprintf(stdout,"Maxflow computation failed.\n"); } /* Compute shortest paths if requested and if the circuit is sequential. */ if (option->shortPath != NTR_SHORT_NONE && net1->nlatches > 0) { result = Ntr_ShortestPaths(dd,net1,option); if (result == 0) (void) fprintf(stdout,"Shortest paths computation failed.\n"); } /* Compute output signatures if so requested. */ if (option->signatures) { (void) printf("Positive cofactor measures\n"); for (i = 0; i < net1->noutputs; i++) { if (!st_lookup(net1->hash,net1->outputs[i],&node)) { exit(2); } signatures = Cudd_CofMinterm(dd, node->dd); if (signatures) { (void) printf("%s:\n", node->name); for (j = 0; j < Cudd_ReadSize(dd); j++) { if((j%5 == 0)&&i) (void) printf("\n"); (void) printf("%5d: %-#8.4g ", j, signatures[j]); } (void) printf("\n"); FREE(signatures); } else { (void) printf("Signature computation failed.\n"); } } } /* Dump BDDs if so requested. */ if (option->bdddump && option->second == FALSE && option->density == FALSE && option->decomp == FALSE && option->cofest == FALSE && option->clip < 0.0 && option->scc == FALSE) { (void) printf("Dumping BDDs to %s\n", option->dumpfile); if (option->node != NULL) { if (!st_lookup(net1->hash,option->node,&node)) { exit(2); } result = Bnet_bddArrayDump(dd,net1,option->dumpfile,&(node->dd), &(node->name),1,option->dumpFmt); } else { result = Bnet_bddDump(dd, net1, option->dumpfile, option->dumpFmt, reencoded); } if (result != 1) { (void) printf("BDD dump failed.\n"); } } /* Print stats and clean up. */ if (pr >= 0) { result = Cudd_PrintInfo(dd,stdout); if (result != 1) { (void) printf("Cudd_PrintInfo failed.\n"); } } #if defined(DD_DEBUG) && !defined(DD_NO_DEATH_ROW) (void) fprintf(dd->err,"%d empty slots in death row\n", cuddTimesInDeathRow(dd,NULL)); #endif (void) printf("Final size: %ld\n", Cudd_ReadNodeCount(dd)); /* Dispose of node BDDs. */ node = net1->nodes; while (node != NULL) { if (node->dd != NULL && node->type != BNET_INPUT_NODE && node->type != BNET_PRESENT_STATE_NODE) { Cudd_IterDerefBdd(dd,node->dd); } node = node->next; } /* Dispose of network. */ Bnet_FreeNetwork(net1); /* Do the same cleanup for the second network if it was created. */ if (option->verify == TRUE || option->second == TRUE || option->clip > 0.0 || option->dontcares == TRUE) { node = net2->nodes; while (node != NULL) { if (node->dd != NULL && node->type != BNET_INPUT_NODE && node->type != BNET_PRESENT_STATE_NODE) { Cudd_IterDerefBdd(dd,node->dd); } node = node->next; } Bnet_FreeNetwork(net2); } /* Check reference counts: At this point we should have dereferenced ** everything we had, except in the case of re-encoding. */ exitval = Cudd_CheckZeroRef(dd); ok = exitval != 0; /* ok == 0 means O.K. */ if (exitval != 0) { (void) fflush(stdout); (void) fprintf(stderr, "%d non-zero DD reference counts after dereferencing\n", exitval); } #ifdef DD_DEBUG Cudd_CheckKeys(dd); #endif Cudd_Quit(dd); if (pr >= 0) (void) printf("total time = %s\n", util_print_time(util_cpu_time() - option->initialTime)); freeOption(option); if (pr >= 0) util_print_cpu_stats(stdout); #ifdef MNEMOSYNE mnem_writestats(); #endif exit(ok); /* NOTREACHED */ } /* end of main */