VIS
|
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 }