VIS
|
00001 00017 #include "synthInt.h" 00018 00019 static char rcsid[] UNUSED = "$Id: synthOpt.c,v 1.53 2005/05/11 20:18:25 hhhan Exp $"; 00020 00021 /*---------------------------------------------------------------------------*/ 00022 /* Constant declarations */ 00023 /*---------------------------------------------------------------------------*/ 00024 00025 00026 /*---------------------------------------------------------------------------*/ 00027 /* Type declarations */ 00028 /*---------------------------------------------------------------------------*/ 00029 00030 00031 /*---------------------------------------------------------------------------*/ 00032 /* Structure declarations */ 00033 /*---------------------------------------------------------------------------*/ 00034 00035 00036 /*---------------------------------------------------------------------------*/ 00037 /* Variable declarations */ 00038 /*---------------------------------------------------------------------------*/ 00039 00040 int OutputOrdering = 1; /* 00041 ** 0 : just use VIS's order 00042 ** 1 : smaller first in terms of support 00043 ** 2 : smaller first in terms of bdd size 00044 */ 00045 00046 static int UseFuncDivisor = 1; 00047 static float SuppFactor = 10.0; 00048 static float ProbFactor = 10.0; 00049 static int *SupportCount; 00050 static float *Probability; 00051 static char **outputNames; 00052 00053 extern int TryNodeSharing; 00054 extern int noMemoryFlag; 00055 extern int VerifyTreeMode; 00056 00059 /*---------------------------------------------------------------------------*/ 00060 /* Static function prototypes */ 00061 /*---------------------------------------------------------------------------*/ 00062 00063 static void GetOutputOrder(bdd_manager *dd, bdd_node **ofuncs, int no, int *order, int verbosity); 00064 static int IsSubsetOfSupportForOneWord(unsigned int mask1, unsigned int mask2); 00065 static int IsNullSupport(int size, unsigned int *mask); 00066 static void PrintSupportMask(int n, int size, unsigned int *mask); 00067 static int GetNumberOfSupport(int n, int size, unsigned int *mask); 00068 static int factorizeNetwork(Ntk_Network_t *net, bdd_manager *dd, bdd_node **ofuncs, MlTree **tree, int no, int *out_order, st_table *table, char **combOutNames, int divisor, MlTree *(* factoring_func)(bdd_manager *, st_table *, bdd_node *, int, int *, MlTree *, int, MlTree *, int), int verbosity); 00069 00073 /*---------------------------------------------------------------------------*/ 00074 /* Definition of exported functions */ 00075 /*---------------------------------------------------------------------------*/ 00076 00077 00078 /*---------------------------------------------------------------------------*/ 00079 /* Definition of internal functions */ 00080 /*---------------------------------------------------------------------------*/ 00081 00093 void 00094 SynthMultiLevelOptimize(Ntk_Network_t *network, 00095 bdd_node **combOutBdds, 00096 bdd_node **combUpperBdds, 00097 char **combOutNames, 00098 int *initStates, 00099 Synth_InfoData_t *synthInfo, 00100 int verbosity) 00101 { 00102 bdd_manager *dd = (bdd_manager *)Ntk_NetworkReadMddManager(network); 00103 bdd_node *top; 00104 bdd_node **ofuncs; 00105 int i, no; 00106 int factoring, divisor; 00107 char *filename; 00108 char *filehead; 00109 MlTree **tree; 00110 bdd_node *zdd_I; 00111 st_table *table; 00112 int nml, tml; 00113 int *out_order; 00114 FILE *feqn; 00115 MlTree *(* factoring_func)(bdd_manager *, st_table *, 00116 bdd_node *, int, int *, MlTree *, 00117 int, MlTree *, int); 00118 int autoDyn, autoDynZ; 00119 bdd_reorder_type_t method, methodZ; 00120 int error; 00121 00122 factoring = synthInfo->factoring; 00123 divisor = synthInfo->divisor; 00124 filehead = synthInfo->filehead; 00125 TryNodeSharing = synthInfo->trySharing; 00126 SynthSetInternalNodePrefix(synthInfo->prefix); 00127 00128 /* Save reordering status and set reordering mode specific to 00129 * synthesis. 00130 */ 00131 autoDyn = bdd_reordering_status(dd, &method); 00132 autoDynZ = bdd_reordering_zdd_status(dd, &methodZ); 00133 00134 switch (synthInfo->reordering) { 00135 case 0 : 00136 bdd_dynamic_reordering_disable(dd); 00137 bdd_dynamic_reordering_zdd_disable(dd); 00138 break; 00139 case 1 : 00140 bdd_dynamic_reordering(dd, method, BDD_REORDER_VERBOSITY_DEFAULT); 00141 bdd_dynamic_reordering_zdd_disable(dd); 00142 break; 00143 case 2 : 00144 bdd_dynamic_reordering_disable(dd); 00145 bdd_dynamic_reordering_zdd(dd, methodZ, BDD_REORDER_VERBOSITY_DEFAULT); 00146 break; 00147 case 3 : 00148 bdd_dynamic_reordering(dd, method, BDD_REORDER_VERBOSITY_DEFAULT); 00149 bdd_dynamic_reordering_zdd(dd, methodZ, BDD_REORDER_VERBOSITY_DEFAULT); 00150 break; 00151 default : 00152 bdd_dynamic_reordering_disable(dd); 00153 bdd_dynamic_reordering_zdd_disable(dd); 00154 break; 00155 } 00156 00157 if (factoring == 0) 00158 factoring_func = SynthSimpleFactorTree; 00159 else 00160 factoring_func = SynthGenericFactorTree; 00161 00162 /* outputNames is a static global variable for this file. */ 00163 outputNames = combOutNames; 00164 00165 /* Initialize the node-tree table and other factoring-related variables. 00166 * The table contains pairs of a ZDD node and the corresponding multi-level 00167 * tree. 00168 */ 00169 table = st_init_table(st_ptrcmp, st_ptrhash); 00170 SynthInitMlTable(); 00171 00172 /* Create ZDD variables for the positive and negative literals. */ 00173 bdd_zdd_vars_from_bdd_vars(dd, 2); 00174 00175 /* Since we currently support only blif files, the number of 00176 * functions to synthesize should not include the initial 00177 * inputs of latches in case of sequential ckts. 00178 */ 00179 no = Ntk_NetworkReadNumCombOutputs(network) - 00180 Ntk_NetworkReadNumLatches(network); 00181 00182 /* Compute two-level covers for all the functions to be synthesized. */ 00183 ofuncs = ALLOC(bdd_node *, no); 00184 for (i = 0; i < no; i++) { 00185 if (verbosity) { 00186 (void)fprintf(vis_stdout, "** synth info: Synthesizing output [%d(%s)]\n", 00187 i, combOutNames[i]); 00188 } 00189 bdd_ref(top = bdd_zdd_isop(dd, combOutBdds[i], combUpperBdds[i], 00190 &zdd_I)); 00191 bdd_ref(zdd_I); 00192 bdd_recursive_deref(dd, top); 00193 ofuncs[i] = zdd_I; 00194 } 00195 00196 if (VerifyTreeMode == 2) 00197 SynthDumpBlif(network, dd, no, ofuncs, combOutNames, initStates, filehead); 00198 00199 /* Initialize array of factoring trees and determine the order in 00200 * which the functions will be processed. Then proceed to factor. 00201 */ 00202 tree = ALLOC(MlTree *, no); 00203 (void)memset((void *)tree, 0, no * sizeof(MlTree *)); 00204 out_order = ALLOC(int, no); 00205 GetOutputOrder(dd, ofuncs, no, out_order, verbosity); 00206 error = factorizeNetwork(network, dd, ofuncs, tree, no, out_order, 00207 table, combOutNames, divisor, factoring_func, verbosity); 00208 FREE(out_order); 00209 00210 if (error) { 00211 (void)fprintf(vis_stderr, 00212 "** synth error: synthesize_network has finished abnormally"); 00213 if (noMemoryFlag) 00214 (void)fprintf(vis_stderr, " due to lack of memory\n"); 00215 else 00216 (void)fprintf(vis_stderr, " for some reason\n"); 00217 goto cleanup; 00218 } 00219 00220 /* Count total number of literals in multi-level network. */ 00221 tml = 0; 00222 for (i = 0; i < no; i++) { 00223 if (tree[i]) { 00224 nml = SynthCountMlLiteral(dd, tree[i], 1); 00225 tml += nml; 00226 } 00227 } 00228 (void)fprintf(vis_stdout, 00229 "** synth info: Total number of literals = %d\n", tml); 00230 00231 /* Write network in eqn and blif formats. */ 00232 SynthSetupNodeNameTable(network); 00233 filename = ALLOC(char, strlen(filehead) + 9); 00234 if (synthInfo->eqn) { 00235 sprintf(filename, "%s.eqn", filehead); 00236 feqn = Cmd_FileOpen(filename, "w", NIL(char *), 0); 00237 if (feqn) { 00238 fprintf(feqn, "** synth info: Total number of literals = %d\n", tml); 00239 SynthWriteEqnHeader(feqn, network, dd); 00240 for (i = 0; i < no; i++) { 00241 if (tree[i]) 00242 SynthWriteEqn(feqn, network, dd, tree[i], ofuncs, combOutNames[i], 1); 00243 } 00244 fclose(feqn); 00245 } else { 00246 (void)fprintf(vis_stdout, 00247 "** synth error: Error in opening file [%s]\n", filename); 00248 } 00249 } 00250 sprintf(filename, "%s.ml.blif", filehead); 00251 SynthWriteBlifFile(network, dd, tree, filename, no, ofuncs, initStates, 00252 0, verbosity); 00253 FREE(filename); 00254 SynthFreeNodeNameTable(); 00255 00256 cleanup: 00257 /* Clean up. */ 00258 for (i = 0; i < no; i++) { 00259 if (!tree[i]) 00260 continue; 00261 bdd_recursive_deref_zdd(dd, tree[i]->node); 00262 /* frees some trees not in node-tree table */ 00263 if (tree[i]->ref) 00264 SynthFreeMlTree(tree[i], 0); 00265 } 00266 00267 SynthClearMlTable(dd, table); 00268 st_free_table(table); 00269 FREE(tree); 00270 00271 for (i = 0; i < no; i++) { 00272 if (!ofuncs[i]) 00273 continue; 00274 bdd_recursive_deref_zdd(dd, ofuncs[i]); 00275 } 00276 00277 FREE(ofuncs); 00278 00279 /* Restore reordering status. */ 00280 if (autoDyn) 00281 bdd_dynamic_reordering(dd, method, BDD_REORDER_VERBOSITY_DEFAULT); 00282 else 00283 bdd_dynamic_reordering_disable(dd); 00284 if (autoDynZ) 00285 bdd_dynamic_reordering_zdd(dd, methodZ, BDD_REORDER_VERBOSITY_DEFAULT); 00286 else 00287 bdd_dynamic_reordering_zdd_disable(dd); 00288 } 00289 00290 00304 void 00305 SynthSetUseFuncDivisor(int mode) 00306 { 00307 UseFuncDivisor = mode; 00308 } 00309 00310 00322 void 00323 SynthSetOutputOrdering(int mode) 00324 { 00325 OutputOrdering = mode; 00326 } 00327 00328 00340 void 00341 SynthSetCostFactors(float supp, 00342 float prob) 00343 { 00344 SuppFactor = supp; 00345 ProbFactor = prob; 00346 } 00347 00348 00360 void 00361 SynthSetSupportCount(int *count) 00362 { 00363 SupportCount = count; 00364 } 00365 00366 00378 void 00379 SynthSetProbability(float *prob) 00380 { 00381 Probability = prob; 00382 } 00383 00384 00396 int 00397 SynthFindDivisorForLowPower(int *count, 00398 int nvars, 00399 int min_count, 00400 int min_pos) 00401 { 00402 int i, v; 00403 float cost, best; 00404 00405 if ((!SupportCount) || (!Probability)) 00406 return(-1); 00407 00408 v = min_pos; 00409 if (SuppFactor == 0.0 && ProbFactor == 0.0) 00410 best = (float)SupportCount[min_pos] * Probability[min_pos]; 00411 else { 00412 best = (float)SupportCount[min_pos] * SuppFactor + 00413 Probability[min_pos] * ProbFactor; 00414 } 00415 00416 for (i = min_pos + 1; i < nvars; i++) { 00417 if (count[i] == min_count) { 00418 if (SuppFactor == 0.0 && ProbFactor == 0.0) 00419 cost = (float)SupportCount[i] * Probability[i]; 00420 else { 00421 cost = (float)SupportCount[i] * SuppFactor + 00422 Probability[i] * ProbFactor; 00423 } 00424 if (cost > best) { 00425 best = cost; 00426 v = i; 00427 } 00428 } 00429 } 00430 00431 return(v); 00432 } 00433 00434 00446 char * 00447 SynthGetIthOutputName(int i) 00448 { 00449 return outputNames[i]; 00450 } 00451 00452 00472 int 00473 SynthIsSubsetOfSupport(int size, 00474 unsigned int *mask1, 00475 unsigned int *mask2) 00476 { 00477 int i, tmp, flag = 0; 00478 00479 if (!mask2) 00480 return(1); 00481 00482 if (IsNullSupport(size, mask1) && IsNullSupport(size, mask2)) 00483 return(0); 00484 else if (IsNullSupport(size, mask1)) 00485 return(0); 00486 else if (IsNullSupport(size, mask2)) 00487 return(1); 00488 00489 for (i = 0; i < size; i++) { 00490 tmp = IsSubsetOfSupportForOneWord(mask1[i], mask2[i]); 00491 if (tmp == 0) 00492 return(0); 00493 flag |= tmp; 00494 } 00495 00496 return(flag); 00497 } 00498 00499 00500 /*---------------------------------------------------------------------------*/ 00501 /* Definition of static functions */ 00502 /*---------------------------------------------------------------------------*/ 00503 00524 static void 00525 GetOutputOrder(bdd_manager *dd, 00526 bdd_node **ofuncs, 00527 int no, 00528 int *order, 00529 int verbosity) 00530 { 00531 int i, j, k, flag; 00532 int *support, *bddsize; 00533 int size; 00534 unsigned int **mask; 00535 int word, sizeZ; 00536 int pos, bit, bit_mask; 00537 int insert_flag, s1, s2; 00538 00539 if (no == 1) { 00540 order[0] = 0; 00541 return; 00542 } 00543 00544 if (OutputOrdering == 0) { 00545 for (i = 0; i < no; i++) 00546 order[i] = i; 00547 return; 00548 } 00549 00550 bddsize = ALLOC(int, no); 00551 if (OutputOrdering == 2) { 00552 for (i = 0; i < no; i++) { 00553 if (!ofuncs[i]) { 00554 order[i] = i; 00555 bddsize[i] = 0; 00556 continue; 00557 } 00558 00559 bddsize[i] = bdd_node_size(ofuncs[i]); 00560 00561 /* Insert i-th output at the right place in the order. */ 00562 for (j = 0; j < i; j++) { 00563 if (bddsize[i] < bddsize[order[j]]) { 00564 for (k = i; k > j; k--) 00565 order[k] = order[k - 1]; 00566 order[j] = i; 00567 break; 00568 } 00569 } 00570 00571 if (j == i) 00572 order[i] = i; 00573 } 00574 00575 if (verbosity) { 00576 fprintf(vis_stdout, "output order :"); 00577 for (i = 0; i < no; i++) 00578 fprintf(vis_stdout, " %d", order[i]); 00579 fprintf(vis_stdout, "\n"); 00580 if (verbosity > 1) { 00581 for (i = 0; i < no; i++) 00582 fprintf(vis_stdout, "%d - %d", i, bddsize[i]); 00583 } 00584 } 00585 00586 FREE(bddsize); 00587 return; 00588 } 00589 00590 /* Here OutputOrdering should be 1. */ 00591 mask = ALLOC(unsigned int *, no); 00592 sizeZ = bdd_num_zdd_vars(dd); 00593 support = ALLOC(int, sizeZ); 00594 word = sizeof(int) * 8; 00595 size = sizeZ / word + 1; 00596 00597 for (i = 0; i < no; i++) { 00598 if (!ofuncs[i]) { 00599 mask[i] = (unsigned int *)NULL; 00600 order[i] = i; 00601 bddsize[i] = 0; 00602 continue; 00603 } 00604 00605 mask[i] = ALLOC(unsigned int, size); 00606 (void)memset((void *)mask[i], 0, size * sizeof(int)); 00607 (void)memset((void *)support, 0, sizeof(int) * sizeZ); 00608 SynthZddSupportStep(bdd_regular(ofuncs[i]), support); 00609 SynthZddClearFlag(bdd_regular(ofuncs[i])); 00610 /* Pack the support array into a bit vector. */ 00611 for (j = 0; j < sizeZ; j++) { 00612 if (support[j]) { 00613 pos = j / word; 00614 bit = j % word; 00615 bit_mask = 01 << bit; 00616 mask[i][pos] |= bit_mask; 00617 } 00618 } 00619 bddsize[i] = bdd_node_size(ofuncs[i]); 00620 00621 for (j = 0; j < i; j++) { 00622 insert_flag = 0; 00623 flag = SynthIsSubsetOfSupport(size, mask[i], mask[order[j]]); 00624 if (flag == 1) 00625 insert_flag = 1; 00626 else if (flag == 2) { 00627 s1 = GetNumberOfSupport(sizeZ, size, mask[i]); 00628 s2 = GetNumberOfSupport(sizeZ, size, mask[order[j]]); 00629 if (s1 < s2 || (s1 == s2 && bddsize[i] < bddsize[order[j]])) 00630 insert_flag = 1; 00631 } 00632 if (insert_flag) { 00633 for (k = i; k > j; k--) 00634 order[k] = order[k - 1]; 00635 order[j] = i; 00636 break; 00637 } 00638 } 00639 00640 if (j == i) 00641 order[i] = i; 00642 } 00643 FREE(support); 00644 FREE(bddsize); 00645 00646 if (verbosity) { 00647 fprintf(vis_stdout, "output order :"); 00648 for (i = 0; i < no; i++) 00649 fprintf(vis_stdout, " %d", order[i]); 00650 fprintf(vis_stdout, "\n"); 00651 if (verbosity > 1) { 00652 for (i = 0; i < no; i++) { 00653 if (mask[i]) 00654 PrintSupportMask(sizeZ, size, mask[i]); 00655 } 00656 } 00657 } 00658 00659 for (i = 0; i < no; i++) { 00660 if (mask[i]) 00661 FREE(mask[i]); 00662 } 00663 FREE(mask); 00664 } 00665 00666 00681 static int 00682 IsSubsetOfSupportForOneWord(unsigned int mask1, 00683 unsigned int mask2) 00684 { 00685 unsigned int tmp; 00686 00687 if (mask1 == mask2) 00688 return(2); 00689 00690 tmp = mask1 | mask2; 00691 if (tmp != mask2) 00692 return(0); 00693 return(1); 00694 } 00695 00696 00708 static int 00709 IsNullSupport(int size, 00710 unsigned int *mask) 00711 { 00712 int i; 00713 00714 for (i = 0; i < size; i++) { 00715 if (mask[i] != 0) 00716 return(0); 00717 } 00718 return(1); 00719 } 00720 00721 00736 static void 00737 PrintSupportMask(int n, 00738 int size, 00739 unsigned int *mask) 00740 { 00741 int i, j, pos, last; 00742 char *support; 00743 char *mark; 00744 int bit; 00745 00746 support = ALLOC(char,n); 00747 mark = ALLOC(char,n); 00748 00749 pos = 0; 00750 for (i = 0; i < size; i++) { 00751 if (i == (size - 1)) 00752 last = n % 32; 00753 else 00754 last = 32; 00755 bit = 01; 00756 for (j = 0; j < last; j++) { 00757 sprintf(&mark[pos], "%d", pos % 10); 00758 if (mask[i] & bit) 00759 support[pos] = '1'; 00760 else 00761 support[pos] = '0'; 00762 pos++; 00763 bit = bit << 1; 00764 } 00765 } 00766 mark[pos] = support[pos] = '\0'; 00767 00768 fprintf(vis_stdout, "%s\n", mark); 00769 fprintf(vis_stdout, "%s\n", support); 00770 00771 FREE(support); 00772 FREE(mark); 00773 } 00774 00775 00787 static int 00788 GetNumberOfSupport(int n, 00789 int size, 00790 unsigned int *mask) 00791 { 00792 int i, j, last; 00793 int bit; 00794 int count; 00795 00796 count = 0; 00797 for (i = 0; i < size; i++) { 00798 if (i == (size - 1)) 00799 last = n % 32; 00800 else 00801 last = 32; 00802 bit = 01; 00803 for (j = 0; j < last; j++) { 00804 if (mask[i] & bit) 00805 count++; 00806 bit = bit << 1; 00807 } 00808 } 00809 return(count); 00810 } 00811 00812 00825 static int 00826 factorizeNetwork(Ntk_Network_t *net, 00827 bdd_manager *dd, 00828 bdd_node **ofuncs, 00829 MlTree **tree, 00830 int no, 00831 int *out_order, 00832 st_table *table, 00833 char **combOutNames, 00834 int divisor, 00835 MlTree *(* factoring_func)(bdd_manager *, st_table *, 00836 bdd_node *, int, int *, MlTree *, 00837 int, MlTree *, int), 00838 int verbosity) 00839 { 00840 int i, j, k; 00841 int ref; 00842 int nml; 00843 MlTree *tmp_tree; 00844 int flag; 00845 int comp_flag; 00846 00847 SynthSetZddDivisorFunc(divisor); /* set static variable in synthFactor.c */ 00848 00849 for (k = 0; k < no; k++) { 00850 i = out_order[k]; 00851 if (!ofuncs[i]) { 00852 tree[i] = NULL; 00853 continue; 00854 } 00855 if (verbosity) 00856 SynthPrintZddCoverWithName(net, dd, ofuncs[i]); 00857 00858 tree[i] = (MlTree *)NULL; 00859 ref = 0; 00860 if (ofuncs[i] == bdd_read_one(dd) || ofuncs[i] == bdd_read_zero(dd)) { 00861 tree[i] = SynthFindOrCreateMlTree(table, dd, ofuncs[i], 1, 0, 00862 &ref, verbosity); 00863 if (!tree[i]) 00864 return(1); 00865 } else { 00866 tree[i] = SynthLookupMlTable(table, dd, ofuncs[i], 1, verbosity); 00867 if (tree[i]) { 00868 if (MlTree_IsComplement(tree[i]) || tree[i]->top) 00869 ref = 1; 00870 else 00871 SynthUpdateRefOfParent(tree[i]); 00872 } 00873 else if (UseFuncDivisor) { 00874 /* Try to divide by existing functions. The smaller 00875 * functions are factored first to increase the probability 00876 * of success of this step. Both phases of the divisor are 00877 * tried. 00878 */ 00879 for (j = k - 1; j >= 0; j--) { 00880 tree[i] = (* factoring_func)(dd, table, ofuncs[i], 0, &ref, 00881 tree[out_order[j]], 0, NULL, verbosity); 00882 if (tree[i]) { 00883 SynthSetSharedFlag(dd, tree[out_order[j]]); 00884 break; 00885 } else if (noMemoryFlag == 1) 00886 return(1); 00887 else { 00888 tree[i] = (* factoring_func)(dd, table, ofuncs[i], 0, 00889 &ref, tree[out_order[j]], 1, NULL, verbosity); 00890 if (tree[i]) { 00891 SynthSetSharedFlag(dd, tree[out_order[j]]); 00892 break; 00893 } else if (noMemoryFlag == 1) 00894 return(1); 00895 } 00896 } 00897 } 00898 } 00899 /* Division by other functions did not work. Find a brand-new 00900 * factorization. 00901 */ 00902 if (!tree[i]) { 00903 tree[i] = (* factoring_func)(dd, table, ofuncs[i], 0, 00904 &ref, NULL, 0, NULL, verbosity); 00905 if (!tree[i]) 00906 return(1); 00907 } 00908 /* Compute the complement ZDD node of ofuncs[i], if not exist. 00909 * This is to increase sharing. 00910 */ 00911 tmp_tree = tree[i]; 00912 tree[i] = SynthCheckAndMakeComplement(dd, table, tree[i], &comp_flag, 00913 verbosity); 00914 if (!tree[i]) 00915 return(1); 00916 else if (tree[i] != tmp_tree) { 00917 ref = 1; 00918 if (comp_flag) 00919 tree[i] = MlTree_Not(tree[i]); 00920 } 00921 00922 /* When the tree already exists, create a new tree and copy all 00923 * contents, and set the field 'ref' to 1. This is for the 00924 * purpose of avoiding duplicate literal counting. 00925 */ 00926 if (ref) { 00927 int comp_flag; 00928 00929 comp_flag = 0; 00930 if (MlTree_IsComplement(tree[i])) { 00931 tree[i] = MlTree_Not(tree[i]); 00932 comp_flag = 1; 00933 } 00934 tmp_tree = ALLOC(MlTree, sizeof(MlTree)); 00935 memcpy((void *)tmp_tree, (void *)tree[i], sizeof(MlTree)); 00936 tree[i] = tmp_tree; 00937 tree[i]->ref = 1; 00938 tree[i]->comp = comp_flag; 00939 } 00940 tree[i]->top = 1; 00941 bdd_ref(tree[i]->node); 00942 00943 nml = SynthCountMlLiteral(dd, tree[i], 1); 00944 00945 if (verbosity) { 00946 SynthPrintMlTreeWithName(net, dd, tree[i], "result : "); 00947 fprintf(vis_stdout, "**** %d (#literal = %d) ****\n", i, nml); 00948 if (verbosity > 1) 00949 SynthWriteEqn(stdout, net, dd, tree[i], ofuncs, combOutNames[i], 1); 00950 } 00951 00952 if (VerifyTreeMode) { 00953 SynthVerifyTree(dd, tree[i], 1); 00954 SynthVerifyMlTable(dd, table); 00955 } 00956 } 00957 00958 flag = SynthPostFactoring(dd, table, factoring_func, verbosity); 00959 00960 if (VerifyTreeMode) { 00961 bdd_node *tmp; 00962 00963 for (i = 0; i < no; i++) { 00964 if (tree[i]->comp) 00965 tmp = tree[i]->complement; 00966 else 00967 tmp = tree[i]->node; 00968 if (tmp != ofuncs[i]) { 00969 (void) fprintf(vis_stdout, 00970 "** synth error: Different zdds in [%s].\n", 00971 combOutNames[i]); 00972 } 00973 SynthVerifyTree(dd, tree[i], 1); 00974 } 00975 } 00976 00977 return(flag); 00978 }