VIS

src/synth/synthWrite.c

Go to the documentation of this file.
00001 
00019 #include "synthInt.h"
00020 
00021 static char rcsid[] UNUSED = "$Id: synthWrite.c,v 1.43 2005/05/11 20:18:39 hhhan Exp $";
00022 
00023 /*---------------------------------------------------------------------------*/
00024 /* Constant declarations                                                     */
00025 /*---------------------------------------------------------------------------*/
00026 
00027 
00028 /*---------------------------------------------------------------------------*/
00029 /* Type declarations                                                         */
00030 /*---------------------------------------------------------------------------*/
00031 
00032 
00033 /*---------------------------------------------------------------------------*/
00034 /* Structure declarations                                                    */
00035 /*---------------------------------------------------------------------------*/
00036 
00048 typedef struct TruthTableLine {
00049   char *values;    /* string of 1, 0, and - */
00050   struct TruthTableLine *next; /* pointer to next table line */
00051 } TruthTableLine;
00052 
00053 
00054 /*---------------------------------------------------------------------------*/
00055 /* Variable declarations                                                     */
00056 /*---------------------------------------------------------------------------*/
00057 
00058 static  char            *DefaultPrefix = "_n";
00059 static  char            *InternalNodePrefix;
00060 static  st_table        *NodeNameTable; /* to keep all node names for
00061                                          * primary input, primary output 
00062                                          * latch input and output
00063                                          */
00064 
00067 /*---------------------------------------------------------------------------*/
00068 /* Static function prototypes                                                */
00069 /*---------------------------------------------------------------------------*/
00070 
00071 static void WriteMlBlif(Ntk_Network_t *net, bdd_manager *dd, MlTree *tree, FILE *fout, int no, bdd_node **ofuncs, int *oflags, int top_flag, int verbosity);
00072 static void WriteLeafMlBlif(Ntk_Network_t *net, bdd_manager *dd, MlTree *tree, FILE *fout, int no, bdd_node **ofuncs, int *oflags, int top_flag, int verbosity);
00073 static void WriteBlifBinary(bdd_manager *dd, bdd_node *node, char *name, FILE *fout, int *support);
00074 static void WriteEqnOfTree(FILE *fout, Ntk_Network_t *net, bdd_manager *dd, MlTree *tree, bdd_node **ofuncs);
00075 static int GetEqnOfTree(Ntk_Network_t *net, bdd_manager *dd, MlTree *top, MlTree *tree, char *eq, bdd_node **ofuncs);
00076 static void WriteMlTreeBlif(FILE *fout, Ntk_Network_t *net, bdd_manager *dd, MlTree *tree, bdd_node **ofuncs, int no, char *func_name, int ref);
00077 static void WriteMultiLevelBlif(FILE *fout, Ntk_Network_t *net, bdd_manager *dd, MlTree *tree, bdd_node **ofuncs, int no);
00078 static TruthTableLine * GetMultiLevelBlifRecur(Ntk_Network_t *net, bdd_manager *dd, MlTree *top, MlTree *tree, bdd_node **ofuncs, int no, st_table *table, int ni);
00079 static int GetMultiLevelNodes(Ntk_Network_t *net, bdd_manager *dd, MlTree *top, MlTree *tree, bdd_node **ofuncs, int no, st_table *table, int ni);
00080 static int GetLeafNodes(Ntk_Network_t *net, bdd_manager *dd, MlTree *tree, bdd_node **ofuncs, int no, st_table *table, int ni);
00081 static TruthTableLine * GetTautologyLine(int ni);
00082 static TruthTableLine * GetLeafLines(Ntk_Network_t *net, bdd_manager *dd, MlTree *tree, bdd_node **ofuncs, int no, st_table *table, int ni);
00083 static TruthTableLine * GetBlifBinary(TruthTableLine *line, bdd_manager *dd, bdd_node *node, char *values, int *support, int ni);
00084 static TruthTableLine * GetComplementOneLine(TruthTableLine *line, int ni, int flag);
00085 static TruthTableLine * GetComplementLines(TruthTableLine *lines, int ni, int flag);
00086 static TruthTableLine * GetAndLines(TruthTableLine *line1, TruthTableLine *line2, int ni, int flag);
00087 static bdd_node * GetDdNodeOfMlTree(MlTree *tree, int comp);
00088 static int GetMlTreeName(Ntk_Network_t *net, bdd_node **ofuncs, MlTree *tree, char *name);
00089 static char ** GetAllVarNameArray(bdd_manager *dd);
00090 
00094 /*---------------------------------------------------------------------------*/
00095 /* Definition of exported functions                                          */
00096 /*---------------------------------------------------------------------------*/
00097 
00098 
00099 /*---------------------------------------------------------------------------*/
00100 /* Definition of internal functions                                          */
00101 /*---------------------------------------------------------------------------*/
00102 
00103 
00117 int
00118 SynthStringCompare(char **a,
00119                    char **b)
00120 {
00121   char  *pa, *pb;
00122 
00123   pa = *a;
00124   pb = *b;
00125 
00126   if (*pa == '\0') {
00127     if (*pb == '\0')
00128       return(0);
00129     else
00130       return(-1);
00131   } else if (*pb == '\0')
00132     return(1);
00133   while (*pa != '\0' && *pb != '\0') {
00134     if (*pa > *pb)
00135       return(1);
00136     if (*pa < *pb)
00137       return(-1);
00138     pa++;
00139     pb++;
00140     if (*pa == '\0') {
00141       if (*pb == '\0')
00142         return(0);
00143       else
00144         return(-1);
00145     } else if (*pb == '\0')
00146       return(1);
00147   }
00148   return(0);
00149 }
00150 
00151 
00169 void
00170 SynthWriteBlifFile(Ntk_Network_t *net,
00171                    bdd_manager *dd,
00172                    MlTree **tree,
00173                    char *filename,
00174                    int no,
00175                    bdd_node **ofuncs,
00176                    int *initStates,
00177                    int ml_mode,
00178                    int verbosity)
00179 {
00180   FILE          *fout;
00181   int           i, j;
00182   int           *oflags;
00183   char          out_name[MAX_NAME_LEN], name[MAX_NAME_LEN];
00184   lsGen         gen;
00185   Ntk_Node_t    *node;
00186   char          **sorted_name;
00187   int           ni, po;
00188   int           polarity;
00189 
00190   fout = Cmd_FileOpen(filename, "w", NIL(char *), 0);
00191   if (!fout) {
00192     (void)fprintf(vis_stdout,
00193                   "** synth error: Error in opening file [%s]\n", filename);
00194     return;
00195   }
00196 
00197   fprintf(fout, ".model %s\n", Ntk_NetworkReadName(net));
00198   fprintf(fout, ".inputs");
00199 
00200   /* Write list of primary inputs sorted lexicographically. */
00201   ni = Ntk_NetworkReadNumPrimaryInputs(net);
00202   sorted_name = ALLOC(char *, ni * sizeof(char *));
00203   i = 0;
00204   Ntk_NetworkForEachPrimaryInput(net, gen, node) {
00205     sorted_name[i++] = Ntk_NodeReadName(node);
00206   }
00207   qsort(sorted_name, ni, sizeof(char *),
00208         (int (*)(const void *, const void *)) SynthStringCompare);
00209   for (i = 0; i < ni; i++)
00210     fprintf(fout," %s", sorted_name[i]);
00211   FREE(sorted_name);
00212 
00213   fprintf(fout, "\n");
00214   fprintf(fout, ".outputs");
00215 
00216   /* Write list of primary outputs sorted lexicographically. */
00217   po = Ntk_NetworkReadNumPrimaryOutputs(net);
00218   sorted_name = ALLOC(char *, po * sizeof(char *));
00219   i = 0;
00220   Ntk_NetworkForEachPrimaryOutput(net, gen, node) {
00221     sorted_name[i++] = Ntk_NodeReadName(node);
00222   }
00223   qsort(sorted_name, po, sizeof(char *),
00224         (int (*)(const void *, const void *))SynthStringCompare);
00225   for (i = 0; i < po; i++)
00226     fprintf(fout," %s", sorted_name[i]);
00227   FREE(sorted_name);
00228   fprintf(fout, "\n");
00229 
00230   /* Print list of latches. */
00231   i = 0;
00232   Ntk_NetworkForEachLatch(net, gen, node) {
00233     fprintf(fout,".latch %s", Ntk_NodeReadName(Ntk_LatchReadDataInput(node)));
00234     fprintf(fout, " %s", Ntk_NodeReadName(node));
00235     fprintf(fout, " %d\n", initStates[i]);
00236     i++;
00237   }
00238 
00239   oflags = ALLOC(int, no);
00240   (void)memset((void *)oflags, 0, no * sizeof(int));
00241   for (i = 0; i < no; i++) {
00242     if (!tree[i])
00243       continue;
00244     if (bdd_is_constant(tree[i]->node)) {
00245       if (tree[i]->comp) {
00246         for (j = 0; j < no; j++) {
00247           if (tree[i]->complement == ofuncs[j] && oflags[j] == 0) {
00248             sprintf(out_name, "%s", SynthGetIthOutputName(j));
00249             break;
00250           }
00251         }
00252       } else {
00253         for (j = 0; j < no; j++) {
00254           if (tree[i]->node == ofuncs[j] && oflags[j] == 0) {
00255             sprintf(out_name, "%s", SynthGetIthOutputName(j));
00256             break;
00257           }
00258         }
00259       }
00260       if (j == no)
00261         SynthGetInternalNodeName(out_name, tree[i]->id);
00262       else {
00263         if (oflags[j])
00264           continue;
00265         else
00266           oflags[j] = 1;
00267       }
00268       fprintf(fout, "\n.names %s\n", out_name);
00269       if (tree[i]->node == bdd_read_one(dd)) {
00270         if (tree[i]->comp)
00271           fprintf(fout, "0\n");
00272         else
00273           fprintf(fout, "1\n");
00274       } else {
00275         if (tree[i]->comp)
00276           fprintf(fout, "1\n");
00277         else
00278           fprintf(fout, "0\n");
00279       }
00280       continue;
00281     } else if (tree[i]->ref) {
00282       for (j = 0; j < no; j++) {
00283         if ((((tree[i]->comp == 0 && tree[i]->node == ofuncs[j]) ||
00284               (tree[i]->comp && tree[i]->complement == ofuncs[j]))) &&
00285             oflags[j] == 0) {
00286           sprintf(out_name, "%s", SynthGetIthOutputName(j));
00287           break;
00288         }
00289       }
00290       if (j == no)
00291         SynthGetInternalNodeName(out_name, tree[i]->id);
00292       else {
00293         if (oflags[j])
00294           continue;
00295         else
00296           oflags[j] = 1;
00297       }
00298       polarity = GetMlTreeName(net, ofuncs, tree[i], name);
00299       if (strcmp(out_name, name) == 0)
00300         SynthGetPrimaryNodeName(net, tree[i]->node, name);
00301       fprintf(fout, "\n.names %s %s\n", name, out_name);
00302       if (polarity == 0) {
00303         if (tree[i]->comp)
00304           fprintf(fout, "0 1\n");
00305         else
00306           fprintf(fout, "1 1\n");
00307       } else {
00308         if (tree[i]->comp)
00309           fprintf(fout, "1 1\n");
00310         else
00311           fprintf(fout, "0 1\n");
00312       }
00313       continue;
00314     }
00315     if (ml_mode == 0) {
00316       if (tree[i]->pi) {
00317         tree[i]->pi = 0;
00318         WriteMlBlif(net, dd, tree[i], fout, no, ofuncs, oflags, 1, verbosity);
00319         tree[i]->pi = 1;
00320       } else {
00321         WriteMlBlif(net, dd, tree[i], fout, no, ofuncs, oflags, 1, verbosity);
00322       }
00323     } else {
00324       for (j = 0; j < no; j++) {
00325         if (tree[i]->node == ofuncs[j]) {
00326           if (oflags[j])
00327             continue;
00328           else
00329             oflags[j] = 1;
00330           sprintf(out_name, "%s", SynthGetIthOutputName(j));
00331           break;
00332         }
00333       }
00334       if (j == no)
00335         SynthGetInternalNodeName(out_name, tree[i]->id);
00336       if (tree[i]->pi) {
00337         tree[i]->pi = 0;
00338         WriteMlTreeBlif(fout, net, dd, tree[i], ofuncs, no, out_name, 1);
00339         tree[i]->pi = 1;
00340       } else {
00341         WriteMlTreeBlif(fout, net, dd, tree[i], ofuncs, no, out_name, 1);
00342       }
00343     }
00344   }
00345   FREE(oflags);
00346 
00347   fprintf(fout, "\n.end\n");
00348   fclose(fout);
00349 }
00350 
00351 
00363 void
00364 SynthWriteEqnHeader(FILE *fout,
00365                   Ntk_Network_t *net,
00366                   bdd_manager *dd)
00367 {
00368   int           i;
00369   lsGen         gen;
00370   Ntk_Node_t    *node;
00371   char          **sorted_name;
00372   int           ni, po;
00373 
00374   /* Write list of primary inputs sorted lexicographically. */
00375   ni = Ntk_NetworkReadNumPrimaryInputs(net);
00376   sorted_name = ALLOC(char *, ni * sizeof(char *));
00377   i = 0;
00378   Ntk_NetworkForEachPrimaryInput(net, gen, node) {
00379     sorted_name[i++] = Ntk_NodeReadName(node);
00380   }
00381   qsort(sorted_name, ni, sizeof(char *),
00382         (int (*)(const void *, const void *))SynthStringCompare);
00383   fprintf(fout, "INORDER");
00384   for (i = 0; i < ni; i++)
00385     fprintf(fout," %s", sorted_name[i]);
00386   fprintf(fout, "\n");
00387   FREE(sorted_name);
00388 
00389   /* Write list of primary outputs sorted lexicographically. */
00390   po = Ntk_NetworkReadNumPrimaryOutputs(net);
00391   sorted_name = ALLOC(char *, po * sizeof(char *));
00392   i = 0;
00393   Ntk_NetworkForEachPrimaryOutput(net, gen, node) {
00394     sorted_name[i++] = Ntk_NodeReadName(node);
00395   }
00396   qsort(sorted_name, po, sizeof(char *),
00397         (int (*)(const void *, const void *))SynthStringCompare);
00398   fprintf(fout, "OUTORDER");
00399   for (i = 0; i < po; i++)
00400     fprintf(fout," %s", sorted_name[i]);
00401   fprintf(fout, "\n");
00402   FREE(sorted_name);
00403 }
00404 
00405 
00417 void
00418 SynthWriteEqn(FILE *fout,
00419               Ntk_Network_t *net,
00420               bdd_manager *dd,
00421               MlTree *tree,
00422               bdd_node **ofuncs,
00423               char *func_name,
00424               int ref)
00425 {
00426   char  name[MAX_NAME_LEN];
00427   int   polarity = 0;
00428 
00429   if (tree->top || tree->shared) {
00430     if (ref) {
00431       /* If tree is shared we print the name of the original function
00432        * unless it is a constant.
00433        */
00434       if (tree->ref) {
00435         if (tree->node == bdd_read_zero(dd))
00436           sprintf(name, "zero");
00437         else if (tree->node == bdd_read_one(dd))
00438           sprintf(name, "one");
00439         else
00440           polarity = GetMlTreeName(net, ofuncs, tree, name);
00441         if (polarity == 0) {
00442           if (tree->comp)
00443             SynthMakeComplementString(name);
00444         } else {
00445           if (!tree->comp)
00446             SynthMakeComplementString(name);
00447         }
00448         fprintf(fout, "%s = %s\n", func_name, name);
00449         return;
00450       }
00451     }
00452     WriteEqnOfTree(fout, net, dd, tree, ofuncs);
00453   }
00454 
00455   if (tree->leaf) {
00456     return;
00457   }
00458 
00459   if (tree->q_ref == 0)
00460     SynthWriteEqn(fout, net, dd, tree->q, ofuncs, NULL, ref);
00461   if (tree->d_ref == 0)
00462     SynthWriteEqn(fout, net, dd, tree->d, ofuncs, NULL, ref);
00463   if (tree->r_ref == 0)
00464     SynthWriteEqn(fout, net, dd, tree->r, ofuncs, NULL, ref);
00465 }
00466 
00467 
00479 void
00480 SynthSetInternalNodePrefix(char *prefix)
00481 {
00482   if (prefix)
00483     InternalNodePrefix = prefix;
00484   else
00485     InternalNodePrefix = DefaultPrefix;
00486 }
00487 
00488 
00503 void
00504 SynthSetupNodeNameTable(Ntk_Network_t *net)
00505 {
00506   lsGen         gen;
00507   Ntk_Node_t    *node;
00508 
00509   if (NodeNameTable) {
00510     (void)fprintf(vis_stdout,
00511         "** synth warning: table already exists in SynthSetupNodeNameTable.\n");
00512     st_free_table(NodeNameTable);
00513   }
00514 
00515   NodeNameTable = st_init_table(strcmp, st_strhash);
00516 
00517   /* Register all primary input node names. */
00518   Ntk_NetworkForEachPrimaryInput(net, gen, node) {
00519     st_insert(NodeNameTable, Ntk_NodeReadName(node), (char *)NULL);
00520   }
00521 
00522   /* Register all primary output node names. */
00523   Ntk_NetworkForEachPrimaryOutput(net, gen, node) {
00524     st_insert(NodeNameTable, Ntk_NodeReadName(node), (char *)NULL);
00525   }
00526 
00527   /* Register all latch input and output node names. */
00528   Ntk_NetworkForEachLatch(net, gen, node) {
00529     st_insert(NodeNameTable, Ntk_NodeReadName(Ntk_LatchReadDataInput(node)),
00530               (char *)NULL);
00531     st_insert(NodeNameTable, Ntk_NodeReadName(node), (char *)NULL);
00532   }
00533 }
00534 
00535 
00547 void
00548 SynthFreeNodeNameTable(void)
00549 {
00550   st_free_table(NodeNameTable);
00551   NodeNameTable = NIL(st_table);
00552 }
00553 
00554 
00570 void
00571 SynthGetInternalNodeName(char *name, int id)
00572 {
00573   sprintf(name, "%s%d", InternalNodePrefix, id);
00574   if (NodeNameTable) {
00575     if (st_lookup(NodeNameTable, name, NIL(char *))) {
00576       int       pos;
00577 
00578       sprintf(name, "_synth_%s%d", InternalNodePrefix, id);
00579       pos = 7; /* _synth_ */
00580       while (st_lookup(NodeNameTable, name, NIL(char *))) {
00581         sprintf(&name[pos], "_%s%d", InternalNodePrefix, id);
00582         pos++;
00583       }
00584     }
00585   } else {
00586     (void)fprintf(vis_stdout,
00587                   "** synth warning: skipping internal node name checking.\n");
00588   }
00589 }
00590 
00591 
00603 void
00604 SynthDumpBlif(Ntk_Network_t *net,
00605               bdd_manager *dd,
00606               int no,
00607               bdd_node **ofuncs,
00608               char **onames,
00609               int *initStates,
00610               char *model)
00611 {
00612   int           size;
00613   bdd_node      **bdds;
00614   FILE          *fout;
00615   char          **inames;
00616   char          filename[MAX_NAME_LEN];
00617   int           i;
00618   lsGen         gen;
00619   Ntk_Node_t    *node;
00620   char          **sorted_name;
00621   int           ni, po;
00622 
00623   sprintf(filename, "%s.debug.blif", model);
00624   fout = fopen(filename, "w");
00625   if (!fout) {
00626     (void)fprintf(vis_stderr,
00627                   "** synth error: Can't open the file %s.\n", filename);
00628     return;
00629   }
00630 
00631   fprintf(fout, ".model %s\n", model);
00632   fprintf(fout, ".inputs");
00633 
00634   /* Write list of primary inputs sorted lexicographically. */
00635   ni = Ntk_NetworkReadNumPrimaryInputs(net);
00636   sorted_name = ALLOC(char *, ni * sizeof(char *));
00637   i = 0;
00638   Ntk_NetworkForEachPrimaryInput(net, gen, node) {
00639     sorted_name[i++] = Ntk_NodeReadName(node);
00640   }
00641   qsort(sorted_name, ni, sizeof(char *),
00642         (int (*)(const void *, const void *))SynthStringCompare);
00643   for (i = 0; i < ni; i++)
00644     fprintf(fout," %s", sorted_name[i]);
00645   FREE(sorted_name);
00646 
00647   fprintf(fout, "\n");
00648   fprintf(fout, ".outputs");
00649 
00650   /* Write list of primary outputs sorted lexicographically. */
00651   po = Ntk_NetworkReadNumPrimaryOutputs(net);
00652   sorted_name = ALLOC(char *, po * sizeof(char *));
00653   i = 0;
00654   Ntk_NetworkForEachPrimaryOutput(net, gen, node) {
00655     sorted_name[i++] = Ntk_NodeReadName(node);
00656   }
00657   qsort(sorted_name, po, sizeof(char *),
00658         (int (*)(const void *, const void *))SynthStringCompare);
00659   for (i = 0; i < po; i++)
00660     fprintf(fout," %s", sorted_name[i]);
00661   FREE(sorted_name);
00662   fprintf(fout, "\n");
00663 
00664   /* Print list of latches. */
00665   i = 0;
00666   Ntk_NetworkForEachLatch(net, gen, node) {
00667     fprintf(fout,".latch %s", Ntk_NodeReadName(Ntk_LatchReadDataInput(node)));
00668     fprintf(fout, " %s", Ntk_NodeReadName(node));
00669     fprintf(fout, " %d\n", initStates[i]);
00670     i++;
00671   }
00672 
00673   bdds = ALLOC(bdd_node *, no);
00674 
00675   for (i = 0; i < no; i++) {
00676     bdds[i] = bdd_make_bdd_from_zdd_cover(dd, ofuncs[i]);
00677     bdd_ref(bdds[i]);
00678   }
00679 
00680   inames = GetAllVarNameArray(dd);
00681   if (!inames) {
00682     for (i = 0; i < no; i++)
00683       bdd_recursive_deref(dd, bdds[i]);
00684     FREE(bdds);
00685     fclose(fout);
00686     (void)fprintf(vis_stderr, "** synth error: Out of memory.\n");
00687     return;
00688   }
00689 
00690   bdd_dump_blif_body(dd, no, bdds, inames, onames, fout);
00691   fprintf(fout, ".end\n");
00692 
00693   size = bdd_num_vars(dd);
00694   for (i = 0; i < size; i++)
00695     FREE(inames[i]);
00696   FREE(inames);
00697 
00698   for (i = 0; i < no; i++)
00699     bdd_recursive_deref(dd, bdds[i]);
00700 
00701   FREE(bdds);
00702   fclose(fout);
00703 }
00704 
00705 
00706 /*---------------------------------------------------------------------------*/
00707 /* Definition of static functions                                            */
00708 /*---------------------------------------------------------------------------*/
00709 
00723 static void
00724 WriteMlBlif(Ntk_Network_t *net,
00725             bdd_manager *dd,
00726             MlTree *tree,
00727             FILE *fout,
00728             int no,
00729             bdd_node **ofuncs,
00730             int *oflags,
00731             int top_flag,
00732             int verbosity)
00733 {
00734   int           i;
00735   char          name[MAX_NAME_LEN], q_name[MAX_NAME_LEN];
00736   char          d_name[MAX_NAME_LEN], r_name[MAX_NAME_LEN];
00737   char          eq[MAX_EQ_LEN];
00738   bdd_node      *one = bdd_read_one(dd);
00739   bdd_node      *zero = bdd_read_zero(dd);
00740   char          q, d, r;
00741   int           comp;
00742 
00743   if (tree->leaf) {
00744     WriteLeafMlBlif(net, dd, tree, fout, no, ofuncs, oflags, top_flag,
00745                     verbosity);
00746     return;
00747   }
00748 
00749   if (!tree->ref) {
00750     if (!tree->q_ref)
00751       WriteMlBlif(net, dd, tree->q, fout, no, ofuncs, oflags, 0, verbosity);
00752     if (!tree->d_ref)
00753       WriteMlBlif(net, dd, tree->d, fout, no, ofuncs, oflags, 0, verbosity);
00754     if (!tree->r_ref)
00755       WriteMlBlif(net, dd, tree->r, fout, no, ofuncs, oflags, 0, verbosity);
00756   }
00757 
00758   for (i = 0; i < no; i++) {
00759     if (tree->node == ofuncs[i]) {
00760       if (top_flag == 0)
00761         return;
00762 
00763       if (oflags[i])
00764         continue;
00765       else
00766         oflags[i] = 1;
00767       sprintf(name, "%s",  SynthGetIthOutputName(i));
00768       break;
00769     }
00770   }
00771   if (i == no)
00772     SynthGetInternalNodeName(name, tree->id);
00773 
00774   fprintf(fout, "\n");
00775   if (verbosity > 2) {
00776     SynthGetChildMlTreeWithName(net, dd, tree, eq);
00777     (void)fprintf(fout, "# %s\n", eq);
00778   }
00779 
00780   if (tree->q->pi) {
00781     comp = SynthGetPrimaryNodeName(net, tree->q->node, q_name);
00782 
00783     if (comp)
00784       q = '0';
00785     else
00786       q = '1';
00787     if (tree->q_comp) {
00788       if (q == '0')
00789         q = '1';
00790       else
00791         q = '0';
00792     }
00793   } else {
00794     for (i = 0; i < no; i++) {
00795       if (tree->q->node == ofuncs[i]) {
00796         sprintf(q_name, "%s",  SynthGetIthOutputName(i));
00797         break;
00798       }
00799     }
00800     if (i == no)
00801       SynthGetInternalNodeName(q_name, tree->q->id);
00802     if (tree->q_comp)
00803       q = '0';
00804     else
00805       q = '1';
00806   }
00807   if (tree->d->pi) {
00808     comp = SynthGetPrimaryNodeName(net, tree->d->node, d_name);
00809 
00810     if (comp)
00811       d = '0';
00812     else
00813       d = '1';
00814     if (tree->d_comp) {
00815       if (d == '0')
00816         d = '1';
00817       else
00818         d = '0';
00819     }
00820   } else {
00821     for (i = 0; i < no; i++) {
00822       if (tree->d->node == ofuncs[i]) {
00823         sprintf(d_name, "%s", SynthGetIthOutputName(i));
00824         break;
00825       }
00826     }
00827     if (i == no)
00828       SynthGetInternalNodeName(d_name, tree->d->id);
00829     if (tree->d_comp)
00830       d = '0';
00831     else
00832       d = '1';
00833   }
00834   if (tree->r->pi) {
00835     comp = SynthGetPrimaryNodeName(net, tree->r->node, r_name);
00836 
00837     if (comp)
00838       r = '0';
00839     else
00840       r = '1';
00841     if (tree->r_comp) {
00842       if (r == '0')
00843         r = '1';
00844       else
00845         r = '0';
00846     }
00847   } else {
00848     for (i = 0; i < no; i++) {
00849       if (tree->r->node == ofuncs[i]) {
00850         sprintf(r_name, "%s", SynthGetIthOutputName(i));
00851         break;
00852       }
00853     }
00854     if (i == no)
00855       SynthGetInternalNodeName(r_name, tree->r->id);
00856     if (tree->r_comp)
00857       r = '0';
00858     else
00859       r = '1';
00860   }
00861 
00862   if (GetDdNodeOfMlTree(tree->q, tree->q_comp) == zero ||
00863       GetDdNodeOfMlTree(tree->d, tree->d_comp) == zero) {
00864     if (GetDdNodeOfMlTree(tree->r, tree->r_comp) == one) {
00865       fprintf(fout, ".names %s\n", name);
00866       fprintf(fout, "1\n");
00867     } else if (GetDdNodeOfMlTree(tree->r, tree->r_comp) == zero) {
00868       fprintf(fout, ".names %s\n", name);
00869       fprintf(fout, "0\n");
00870     } else {
00871       fprintf(fout, ".names %s %s\n", r_name, name);
00872       fprintf(fout, "%c 1\n", r);
00873     }
00874   } else if (GetDdNodeOfMlTree(tree->q, tree->q_comp) == one) {
00875     if (GetDdNodeOfMlTree(tree->d, tree->d_comp) == one) {
00876       fprintf(fout, ".names %s\n", name);
00877       fprintf(fout, "1\n");
00878     } else if (GetDdNodeOfMlTree(tree->d, tree->d_comp) == zero) {
00879       if (GetDdNodeOfMlTree(tree->r, tree->r_comp) == one) {
00880         fprintf(fout, ".names %s\n", name);
00881         fprintf(fout, "1\n");
00882       } else if (GetDdNodeOfMlTree(tree->r, tree->r_comp) == zero) {
00883         fprintf(fout, ".names %s\n", name);
00884         fprintf(fout, "0\n");
00885       } else {
00886         fprintf(fout, ".names %s %s\n", r_name, name);
00887         fprintf(fout, "%c 1\n", r);
00888       }
00889     } else {
00890       if (GetDdNodeOfMlTree(tree->r, tree->r_comp) == one) {
00891         fprintf(fout, ".names %s\n", name);
00892         fprintf(fout, "1\n");
00893       } else if (GetDdNodeOfMlTree(tree->r, tree->r_comp) == zero) {
00894         fprintf(fout, ".names %s %s\n", d_name, name);
00895         fprintf(fout, "%c 1\n", d);
00896       } else {
00897         fprintf(fout, ".names %s %s %s\n", d_name, r_name,
00898                 name);
00899         fprintf(fout, "%c- 1\n", d);
00900         fprintf(fout, "-%c 1\n", r);
00901       }
00902     }
00903   } else if (GetDdNodeOfMlTree(tree->d, tree->d_comp) == one) {
00904     if (GetDdNodeOfMlTree(tree->q, tree->q_comp) == one) {
00905       fprintf(fout, ".names %s\n", name);
00906       fprintf(fout, "1\n");
00907     } else if (GetDdNodeOfMlTree(tree->q, tree->q_comp) == zero) {
00908       if (GetDdNodeOfMlTree(tree->r, tree->r_comp) == one) {
00909         fprintf(fout, ".names %s\n", name);
00910         fprintf(fout, "1\n");
00911       } else if (GetDdNodeOfMlTree(tree->r, tree->r_comp) == zero) {
00912         fprintf(fout, ".names %s\n", name);
00913         fprintf(fout, "0\n");
00914       } else {
00915         fprintf(fout, ".names %s %s\n", r_name, name);
00916         fprintf(fout, "%c 1\n", r);
00917       }
00918     } else {
00919       if (GetDdNodeOfMlTree(tree->r, tree->r_comp) == one) {
00920         fprintf(fout, ".names %s\n", name);
00921         fprintf(fout, "1\n");
00922       } else if (GetDdNodeOfMlTree(tree->r, tree->r_comp) == zero) {
00923         fprintf(fout, ".names %s %s\n", q_name, name);
00924         fprintf(fout, "%c 1\n", q);
00925       } else {
00926         fprintf(fout, ".names %s %s %s\n", q_name, r_name, name);
00927         fprintf(fout, "%c- 1\n", q);
00928         fprintf(fout, "-%c 1\n", r);
00929       }
00930     }
00931   } else {
00932     if (GetDdNodeOfMlTree(tree->r, tree->r_comp) == one) {
00933       fprintf(fout, ".names %s\n", name);
00934       fprintf(fout, "1\n");
00935     } else if (GetDdNodeOfMlTree(tree->r, tree->r_comp) == zero) {
00936       fprintf(fout, ".names %s %s %s\n", q_name, d_name, name);
00937       fprintf(fout, "%c%c 1\n", q, d);
00938     } else {
00939       fprintf(fout, ".names %s %s %s %s\n", q_name, d_name, r_name, name);
00940       fprintf(fout, "%c%c- 1\n", q, d);
00941       fprintf(fout, "--%c 1\n", r);
00942     }
00943   }
00944 }
00945 
00959 static void
00960 WriteLeafMlBlif(Ntk_Network_t *net,
00961                 bdd_manager *dd,
00962                 MlTree *tree,
00963                 FILE *fout,
00964                 int no,
00965                 bdd_node **ofuncs,
00966                 int *oflags,
00967                 int top_flag,
00968                 int verbosity)
00969 {
00970   int           i, count, *support;
00971   char          name[MAX_EQ_LEN];
00972   bdd_node      *one = bdd_read_one(dd);
00973   bdd_node      *zero = bdd_read_zero(dd);
00974   char          out_name[MAX_NAME_LEN];
00975   bdd_node      *node;
00976   Ntk_Node_t    *ntk_node;
00977   int           sizeZ;
00978 
00979   sizeZ = bdd_num_zdd_vars(dd);
00980 
00981   if (tree->node == one || tree->node == zero || tree->pi)
00982     return;
00983 
00984   if (tree->comp)
00985     node = tree->complement;
00986   else
00987     node = tree->node;
00988   for (i = 0; i < no; i++) {
00989     if (node == ofuncs[i]) {
00990       if (top_flag == 0)
00991         return;
00992 
00993       if (oflags[i])
00994         continue;
00995       else
00996         oflags[i] = 1;
00997       sprintf(out_name, "%s", SynthGetIthOutputName(i));
00998       break;
00999     }
01000   }
01001   if (i == no)
01002     SynthGetInternalNodeName(out_name, tree->id);
01003   else {
01004     ntk_node = Ntk_NetworkFindNodeByName(net, out_name);
01005     if (Ntk_NodeTestIsLatch(ntk_node))
01006       return;
01007   }
01008 
01009   fprintf(fout, "\n");
01010   if (verbosity > 2) {
01011     SynthGetChildMlTreeWithName(net, dd, tree, name);
01012     fprintf(fout, "# %s\n", name);
01013   }
01014   fprintf(fout, ".names ");
01015 
01016   support = ALLOC(int, sizeZ);
01017   if (!support)
01018     return;
01019   (void)memset((void *)support, 0, sizeof(int) * sizeZ);
01020   SynthZddSupportStep(bdd_regular(node), support);
01021   SynthZddClearFlag(bdd_regular(node));
01022   count = 0;
01023   for (i = 0; i < sizeZ; i++) {
01024     if (support[i]) {
01025       SynthGetPrimaryIndexName(net, i, name);
01026       fprintf(fout, "%s ", name);
01027       if (i % 2 == 0) {
01028         support[i] = count;
01029         i++;
01030         if (support[i])
01031           support[i] = count;
01032       } else {
01033         support[i] = count;
01034       }
01035       count++;
01036     }
01037   }
01038   fprintf(fout, "%s\n", out_name);
01039 
01040   for (i = 0; i < count; i++)
01041     name[i] = '-';
01042   name[count] = '\0';
01043   WriteBlifBinary(dd, node, name, fout, support);
01044   FREE(support);
01045 }
01046 
01047 
01060 static void
01061 WriteBlifBinary(bdd_manager *dd,
01062                 bdd_node *node,
01063                 char *name,
01064                 FILE *fout,
01065                 int *support)
01066 {
01067   bdd_node      *one = bdd_read_one(dd);
01068   bdd_node      *zero = bdd_read_zero(dd);
01069   int           id = bdd_node_read_index(node);
01070 
01071   if (node == zero)
01072     return;
01073 
01074   if (node == one) {
01075     fprintf(fout, "%s 1\n", name);
01076     return;
01077   }
01078 
01079   if (id % 2 == 0)
01080     name[support[id]] = '1';
01081   else
01082     name[support[id]] = '0';
01083   WriteBlifBinary(dd, bdd_bdd_T(node), name, fout, support);
01084   name[support[id]] = '-';
01085   WriteBlifBinary(dd, bdd_bdd_E(node), name, fout, support);
01086   name[support[id]] = '-';
01087 }
01088 
01089 
01101 static void
01102 WriteEqnOfTree(FILE *fout,
01103                Ntk_Network_t *net,
01104                bdd_manager *dd,
01105                MlTree *tree,
01106                bdd_node **ofuncs)
01107 {
01108   char  eq[MAX_EQ_LEN];
01109   char  name[MAX_NAME_LEN];
01110   int   polarity = 0;
01111 
01112   polarity = GetMlTreeName(net, ofuncs, tree, name);
01113   eq[0] = '\0';
01114   GetEqnOfTree(net, dd, tree, tree, eq, ofuncs);
01115   if (polarity)
01116     SynthMakeComplementString(eq);
01117   fprintf(fout, "%s = %s\n", name, eq);
01118 }
01119 
01120 
01132 static int
01133 GetEqnOfTree(Ntk_Network_t *net,
01134              bdd_manager *dd,
01135              MlTree *top,
01136              MlTree *tree,
01137              char *eq,
01138              bdd_node **ofuncs)
01139 {
01140   char          q_eq[MAX_EQ_LEN];
01141   char          d_eq[MAX_EQ_LEN];
01142   char          r_eq[MAX_EQ_LEN];
01143   char          qd_eq[MAX_EQ_LEN];
01144   bdd_node      *one = bdd_read_one(dd);
01145   bdd_node      *zero = bdd_read_zero(dd);
01146   bdd_node      *f;
01147   int           flag;
01148   int           polarity = 0;
01149 
01150   if (tree != top && tree->shared) {
01151     polarity = GetMlTreeName(net, ofuncs, tree, eq);
01152     if (polarity)
01153       SynthMakeComplementString(eq);
01154     return(0);
01155   }
01156 
01157   f = tree->node;
01158   if (tree->leaf) {
01159     flag = SynthGetChildTreeWithName(net, dd, f, eq);
01160     return(flag);
01161   }
01162 
01163   if (f == one) {
01164     sprintf(eq, "one");
01165     return(0);
01166   } else if (f == zero) {
01167     sprintf(eq, "zero");
01168     return(0);
01169   }
01170 
01171   q_eq[0] = d_eq[0] = r_eq[0] = '\0';
01172   flag = GetEqnOfTree(net, dd, top, tree->q, q_eq, ofuncs);
01173   if (tree->q_comp)
01174     SynthMakeComplementString(q_eq);
01175   if (flag)
01176     return(1);
01177   if (GetDdNodeOfMlTree(tree->d, tree->d_comp) == one)
01178     d_eq[0] = '\0';
01179   else {
01180     flag = GetEqnOfTree(net, dd, top, tree->d, d_eq, ofuncs);
01181     if (tree->d_comp)
01182       SynthMakeComplementString(d_eq);
01183     if (flag)
01184       return(1);
01185   }
01186   flag = GetEqnOfTree(net, dd, top, tree->r, r_eq, ofuncs);
01187   if (tree->r_comp)
01188     SynthMakeComplementString(r_eq);
01189   if (flag)
01190     return(1);
01191 
01192   if (strcmp(q_eq, "one") == 0)
01193     sprintf(qd_eq, "%s", d_eq);
01194   else if (strcmp(q_eq, "zero") == 0)
01195     sprintf(qd_eq, "zero");
01196   else if (strcmp(d_eq, "one") == 0)
01197     sprintf(qd_eq, "%s", q_eq);
01198   else if (strcmp(d_eq, "zero") == 0)
01199     sprintf(qd_eq, "zero");
01200   else {
01201     if (strlen(q_eq) + strlen(d_eq) + 1 > MAX_EQ_LEN) {
01202       sprintf(eq, "%s", q_eq);
01203       if (strlen(eq) == MAX_EQ_LEN - 1) {
01204         eq[MAX_EQ_LEN - 2] = '#'; /* truncated */
01205         eq[MAX_EQ_LEN - 1] = '\0';
01206       } else {
01207         eq[strlen(eq)] = '#'; /* truncated */
01208         eq[strlen(eq) + 1] = '\0';
01209       }
01210       return(1);
01211     }
01212     sprintf(qd_eq, "%s %s", q_eq, d_eq);
01213   }
01214 
01215   if (strcmp(r_eq, "zero") == 0)
01216     sprintf(eq, "%s", qd_eq);
01217   else {
01218     if (strlen(qd_eq) + strlen(r_eq) + 1 > MAX_EQ_LEN) {
01219       sprintf(eq, "%s", qd_eq);
01220       if (strlen(eq) == MAX_EQ_LEN - 1) {
01221         eq[MAX_EQ_LEN - 2] = '#'; /* truncated */
01222         eq[MAX_EQ_LEN - 1] = '\0';
01223       } else {
01224         eq[strlen(eq)] = '#'; /* truncated */
01225         eq[strlen(eq) + 1] = '\0';
01226       }
01227       return(1);
01228     }
01229     sprintf(eq, "(%s + %s)", qd_eq, r_eq);
01230   }
01231   return(0);
01232 }
01233 
01234 
01248 static void
01249 WriteMlTreeBlif(FILE *fout,
01250                 Ntk_Network_t *net,
01251                 bdd_manager *dd,
01252                 MlTree *tree,
01253                 bdd_node **ofuncs,
01254                 int no,
01255                 char *func_name,
01256                 int ref)
01257 {
01258   char  name[MAX_NAME_LEN];
01259   int   polarity = 0;
01260 
01261   if (tree->top || tree->shared) {
01262     if (ref) {
01263       if (tree->ref) {
01264         polarity = GetMlTreeName(net, ofuncs, tree, name);
01265         fprintf(fout, "\n.names %s %s\n", name, func_name);
01266         if (polarity == 0) {
01267           if (tree->comp)
01268             fprintf(fout, "0 1\n");
01269           else
01270             fprintf(fout, "1 1\n");
01271         } else {
01272           if (tree->comp)
01273             fprintf(fout, "1 1\n");
01274           else
01275             fprintf(fout, "0 1\n");
01276         }
01277         return;
01278       }
01279     }
01280     WriteMultiLevelBlif(fout, net, dd, tree, ofuncs, no);
01281   }
01282 
01283   if (tree->leaf)
01284     return;
01285 
01286   if (tree->q_ref == 0)
01287     WriteMlTreeBlif(fout, net, dd, tree->q, ofuncs, no, NULL, ref);
01288   if (tree->d_ref == 0)
01289     WriteMlTreeBlif(fout, net, dd, tree->d, ofuncs, no, NULL, ref);
01290   if (tree->r_ref == 0)
01291     WriteMlTreeBlif(fout, net, dd, tree->r, ofuncs, no, NULL, ref);
01292 }
01293 
01294 
01308 static void
01309 WriteMultiLevelBlif(FILE *fout,
01310                     Ntk_Network_t *net,
01311                     bdd_manager *dd,
01312                     MlTree *tree,
01313                     bdd_node **ofuncs,
01314                     int no)
01315 {
01316   int                   i, ni;
01317   char                  name[MAX_NAME_LEN];
01318   TruthTableLine        *lines, *cur, *next;
01319   st_table              *table;
01320   char                  **sorted_name, *key;
01321   st_generator          *gen;
01322   int                   pos;
01323   Ntk_Node_t            *ntk_node;
01324   int                   polarity = 0;
01325 
01326   polarity = GetMlTreeName(net, ofuncs, tree, name);
01327   for (i = 0; i < no; i++) {
01328     if (tree->node == ofuncs[i]) {
01329       ntk_node = Ntk_NetworkFindNodeByName(net, name);
01330       if (Ntk_NodeTestIsLatch(ntk_node))
01331         return;
01332     }
01333   }
01334 
01335   table = st_init_table(strcmp, st_strhash);
01336   ni = 0;
01337   ni = GetMultiLevelNodes(net, dd, tree, tree, ofuncs, no, table, ni);
01338   sorted_name = ALLOC(char *, ni * sizeof(char *));
01339   i = 0;
01340   st_foreach_item_int(table, gen, (char **)&key, &pos) {
01341     sorted_name[i] = key;
01342     i++;
01343   }
01344   qsort(sorted_name, ni, sizeof(char *),
01345         (int (*)(const void *, const void *))SynthStringCompare);
01346   for (i = 0; i < ni; i++) {
01347     st_insert(table, (char *)sorted_name[i], (char *)(long)i);
01348   }
01349   lines = GetMultiLevelBlifRecur(net, dd, tree, tree, ofuncs, no, table, ni);
01350   fprintf(fout, "\n.names");
01351   for (i = 0; i < ni; i++)
01352     fprintf(fout, " %s", sorted_name[i]);
01353   fprintf(fout, " %s\n", name);
01354   cur = lines;
01355   while (cur) {
01356     next = cur->next;
01357     if (polarity == 0)
01358       fprintf(fout, "%s 1\n", cur->values);
01359     else
01360       fprintf(fout, "%s 0\n", cur->values);
01361     FREE(cur->values);
01362     FREE(cur);
01363     cur = next;
01364   }
01365   st_free_table(table);
01366   for (i = 0; i < ni; i++)
01367     FREE(sorted_name[i]);
01368   FREE(sorted_name);
01369 }
01370 
01371 
01383 static TruthTableLine *
01384 GetMultiLevelBlifRecur(Ntk_Network_t *net,
01385                        bdd_manager *dd,
01386                        MlTree *top,
01387                        MlTree *tree,
01388                        bdd_node **ofuncs,
01389                        int no,
01390                        st_table *table,
01391                        int ni)
01392 {
01393   bdd_node              *one = bdd_read_one(dd);
01394   bdd_node              *zero = bdd_read_zero(dd);
01395   bdd_node              *f;
01396   TruthTableLine        *line;
01397   TruthTableLine        *cur, *q_line, *d_line, *r_line;
01398   int                   pos;
01399   char                  name[MAX_NAME_LEN];
01400   int                   polarity = 0;
01401 
01402   line = (TruthTableLine *)NULL;
01403 
01404   if (tree != top && tree->shared) {
01405     polarity = GetMlTreeName(net, ofuncs, tree, name);
01406     line = GetTautologyLine(ni);
01407     if (st_lookup_int(table, (char *)name, (int *)(&pos))) {
01408       if (polarity == 0)
01409         line->values[pos] = '1';
01410       else
01411         line->values[pos] = '0';
01412     }
01413     return(line);
01414   }
01415 
01416   f = tree->node;
01417   if (tree->leaf) {
01418     line = GetLeafLines(net, dd, tree, ofuncs, no, table, ni);
01419     return(line);
01420   }
01421 
01422   if (f == one || f == zero)
01423     return(line);
01424 
01425   q_line = GetMultiLevelBlifRecur(net, dd, top, tree->q, ofuncs,
01426                                   no, table, ni);
01427   if (q_line && tree->q_comp)
01428     q_line = GetComplementLines(q_line, ni, 1);
01429   if (GetDdNodeOfMlTree(tree->d, tree->d_comp) == one)
01430     d_line = (TruthTableLine *)NULL;
01431   else {
01432     d_line = GetMultiLevelBlifRecur(net, dd, top, tree->d, ofuncs, no,
01433                                     table, ni);
01434     if (d_line && tree->d_comp)
01435       d_line = GetComplementLines(d_line, ni, 1);
01436   }
01437   if (q_line && d_line)
01438     line = GetAndLines(q_line, d_line, ni, 1);
01439   else if (q_line)
01440     line = q_line;
01441   else if (d_line)
01442     line = d_line;
01443   r_line = GetMultiLevelBlifRecur(net, dd, top, tree->r, ofuncs, no, table, ni);
01444   if (r_line && tree->r_comp)
01445     r_line = GetComplementLines(r_line, ni, 1);
01446   if (r_line) {
01447     cur = line;
01448     while (cur) {
01449       if (!cur->next) {
01450         cur->next = r_line;
01451         break;
01452       }
01453       cur = cur->next;
01454     }
01455   }
01456 
01457   return(line);
01458 }
01459 
01460 
01474 static int
01475 GetMultiLevelNodes(Ntk_Network_t *net,
01476                    bdd_manager *dd,
01477                    MlTree *top,
01478                    MlTree *tree,
01479                    bdd_node **ofuncs,
01480                    int no,
01481                    st_table *table,
01482                    int ni)
01483 {
01484   bdd_node      *one = bdd_read_one(dd);
01485   bdd_node      *zero = bdd_read_zero(dd);
01486   bdd_node      *f;
01487   char          name[MAX_NAME_LEN], *st_name;
01488   int           pos;
01489 
01490   if (tree != top && tree->shared) {
01491     (void) GetMlTreeName(net, ofuncs, tree, name);
01492     if (!st_lookup_int(table, (char *)name, (int *)(&pos))) {
01493       st_name = ALLOC(char, strlen(name) + 1);
01494       strcpy(st_name, name);
01495       st_insert(table, (char *)st_name, (char *)(long)ni);
01496       ni++;
01497     }
01498     return(ni);
01499   }
01500 
01501   f = tree->node;
01502   if (tree->leaf) {
01503     ni = GetLeafNodes(net, dd, tree, ofuncs, no, table, ni);
01504     return(ni);
01505   }
01506 
01507   if (f == one || f == zero)
01508     return(ni);
01509 
01510   ni = GetMultiLevelNodes(net, dd, top, tree->q, ofuncs, no, table, ni);
01511   if (GetDdNodeOfMlTree(tree->d, tree->d_comp) != one)
01512     ni = GetMultiLevelNodes(net, dd, top, tree->d, ofuncs, no, table, ni);
01513   ni = GetMultiLevelNodes(net, dd, top, tree->r, ofuncs, no, table, ni);
01514 
01515   return(ni);
01516 }
01517 
01518 
01532 static int
01533 GetLeafNodes(Ntk_Network_t *net,
01534              bdd_manager *dd,
01535              MlTree *tree,
01536              bdd_node **ofuncs,
01537              int no,
01538              st_table *table,
01539              int ni)
01540 {
01541   int           i, *support;
01542   char          name[MAX_NAME_LEN], *st_name;
01543   bdd_node      *one = bdd_read_one(dd);
01544   bdd_node      *zero = bdd_read_zero(dd);
01545   bdd_node      *node;
01546   int           pos, sizeZ = bdd_num_zdd_vars(dd);
01547 
01548   if (tree->node == one || tree->node == zero)
01549     return(ni);
01550 
01551   if (tree->comp)
01552     node = tree->complement;
01553   else
01554     node = tree->node;
01555 
01556   support = ALLOC(int, sizeZ);
01557   if (!support)
01558     return(ni);
01559   (void)memset((void *)support, 0, sizeof(int) * sizeZ);
01560   SynthZddSupportStep(bdd_regular(node), support);
01561   SynthZddClearFlag(bdd_regular(node));
01562   for (i = 0; i < sizeZ; i++) {
01563     if (support[i]) {
01564       SynthGetPrimaryIndexName(net, i, name);
01565       if (!st_lookup_int(table, (char *)name, (int *)(&pos))) {
01566         st_name = ALLOC(char, strlen(name) + 1);
01567         strcpy(st_name, name);
01568         st_insert(table, (char *)st_name, (char *)(long)ni);
01569         ni++;
01570       }
01571     }
01572   }
01573   FREE(support);
01574   return(ni);
01575 }
01576 
01577 
01589 static TruthTableLine *
01590 GetTautologyLine(int ni)
01591 {
01592   int                   i;
01593   TruthTableLine        *line;
01594 
01595   line = ALLOC(TruthTableLine, 1);
01596   (void)memset((void *)line, 0, sizeof(TruthTableLine));
01597   line->values = (char *)malloc(ni + 1);
01598   for (i = 0; i < ni; i++)
01599     line->values[i] = '-';
01600   line->values[ni] = '\0';
01601   return(line);
01602 }
01603 
01604 
01616 static TruthTableLine *
01617 GetLeafLines(Ntk_Network_t *net,
01618              bdd_manager *dd,
01619              MlTree *tree,
01620              bdd_node **ofuncs,
01621              int no,
01622              st_table *table,
01623              int ni)
01624 {
01625   int                   i, *support;
01626   char                  values[MAX_EQ_LEN];
01627   bdd_node              *one = bdd_read_one(dd);
01628   bdd_node              *zero = bdd_read_zero(dd);
01629   bdd_node              *node;
01630   TruthTableLine        *line;
01631   int                   pos, sizeZ = bdd_num_zdd_vars(dd);
01632   char                  name[MAX_NAME_LEN];
01633 
01634   line = (TruthTableLine *)NULL;
01635 
01636   if (tree->node == one || tree->node == zero)
01637     return(line);
01638 
01639   if (tree->comp)
01640     node = tree->complement;
01641   else
01642     node = tree->node;
01643 
01644   support = ALLOC(int, sizeZ);
01645   if (!support)
01646     return(line);
01647   (void)memset((void *)support, 0, sizeof(int) * sizeZ);
01648   SynthZddSupportStep(bdd_regular(node), support);
01649   SynthZddClearFlag(bdd_regular(node));
01650   for (i = 0; i < sizeZ; i++) {
01651     if (support[i]) {
01652       SynthGetPrimaryIndexName(net, i, name);
01653       if (!st_lookup_int(table, (char *)name, (int *)(&pos))) {
01654         fprintf(vis_stdout,
01655                 "** synth error: Failed to find %s in hash.\n", name);
01656       }
01657       support[i] = pos;
01658     }
01659   }
01660 
01661   for (i = 0; i < ni; i++)
01662     values[i] = '-';
01663   values[ni] = '\0';
01664   line = GetBlifBinary(line, dd, node, values, support, ni);
01665   FREE(support);
01666   return(line);
01667 }
01668 
01669 
01681 static TruthTableLine *
01682 GetBlifBinary(TruthTableLine *line,
01683               bdd_manager *dd,
01684               bdd_node *node,
01685               char *values,
01686               int *support,
01687               int ni)
01688 {
01689   bdd_node              *one = bdd_read_one(dd);
01690   bdd_node              *zero = bdd_read_zero(dd);
01691   TruthTableLine        *new_, *cur;
01692   int                   id = bdd_node_read_index(node);
01693 
01694   if (node == zero)
01695     return(line);
01696 
01697   if (node == one) {
01698     new_ = ALLOC(TruthTableLine, 1);
01699     (void)memset((void *)new_, 0, sizeof(TruthTableLine));
01700     new_->values = ALLOC(char,ni+1);
01701     strcpy(new_->values, values);
01702     if (line) {
01703       cur = line;
01704       while (cur->next)
01705         cur = cur->next;
01706       cur->next = new_;
01707     } else
01708       line = new_;
01709     return(line);
01710   }
01711 
01712   if (id % 2 == 0)
01713     values[support[id]] = '1';
01714   else
01715     values[support[id]] = '0';
01716   line = GetBlifBinary(line, dd, bdd_bdd_T(node), values, support, ni);
01717   values[support[id]] = '-';
01718   line = GetBlifBinary(line, dd, bdd_bdd_E(node), values, support, ni);
01719   values[support[id]] = '-';
01720   return(line);
01721 }
01722 
01723 
01735 static TruthTableLine *
01736 GetComplementOneLine(TruthTableLine *line,
01737                      int ni,
01738                      int flag)
01739 {
01740   int                   i;
01741   TruthTableLine        *new_line, *start, *last;
01742 
01743   start = last = (TruthTableLine *)NULL;
01744 
01745   for (i = 0; i < ni; i++) {
01746     if (line->values[i] != '-') {
01747       new_line = GetTautologyLine(ni);
01748       if (line->values[i] == '1')
01749         new_line->values[i] = '0';
01750       else
01751         new_line->values[i] = '1';
01752       if (last) {
01753         last->next = new_line;
01754         last = new_line;
01755       } else
01756         start = last = new_line;
01757     }
01758   }
01759 
01760   if (flag) {
01761     FREE(line->values);
01762     FREE(line);
01763   }
01764 
01765   return(start);
01766 }
01767 
01768 
01780 static TruthTableLine *
01781 GetComplementLines(TruthTableLine *lines,
01782                    int ni,
01783                    int flag)
01784 {
01785   TruthTableLine        *first, *cur, *next;
01786 
01787   if (!lines)
01788     return(lines);
01789 
01790   first = lines;
01791   cur = first->next;
01792   first = GetComplementOneLine(first, ni, flag);
01793   while (cur) {
01794     next = cur->next;
01795     cur = GetComplementOneLine(cur, ni, flag);
01796     first = GetAndLines(first, cur, ni, flag);
01797     cur = next;
01798   }
01799   return(first);
01800 }
01801 
01802 
01814 static TruthTableLine *
01815 GetAndLines(TruthTableLine *line1,
01816             TruthTableLine *line2,
01817             int ni,
01818             int flag)
01819 {
01820   int                   i;
01821   TruthTableLine        *cur1, *cur2, *next1, *next2;
01822   TruthTableLine        *start, *last;
01823   TruthTableLine        *new_line;
01824 
01825   start = last = (TruthTableLine *)NULL;
01826 
01827   cur1 = line1;
01828   while (cur1) {
01829     next1 = cur1->next;
01830     cur2 = line2;
01831     while (cur2) {
01832       new_line = GetTautologyLine(ni);
01833       strcpy(new_line->values, cur1->values);
01834       for (i = 0; i < ni; i++) {
01835         if (cur2->values[i] != '-')
01836           new_line->values[i] = cur2->values[i];
01837       }
01838       if (last) {
01839         last->next = new_line;
01840         last = new_line;
01841       } else {
01842         start = last = new_line;
01843       }
01844       cur2 = cur2->next;
01845     }
01846     if (flag) {
01847       FREE(cur1->values);
01848       FREE(cur1);
01849     }
01850     cur1 = next1;
01851   }
01852 
01853   if (flag) {
01854     cur2 = line2;
01855     while (cur2) {
01856       next2 = cur2->next;
01857       FREE(cur2->values);
01858       FREE(cur2);
01859       cur2 = next2;
01860     }
01861   }
01862 
01863   return(start);
01864 }
01865 
01866 
01878 static bdd_node *
01879 GetDdNodeOfMlTree(MlTree *tree,
01880                   int comp)
01881 {
01882   if (comp)
01883     return(tree->complement);
01884   return(tree->node);
01885 }
01886 
01899 static int
01900 GetMlTreeName(Ntk_Network_t *net,
01901               bdd_node **ofuncs,
01902               MlTree *tree,
01903               char *name)
01904 {
01905   int   i, no;
01906   int   polarity = 0; /* positive */
01907 
01908   no = Ntk_NetworkReadNumCombOutputs(net) - Ntk_NetworkReadNumLatches(net);
01909   for (i = 0; i < no; i++) {
01910     if (tree->node == ofuncs[i]) {
01911       sprintf(name, "%s", SynthGetIthOutputName(i));
01912       break;
01913     }
01914   }
01915   if (i == no) {
01916     if (tree->pi)
01917       polarity = SynthGetPrimaryNodeName(net, tree->node, name);
01918     else
01919       SynthGetInternalNodeName(name, tree->id);
01920   }
01921 
01922   return(polarity);
01923 }
01924 
01936 static char **
01937 GetAllVarNameArray(bdd_manager *dd)
01938 {
01939   int           size, i, j;
01940   mvar_type     var;
01941   char          **nameArray, *name;
01942 
01943   size = bdd_num_vars(dd);
01944   nameArray = ALLOC(char *, size);
01945   if (!nameArray)
01946     return(NIL(char *));
01947 
01948   for (i = 0; i < size; i++) {
01949     var = mdd_get_var_by_id(dd, i);
01950     name = ALLOC(char, strlen(var.name) + 1);
01951     if (!name) {
01952       for (j = 0; j < i; j++)
01953         FREE(nameArray[j]);
01954       FREE(nameArray);
01955       return(NIL(char *));
01956     }
01957     strcpy(name, var.name);
01958     nameArray[i] = name;
01959   }
01960   
01961   return(nameArray);
01962 }