VIS
|
00001 00032 #include "ordInt.h" 00033 00034 static char rcsid[] UNUSED = "$Id: ordCmd.c,v 1.37 2005/05/19 03:22:55 awedh Exp $"; 00035 00036 /*---------------------------------------------------------------------------*/ 00037 /* Variable declarations */ 00038 /*---------------------------------------------------------------------------*/ 00039 static jmp_buf timeOutEnv; 00040 00041 00044 /*---------------------------------------------------------------------------*/ 00045 /* Static function prototypes */ 00046 /*---------------------------------------------------------------------------*/ 00047 00048 static int CommandStaticOrder(Hrc_Manager_t ** hmgr, int argc, char ** argv); 00049 static int CommandReadOrder(Hrc_Manager_t ** hmgr, int argc, char ** argv); 00050 static int CommandWriteOrder(Hrc_Manager_t ** hmgr, int argc, char ** argv); 00051 static int CommandDynamicVarOrdering(Hrc_Manager_t ** hmgr, int argc, char ** argv); 00052 static int CommandPrintBddStats(Hrc_Manager_t ** hmgr, int argc, char ** argv); 00053 static Ord_OrderType StringConvertToOrderType(char *string); 00054 static bdd_reorder_type_t StringConvertToDynOrderType(char *string); 00055 static char * DynOrderTypeConvertToString(bdd_reorder_type_t method); 00056 static boolean NetworkCheckSuppliedNodeList(Ntk_Network_t * network, lsList suppliedNodeList, Ord_OrderType orderType); 00057 static void TimeOutHandle(void); 00058 00062 /*---------------------------------------------------------------------------*/ 00063 /* Definition of exported functions */ 00064 /*---------------------------------------------------------------------------*/ 00065 00075 void 00076 Ord_Init(void) 00077 { 00078 Cmd_CommandAdd("static_order", CommandStaticOrder, 0); 00079 Cmd_CommandAdd("read_order", CommandReadOrder, 0); 00080 Cmd_CommandAdd("write_order", CommandWriteOrder, 0); 00081 Cmd_CommandAdd("dynamic_var_ordering", CommandDynamicVarOrdering, 0); 00082 Cmd_CommandAdd("print_bdd_stats", CommandPrintBddStats, 0); 00083 } 00084 00085 00095 void 00096 Ord_End(void) 00097 { 00098 } 00099 00100 00117 boolean 00118 Ord_NetworkTestAreVariablesOrdered( 00119 Ntk_Network_t * network, 00120 Ord_OrderType orderType) 00121 { 00122 lsGen gen; 00123 Ntk_Node_t *node; 00124 mdd_manager *mddManager = Ntk_NetworkReadMddManager(network); 00125 00126 assert((orderType == Ord_All_c) || (orderType == Ord_InputAndLatch_c) 00127 || (orderType == Ord_NextStateNode_c)); 00128 00129 if (mddManager == NIL(mdd_manager)) { 00130 error_append("network doesn't have an MDD manager\n"); 00131 return 0; 00132 } 00133 00134 /* 00135 * Next state nodes are included by all 3 order types. 00136 */ 00137 Ntk_NetworkForEachNode(network, gen, node) { 00138 if ((orderType == Ord_All_c) || Ntk_NodeTestIsNextStateNode(node)) { 00139 if (Ntk_NodeReadMddId(node) == NTK_UNASSIGNED_MDD_ID) { 00140 error_append("node "); 00141 error_append(Ntk_NodeReadName(node)); 00142 error_append(" not ordered\n"); 00143 (void) lsFinish(gen); 00144 return 0; 00145 } 00146 } 00147 else if ((orderType == Ord_InputAndLatch_c) 00148 && Ntk_NodeTestIsCombInput(node)) { 00149 if (Ntk_NodeReadMddId(node) == NTK_UNASSIGNED_MDD_ID) { 00150 error_append("node "); 00151 error_append(Ntk_NodeReadName(node)); 00152 error_append(" not ordered\n"); 00153 (void) lsFinish(gen); 00154 return 0; 00155 } 00156 } 00157 /* else, this node is not included by orderType */ 00158 } 00159 00160 return 1; 00161 } 00162 00163 00164 /*---------------------------------------------------------------------------*/ 00165 /* Definition of internal functions */ 00166 /*---------------------------------------------------------------------------*/ 00167 00168 00169 /*---------------------------------------------------------------------------*/ 00170 /* Definition of static functions */ 00171 /*---------------------------------------------------------------------------*/ 00172 00372 static int 00373 CommandStaticOrder( 00374 Hrc_Manager_t ** hmgr, 00375 int argc, 00376 char ** argv) 00377 { 00378 int c; 00379 FILE *fp; 00380 static int timeOutPeriod; 00381 static int verbose; 00382 static Ord_NodeMethod nodeMethod; 00383 static Ord_RootMethod rootMethod; 00384 static Ord_OrderType suppliedOrderType; 00385 static Ord_OrderType generatedOrderType; 00386 static boolean nsAfterSupport; 00387 lsList suppliedNodeList = (lsList) NULL; 00388 /* list of Ntk_Node_t * */ 00389 Ntk_Network_t *network; 00390 00391 /* 00392 * These are the default values. These variables must be declared static 00393 * to avoid lint warnings. Since they are static, we must reinitialize 00394 * them outside of the variable declarations. 00395 */ 00396 timeOutPeriod = 0; 00397 verbose = 0; 00398 nodeMethod = Ord_NodesByDefault_c; 00399 rootMethod = Ord_RootsByDefault_c; 00400 suppliedOrderType = Ord_Unassigned_c; /* default */ 00401 generatedOrderType = Ord_InputAndLatch_c;/* default */ 00402 nsAfterSupport = FALSE; /* default */ 00403 00404 /* 00405 * Parse the command line. 00406 */ 00407 util_getopt_reset(); 00408 while ((c = util_getopt(argc, argv, "av:o:s:t:n:r:h")) != EOF) { 00409 switch (c) { 00410 case 'a': 00411 nsAfterSupport = TRUE; 00412 break; 00413 case 'h': 00414 goto usage; 00415 case 'v': 00416 verbose = atoi(util_optarg); 00417 break; 00418 case 't': 00419 timeOutPeriod = atoi(util_optarg); 00420 break; 00421 case 'o': 00422 generatedOrderType = StringConvertToOrderType(util_optarg); 00423 if ((generatedOrderType == Ord_NextStateNode_c) 00424 || (generatedOrderType == Ord_Partial_c)) { 00425 (void) fprintf(vis_stderr, "disallowed output order type: %s\n", util_optarg); 00426 goto usage; 00427 } 00428 else if (generatedOrderType == Ord_Unassigned_c) { 00429 (void) fprintf(vis_stderr, "unknown output order type: %s\n", util_optarg); 00430 goto usage; 00431 } 00432 break; 00433 case 's': 00434 suppliedOrderType = StringConvertToOrderType(util_optarg); 00435 if (suppliedOrderType == Ord_Unassigned_c) { 00436 (void) fprintf(vis_stderr, "unknown input order type: %s\n", util_optarg); 00437 goto usage; 00438 } 00439 break; 00440 case 'n': 00441 if (strcmp("interleave", util_optarg) == 0) { 00442 nodeMethod = Ord_NodesByInterleaving_c; 00443 } 00444 else if (strcmp("merge_left", util_optarg) == 0) { 00445 nodeMethod = Ord_NodesByMergingLeft_c; 00446 } 00447 else if (strcmp("merge_right", util_optarg) == 0) { 00448 nodeMethod = Ord_NodesByMergingRight_c; 00449 } 00450 else if (strcmp("append", util_optarg) == 0) { 00451 nodeMethod = Ord_NodesByAppending_c; 00452 } 00453 else { 00454 (void) fprintf(vis_stderr, "unknown node order method: %s\n", util_optarg); 00455 goto usage; 00456 } 00457 break; 00458 case 'r': 00459 if (strcmp("depth", util_optarg) == 0) { 00460 rootMethod = Ord_RootsByDepth_c; 00461 } 00462 else if (strcmp("mincomm", util_optarg) == 0) { 00463 rootMethod = Ord_RootsByPerm_c; 00464 } 00465 else { 00466 (void) fprintf(vis_stderr, "unknown root order method: %s\n", util_optarg); 00467 goto usage; 00468 } 00469 break; 00470 default: 00471 goto usage; 00472 } 00473 } 00474 00475 network = Ntk_HrcManagerReadCurrentNetwork(*hmgr); 00476 if (network == NIL(Ntk_Network_t)) { 00477 return 1; 00478 } 00479 00480 if ((suppliedOrderType == Ord_InputAndLatch_c) && (generatedOrderType == Ord_All_c)) { 00481 (void) fprintf(vis_stderr, "-o all -s input_and_latch not currently supported\n"); 00482 return 1; 00483 } 00484 00485 /* 00486 * The minimum set of variables that can be ordered are those specified by 00487 * Ord_InputAndLatch_c. If these have already been ordered, then just return. 00488 */ 00489 if (Ord_NetworkTestAreVariablesOrdered(network, Ord_InputAndLatch_c)) { 00490 (void) fprintf(vis_stderr, "Variables already ordered. "); 00491 (void) fprintf(vis_stderr, "Reinvoke flatten_hierarchy to undo variable ordering.\n"); 00492 return 1; 00493 } 00494 00495 00496 /* 00497 * Process the input ordering file. 00498 */ 00499 if (suppliedOrderType == Ord_Unassigned_c) { 00500 if (argc - util_optind > 0) { 00501 (void) fprintf(vis_stderr, "must specify -s if supplying order file\n"); 00502 goto usage; 00503 } 00504 } 00505 else { 00506 if (argc - util_optind == 0) { 00507 (void) fprintf(vis_stderr, "order file not provided\n"); 00508 goto usage; 00509 } 00510 else if (argc - util_optind > 1) { 00511 (void) fprintf(vis_stderr, "too many arguments\n"); 00512 goto usage; 00513 } 00514 00515 fp = Cmd_FileOpen(argv[util_optind], "r", NIL(char *), 0); 00516 if (fp == NIL(FILE)) { 00517 (void) fprintf(vis_stderr, "File %s is not readable, please check if it exists\n", argv[util_optind]); 00518 return 1; 00519 } 00520 else { 00521 boolean status; 00522 00523 error_init(); 00524 status = Ord_FileReadNodeList(fp, network, &suppliedNodeList, verbose); 00525 if (status == FALSE) { 00526 (void) fprintf(vis_stderr, "Error reading ordering file:\n"); 00527 (void) fprintf(vis_stderr, "%s", error_string()); 00528 (void) fprintf(vis_stderr, "Cannot perform static ordering.\n"); 00529 (void) fclose(fp); 00530 return 1; 00531 } 00532 else if (NetworkCheckSuppliedNodeList(network, suppliedNodeList, 00533 suppliedOrderType) == FALSE) { 00534 (void) fprintf(vis_stderr, "Incorrect nodes supplied:\n"); 00535 (void) fprintf(vis_stderr, "%s", error_string()); 00536 (void) fprintf(vis_stderr, "Cannot perform static ordering.\n"); 00537 (void) fclose(fp); 00538 (void) lsDestroy(suppliedNodeList, (void (*) (lsGeneric)) NULL); 00539 return 1; 00540 } 00541 else { 00542 (void) fclose(fp); 00543 if (verbose > 0) { 00544 (void) fprintf(vis_stdout, "\nNodes supplied in ordering file, "); 00545 (void) fprintf(vis_stdout, "according to -s option: \n"); 00546 OrdNodeListWrite(vis_stdout, suppliedNodeList); 00547 } 00548 } 00549 } 00550 } 00551 00552 00553 /* 00554 * In order for static ordering to proceed, network must not have any 00555 * combinational cycles. 00556 */ 00557 error_init(); 00558 if(Ntk_NetworkTestIsAcyclic(network) == 0) { 00559 (void) fprintf(vis_stderr, "Combinational cycle found: "); 00560 (void) fprintf(vis_stderr, "%s\n", error_string()); 00561 (void) fprintf(vis_stderr, "cannot perform static ordering\n"); 00562 if (suppliedOrderType != Ord_Unassigned_c) { 00563 (void) lsDestroy(suppliedNodeList, (void (*) (lsGeneric)) NULL); 00564 } 00565 return 1; 00566 } 00567 00568 /* Start the timer before calling the variable ordering routine. */ 00569 if (timeOutPeriod > 0){ 00570 (void) signal(SIGALRM, (void(*)(int))TimeOutHandle); 00571 (void) alarm(timeOutPeriod); 00572 if (setjmp(timeOutEnv) > 0) { 00573 (void) fprintf(vis_stderr, "Timeout occurred after %d seconds.\n", timeOutPeriod); 00574 alarm(0); 00575 return 1; 00576 } 00577 } 00578 00579 /* 00580 * Order the variables. 00581 */ 00582 Ord_NetworkOrderVariables(network, rootMethod, nodeMethod, nsAfterSupport, 00583 generatedOrderType, suppliedOrderType, 00584 suppliedNodeList, verbose); 00585 00586 if (suppliedOrderType != Ord_Unassigned_c) { 00587 (void) lsDestroy(suppliedNodeList, (void (*) (lsGeneric)) NULL); 00588 } 00589 00590 /* 00591 * As a sanity check, make sure that all the variables in generatedOrderType 00592 * have an MDD id. 00593 */ 00594 assert(Ord_NetworkTestAreVariablesOrdered(network, generatedOrderType)); 00595 00596 alarm(0); 00597 return 0; /* Everything okay */ 00598 00599 usage: 00600 (void) fprintf(vis_stderr, "usage: static_order [-a] [-h] [-n method] [-o type] [-r method] -s type [-t time] [-v #] file\n"); 00601 (void) fprintf(vis_stderr, " -a order NS variables after support\n"); 00602 (void) fprintf(vis_stderr, " -h print the command usage\n"); 00603 (void) fprintf(vis_stderr, " -n method node ordering method\n"); 00604 (void) fprintf(vis_stderr, " (interleave (default), append, merge_left, merge_right)\n"); 00605 (void) fprintf(vis_stderr, " -o type nodes to order (all, input_and_latch (default))\n"); 00606 (void) fprintf(vis_stderr, " -r method root ordering method (depth, mincomm (default for < 30 latches))\n"); 00607 (void) fprintf(vis_stderr, " -s type nodes in file (all, input_and_latch, next_state_node, partial)\n"); 00608 (void) fprintf(vis_stderr, " -t time time out period (in seconds)\n"); 00609 (void) fprintf(vis_stderr, " -v # verbosity level\n"); 00610 (void) fprintf(vis_stderr, " file supplied ordering of nodes\n"); 00611 00612 return 1; 00613 } 00614 00615 00673 static int 00674 CommandReadOrder( 00675 Hrc_Manager_t ** hmgr, 00676 int argc, 00677 char ** argv) 00678 { 00679 int c, status; 00680 FILE *fp; 00681 int verbose = 0; 00682 int group = 0; 00683 lsList suppliedNodeList = (lsList)NULL; /* list of Ntk_Node_t * */ 00684 Ntk_Network_t *network; 00685 mdd_manager *mddMgr; 00686 00687 if (bdd_get_package_name() != CUDD) { 00688 fprintf(vis_stderr, 00689 "** ord error: read_order can be used only with the CUDD package\n"); 00690 } 00691 00692 /* 00693 * Parse the command line. 00694 */ 00695 util_getopt_reset(); 00696 while ((c = util_getopt(argc, argv, "hg:v")) != EOF) { 00697 switch (c) { 00698 case 'h': 00699 goto usage; 00700 case 'g': 00701 group = atoi(util_optarg); 00702 break; 00703 case 'v': 00704 verbose = 1; 00705 break; 00706 default: 00707 goto usage; 00708 } 00709 } 00710 00711 network = Ntk_HrcManagerReadCurrentNetwork(*hmgr); 00712 if (network == NIL(Ntk_Network_t)) { 00713 return 1; 00714 } 00715 00716 if (!Ord_NetworkTestAreVariablesOrdered(network, Ord_InputAndLatch_c)) { 00717 (void) fprintf(vis_stderr, 00718 "** ord error: static_order was not called yet.\n"); 00719 return 1; 00720 } 00721 00722 /* 00723 * Process the input ordering file. 00724 */ 00725 if (argc - util_optind == 0) { 00726 (void) fprintf(vis_stderr, "order file not provided\n"); 00727 goto usage; 00728 } 00729 else if (argc - util_optind > 1) { 00730 (void) fprintf(vis_stderr, "too many arguments\n"); 00731 goto usage; 00732 } 00733 00734 fp = Cmd_FileOpen(argv[util_optind], "r", NIL(char *), 0); 00735 if (fp == NIL(FILE)) { 00736 return 1; 00737 } else { 00738 boolean status; 00739 00740 error_init(); 00741 status = Ord_FileReadNodeList(fp, network, &suppliedNodeList, verbose); 00742 if (status == FALSE) { 00743 (void) fprintf(vis_stderr, "Error reading ordering file:\n"); 00744 (void) fprintf(vis_stderr, "%s", error_string()); 00745 (void) fprintf(vis_stderr, "Cannot perform static ordering.\n"); 00746 (void) fclose(fp); 00747 return 1; 00748 } else if (NetworkCheckSuppliedNodeList(network, suppliedNodeList, 00749 Ord_InputAndLatch_c) == FALSE) { 00750 (void) fprintf(vis_stderr, "Incorrect nodes supplied:\n"); 00751 (void) fprintf(vis_stderr, "%s", error_string()); 00752 (void) fprintf(vis_stderr, "Cannot perform read_order.\n"); 00753 (void) fclose(fp); 00754 (void) lsDestroy(suppliedNodeList, (void (*) (lsGeneric)) NULL); 00755 return 1; 00756 } else { 00757 (void) fclose(fp); 00758 if (verbose > 0) { 00759 (void) fprintf(vis_stdout, "\nNew variable order from file %s:\n", 00760 argv[util_optind]); 00761 OrdNodeListWrite(vis_stdout, suppliedNodeList); 00762 } 00763 } 00764 } 00765 00766 /* 00767 * Reorder the variables. 00768 */ 00769 mddMgr = Ntk_NetworkReadMddManager(network); 00770 status = OrdMakeNewVariableOrder(mddMgr, suppliedNodeList, group, verbose); 00771 00772 (void) lsDestroy(suppliedNodeList, (void (*) (lsGeneric)) NULL); 00773 if (status) 00774 return 1; 00775 00776 alarm(0); 00777 return 0; /* Everything okay */ 00778 00779 usage: 00780 (void) fprintf(vis_stderr, "usage: read_order [-g #] [-h] [-v] file\n"); 00781 (void) fprintf(vis_stderr, " -h print the command usage\n"); 00782 (void) fprintf(vis_stderr, " -g # ps/ns variables grouping\n"); 00783 (void) fprintf(vis_stderr, " 0 : do not group ps/ns\n"); 00784 (void) fprintf(vis_stderr, " 1 : group ps/ns (default)\n"); 00785 (void) fprintf(vis_stderr, " -v verbosity on\n"); 00786 (void) fprintf(vis_stderr, " file variable order file\n"); 00787 00788 return 1; 00789 } 00790 00791 00864 static int 00865 CommandWriteOrder( 00866 Hrc_Manager_t ** hmgr, 00867 int argc, 00868 char ** argv) 00869 { 00870 int c; 00871 FILE *fp; 00872 int status; 00873 Ord_OrderType orderType = Ord_InputAndLatch_c; /* default */ 00874 Ntk_Network_t *network; 00875 00876 /* 00877 * Parse the command line. 00878 */ 00879 util_getopt_reset(); 00880 while ((c = util_getopt(argc, argv, "ho:")) != EOF) { 00881 switch (c) { 00882 case 'h': 00883 goto usage; 00884 case 'o': 00885 orderType = StringConvertToOrderType(util_optarg); 00886 if (orderType == Ord_Partial_c) { 00887 (void) fprintf(vis_stderr, "disallowed output order type: %s\n", util_optarg); 00888 goto usage; 00889 } 00890 else if (orderType == Ord_Unassigned_c) { 00891 (void) fprintf(vis_stderr, "unknown output order type: %s\n", util_optarg); 00892 goto usage; 00893 } 00894 break; 00895 default: 00896 goto usage; 00897 } 00898 } 00899 00900 network = Ntk_HrcManagerReadCurrentNetwork(*hmgr); 00901 if (network == NIL(Ntk_Network_t)) { 00902 return 1; 00903 } 00904 00905 /* 00906 * Open the destination file. 00907 */ 00908 if (argc - util_optind == 0) { 00909 fp = Cmd_FileOpen("-", "w", NIL(char *), /* silent */0); 00910 } 00911 else if (argc - util_optind == 1) { 00912 fp = Cmd_FileOpen(argv[util_optind], "w", NIL(char *), /* silent */0); 00913 } 00914 else { 00915 goto usage; 00916 } 00917 if (fp == NIL(FILE)) { 00918 return 1; 00919 } 00920 00921 error_init(); 00922 if (Ord_NetworkPrintVariableOrder(fp, network, orderType) == 0) { 00923 (void) fprintf(vis_stderr, "Not all nodes are ordered: "); 00924 (void) fprintf(vis_stderr, "%s", error_string()); 00925 status = 1; 00926 } 00927 else { 00928 status = 0; /* success */ 00929 } 00930 00931 if (fp != stdout) { 00932 (void) fclose(fp); 00933 } 00934 return (status); 00935 00936 usage: 00937 (void) fprintf(vis_stderr, "usage: write_order [-h] [-o type] [file]\n"); 00938 (void) fprintf(vis_stderr, " -h print the command usage\n"); 00939 (void) fprintf(vis_stderr, " -o type nodes to write (all, input_and_latch (default), next_state_node)\n"); 00940 (void) fprintf(vis_stderr, " file output file name\n"); 00941 00942 return 1; 00943 } 00944 00945 01088 static int 01089 CommandDynamicVarOrdering( 01090 Hrc_Manager_t ** hmgr, 01091 int argc, 01092 char ** argv) 01093 { 01094 int c; 01095 bdd_reorder_type_t currentMethod; 01096 bdd_reorder_type_t dynOrderingMethod = BDD_REORDER_NONE; /* for lint */ 01097 boolean disableFlag = FALSE; 01098 boolean enableFlag = FALSE; 01099 boolean forceFlag = FALSE; 01100 Ntk_Network_t *network; 01101 int verbosityFlag = -1; 01102 bdd_reorder_verbosity_t reorderVerbosity = BDD_REORDER_VERBOSITY_DEFAULT; 01103 01104 /* 01105 * Parse the command line. 01106 */ 01107 util_getopt_reset(); 01108 while ((c = util_getopt(argc, argv, "df:e:hv:")) != EOF) { 01109 switch (c) { 01110 case 'h': 01111 goto usage; 01112 case 'f': 01113 forceFlag = TRUE; 01114 dynOrderingMethod = StringConvertToDynOrderType(util_optarg); 01115 if (dynOrderingMethod == BDD_REORDER_NONE) { 01116 (void) fprintf(vis_stderr, "unknown method: %s\n", util_optarg); 01117 goto usage; 01118 } 01119 break; 01120 case 'e': 01121 enableFlag = TRUE; 01122 dynOrderingMethod = StringConvertToDynOrderType(util_optarg); 01123 if (dynOrderingMethod == BDD_REORDER_NONE) { 01124 (void) fprintf(vis_stderr, "unknown method: %s\n", util_optarg); 01125 goto usage; 01126 } 01127 break; 01128 case 'd': 01129 disableFlag = TRUE; 01130 break; 01131 case 'v': 01132 verbosityFlag = atoi(util_optarg); 01133 break; 01134 default: 01135 goto usage; 01136 } 01137 } 01138 if (c == EOF && argc != util_optind) 01139 goto usage; 01140 01141 switch (verbosityFlag) { 01142 case 0: reorderVerbosity = BDD_REORDER_NO_VERBOSITY; break; 01143 case 1: reorderVerbosity = BDD_REORDER_VERBOSITY; break; 01144 default: reorderVerbosity = BDD_REORDER_VERBOSITY_DEFAULT; break; 01145 } 01146 01147 /* flatten_hierarchy and static_order must have been invoked already. */ 01148 network = Ntk_HrcManagerReadCurrentNetwork(*hmgr); 01149 if (network == NIL(Ntk_Network_t)) { 01150 return 1; 01151 } 01152 if (Ord_NetworkTestAreVariablesOrdered(network, Ord_InputAndLatch_c) == FALSE) { 01153 (void) fprintf(vis_stderr, "The MDD variables have not been ordered. "); 01154 (void) fprintf(vis_stderr, "Use static_order.\n"); 01155 return 1; 01156 } 01157 01158 /* At most one option is allowed. */ 01159 if ((disableFlag && enableFlag) || (disableFlag && forceFlag) 01160 || (enableFlag && forceFlag)) { 01161 (void) fprintf(vis_stderr, "Only one of -d, -f, -e is allowed.\n"); 01162 return 1; 01163 } 01164 01165 /* 01166 * Get the current method for reading and to save in case temporarily 01167 * overwritten. 01168 */ 01169 currentMethod = Ntk_NetworkReadDynamicVarOrderingMethod(network); 01170 01171 /* If no options are given, then just display current status. */ 01172 if (!(disableFlag || enableFlag || forceFlag)) { 01173 if (currentMethod == BDD_REORDER_NONE) { 01174 (void) fprintf(vis_stdout, "Dynamic variable ordering is disabled.\n"); 01175 } 01176 else { 01177 (void) fprintf(vis_stdout, "Dynamic variable ordering is enabled "); 01178 (void) fprintf(vis_stdout, "with method %s.\n", 01179 DynOrderTypeConvertToString(currentMethod)); 01180 } 01181 } 01182 01183 if (disableFlag) { 01184 if (currentMethod == BDD_REORDER_NONE) { 01185 (void) fprintf(vis_stdout, "Dynamic variable ordering is already disabled.\n"); 01186 } 01187 else { 01188 (void) fprintf(vis_stdout, "Dynamic variable ordering is disabled.\n"); 01189 Ntk_NetworkSetDynamicVarOrderingMethod(network, BDD_REORDER_NONE, reorderVerbosity); 01190 } 01191 } 01192 01193 /* 01194 * Set the dynamic ordering method of the network. Note that 01195 * Ntk_NetworkSetDynamicVarOrderingMethod makes the necessary call to 01196 * bdd_dynamic_reordering. 01197 */ 01198 if (enableFlag) { 01199 Ntk_NetworkSetDynamicVarOrderingMethod(network, dynOrderingMethod, 01200 reorderVerbosity); 01201 if (bdd_get_package_name() != CUDD) 01202 dynOrderingMethod = Ntk_NetworkReadDynamicVarOrderingMethod(network); 01203 (void) fprintf(vis_stdout, 01204 "Dynamic variable ordering is enabled with method %s.\n", 01205 DynOrderTypeConvertToString(dynOrderingMethod)); 01206 } 01207 01208 /* 01209 * Force a reordering. Note that the mddManager has to have the method set 01210 * before calling bdd_reorder. This is done via a call to 01211 * Ntk_NetworkSetDynamicVarOrderingMethod with dynOrderingMethod. The value 01212 * of the ordering method is restored afterwards. 01213 */ 01214 if (forceFlag) { 01215 mdd_manager *mddManager = Ntk_NetworkReadMddManager(network); 01216 bdd_reorder_verbosity_t prevReorderVerbosity; 01217 prevReorderVerbosity = bdd_reordering_reporting(mddManager); 01218 01219 (void) fprintf(vis_stdout, "Dynamic variable ordering forced "); 01220 (void) fprintf(vis_stdout, "with method %s....\n", 01221 DynOrderTypeConvertToString(dynOrderingMethod)); 01222 Ntk_NetworkSetDynamicVarOrderingMethod(network, dynOrderingMethod, reorderVerbosity); 01223 bdd_reorder(Ntk_NetworkReadMddManager(network)); 01224 Ntk_NetworkSetDynamicVarOrderingMethod(network, currentMethod, prevReorderVerbosity); 01225 } 01226 01227 return 0; /* Everything okay */ 01228 01229 usage: 01230 (void) fprintf(vis_stderr, "usage: dynamic_var_ordering [-d] [-e method] [-f method] [-h]\n"); 01231 (void) fprintf(vis_stderr, " -d disable dynamic ordering\n"); 01232 (void) fprintf(vis_stderr, " -e method enable dynamic ordering with method (window, sift)\n"); 01233 (void) fprintf(vis_stderr, " -f method force dynamic ordering with method (window, sift)\n"); 01234 (void) fprintf(vis_stderr, " -h print the command usage\n"); 01235 (void) fprintf(vis_stderr, " -v # verbosity level \n"); 01236 01237 return 1; 01238 } 01239 01240 01273 static int 01274 CommandPrintBddStats( 01275 Hrc_Manager_t ** hmgr, 01276 int argc, 01277 char ** argv) 01278 { 01279 int c; 01280 Ntk_Network_t *network; 01281 01282 /* 01283 * Parse the command line. 01284 */ 01285 util_getopt_reset(); 01286 while ((c = util_getopt(argc, argv, "h")) != EOF) { 01287 switch (c) { 01288 case 'h': 01289 goto usage; 01290 default: 01291 goto usage; 01292 } 01293 } 01294 01295 /* flatten_hierarchy and static_order must have been invoked already. */ 01296 network = Ntk_HrcManagerReadCurrentNetwork(*hmgr); 01297 if (network == NIL(Ntk_Network_t)) { 01298 return 1; 01299 } 01300 if (Ord_NetworkTestAreVariablesOrdered(network, Ord_InputAndLatch_c) == FALSE) { 01301 (void) fprintf(vis_stderr, "The MDD variables have not been ordered. "); 01302 (void) fprintf(vis_stderr, "Use static_order.\n"); 01303 return 1; 01304 } 01305 01306 bdd_print_stats(Ntk_NetworkReadMddManager(network), vis_stdout); 01307 01308 return 0; /* Everything okay */ 01309 01310 usage: 01311 (void) fprintf(vis_stderr, "usage: print_bdd_stats [-h]\n"); 01312 (void) fprintf(vis_stderr, " -h print the command usage\n"); 01313 01314 return 1; 01315 } 01316 01317 01328 static Ord_OrderType 01329 StringConvertToOrderType( 01330 char *string) 01331 { 01332 if (strcmp("all", string) == 0) { 01333 return Ord_All_c; 01334 } 01335 else if (strcmp("input_and_latch", string) == 0) { 01336 return Ord_InputAndLatch_c; 01337 } 01338 else if (strcmp("next_state_node", string) == 0) { 01339 return Ord_NextStateNode_c; 01340 } 01341 else if (strcmp("partial", string) == 0) { 01342 return Ord_Partial_c; 01343 } 01344 else { 01345 return Ord_Unassigned_c; 01346 } 01347 } 01348 01349 01360 static bdd_reorder_type_t 01361 StringConvertToDynOrderType( 01362 char *string) 01363 { 01364 if (strcmp("sift", string) == 0) { 01365 return BDD_REORDER_SIFT; 01366 } 01367 else if (strcmp("window", string) == 0) { 01368 return BDD_REORDER_WINDOW; 01369 } 01370 else if (strcmp("random", string) == 0) { 01371 return BDD_REORDER_RANDOM; 01372 } 01373 else if (strcmp("random_pivot", string) == 0) { 01374 return BDD_REORDER_RANDOM_PIVOT; 01375 } 01376 else if (strcmp("sift_converge", string) == 0) { 01377 return BDD_REORDER_SIFT_CONVERGE; 01378 } 01379 else if (strcmp("symmetry_sift", string) == 0) { 01380 return BDD_REORDER_SYMM_SIFT; 01381 } 01382 else if (strcmp("symmetry_sift_converge", string) == 0) { 01383 return BDD_REORDER_SYMM_SIFT_CONV; 01384 } 01385 else if (strcmp("window2", string) == 0) { 01386 return BDD_REORDER_WINDOW2; 01387 } 01388 else if (strcmp("window3", string) == 0) { 01389 return BDD_REORDER_WINDOW3; 01390 } 01391 else if (strcmp("window4", string) == 0) { 01392 return BDD_REORDER_WINDOW4; 01393 } 01394 else if (strcmp("window2_converge", string) == 0) { 01395 return BDD_REORDER_WINDOW2_CONV; 01396 } 01397 else if (strcmp("window3_converge", string) == 0) { 01398 return BDD_REORDER_WINDOW3_CONV; 01399 } 01400 else if (strcmp("window4_converge", string) == 0) { 01401 return BDD_REORDER_WINDOW4_CONV; 01402 } 01403 else if (strcmp("group_sift", string) == 0) { 01404 return BDD_REORDER_GROUP_SIFT; 01405 } 01406 else if (strcmp("group_sift_converge", string) == 0) { 01407 return BDD_REORDER_GROUP_SIFT_CONV; 01408 } 01409 else if (strcmp("annealing", string) == 0) { 01410 return BDD_REORDER_ANNEALING; 01411 } 01412 else if (strcmp("genetic", string) == 0) { 01413 return BDD_REORDER_GENETIC; 01414 } 01415 else if (strcmp("exact", string) == 0) { 01416 return BDD_REORDER_EXACT; 01417 } 01418 else if (strcmp("lazy_sift", string) == 0) { 01419 return BDD_REORDER_LAZY_SIFT; 01420 } 01421 else { 01422 return BDD_REORDER_NONE; 01423 } 01424 } 01425 01426 01437 static char * 01438 DynOrderTypeConvertToString( 01439 bdd_reorder_type_t method) 01440 { 01441 if (method == BDD_REORDER_SIFT) { 01442 return "sift"; 01443 } 01444 else if (method == BDD_REORDER_WINDOW) { 01445 return "window"; 01446 } 01447 else if (method == BDD_REORDER_NONE) { 01448 return "none"; 01449 } 01450 else if (method == BDD_REORDER_RANDOM) { 01451 return "random"; 01452 } 01453 else if (method == BDD_REORDER_RANDOM_PIVOT) { 01454 return "random_pivot"; 01455 } 01456 else if (method == BDD_REORDER_SIFT_CONVERGE) { 01457 return "sift_converge"; 01458 } 01459 else if (method == BDD_REORDER_SYMM_SIFT) { 01460 return "symmetry_sift"; 01461 } 01462 else if (method == BDD_REORDER_SYMM_SIFT_CONV) { 01463 return "symmetry_sift_converge"; 01464 } 01465 else if (method == BDD_REORDER_WINDOW2) { 01466 return "window2"; 01467 } 01468 else if (method == BDD_REORDER_WINDOW3) { 01469 return "window3"; 01470 } 01471 else if (method == BDD_REORDER_WINDOW4) { 01472 return "window4"; 01473 } 01474 else if (method == BDD_REORDER_WINDOW2_CONV) { 01475 return "window2_converge"; 01476 } 01477 else if (method == BDD_REORDER_WINDOW3_CONV) { 01478 return "window3_converge"; 01479 } 01480 else if (method == BDD_REORDER_WINDOW4_CONV) { 01481 return "window4_converge"; 01482 } 01483 else if (method == BDD_REORDER_GROUP_SIFT) { 01484 return "group_sift"; 01485 } 01486 else if (method == BDD_REORDER_GROUP_SIFT_CONV) { 01487 return "group_sift_converge"; 01488 } 01489 else if (method == BDD_REORDER_ANNEALING) { 01490 return "annealing"; 01491 } 01492 else if (method == BDD_REORDER_GENETIC) { 01493 return "genetic"; 01494 } 01495 else if (method == BDD_REORDER_EXACT) { 01496 return "exact"; 01497 } 01498 else if (method == BDD_REORDER_LAZY_SIFT) { 01499 return "lazy_sift"; 01500 } 01501 else { 01502 fail("unrecognized method"); 01503 return NIL(char); /* not reached */ 01504 } 01505 } 01506 01507 01524 static boolean 01525 NetworkCheckSuppliedNodeList( 01526 Ntk_Network_t * network, 01527 lsList suppliedNodeList, 01528 Ord_OrderType orderType) 01529 { 01530 lsGen gen; 01531 st_generator *stGen; 01532 Ntk_Node_t *node; 01533 st_table *requiredNodes; 01534 st_table *suppliedNodes; 01535 char *dummy; 01536 boolean returnFlag = TRUE; 01537 01538 assert(orderType != Ord_Unassigned_c); 01539 01540 if (orderType == Ord_Partial_c) { 01541 return TRUE; 01542 } 01543 01544 /* At this point, orderType must be one of the these. */ 01545 assert((orderType == Ord_All_c) || (orderType == Ord_InputAndLatch_c) 01546 || (orderType == Ord_NextStateNode_c)); 01547 01548 01549 /* 01550 * Build up the table of required nodes. Next state nodes are included by 01551 * all 3 order types. 01552 */ 01553 requiredNodes = st_init_table(st_ptrcmp, st_ptrhash); 01554 Ntk_NetworkForEachNode(network, gen, node) { 01555 if ((orderType == Ord_All_c) || Ntk_NodeTestIsNextStateNode(node)) { 01556 st_insert(requiredNodes, (char *) node, NIL(char)); 01557 } 01558 else if ((orderType == Ord_InputAndLatch_c) 01559 && Ntk_NodeTestIsCombInput(node)) { 01560 st_insert(requiredNodes, (char *) node, NIL(char)); 01561 } 01562 /* else, this node is not included by orderType */ 01563 } 01564 01565 /* 01566 * Convert suppliedNodeList to the table of supplied nodes. 01567 */ 01568 suppliedNodes = st_init_table(st_ptrcmp, st_ptrhash); 01569 lsForEachItem(suppliedNodeList, gen, node) { 01570 int status = st_insert(suppliedNodes, (char *) node, NIL(char)); 01571 if (status) { 01572 error_append("node "); 01573 error_append(Ntk_NodeReadName(node)); 01574 error_append(" appears more than once in ordering file\n"); 01575 returnFlag = FALSE; 01576 } 01577 } 01578 01579 /* 01580 * Check that suppliedNodes is contained in requiredNodes. 01581 */ 01582 st_foreach_item(suppliedNodes, stGen, &node, &dummy) { 01583 if (!st_is_member(requiredNodes, node)) { 01584 error_append("node "); 01585 error_append(Ntk_NodeReadName(node)); 01586 error_append(" supplied but not required\n"); 01587 returnFlag = FALSE; 01588 } 01589 } 01590 01591 /* 01592 * Check that suppliedNodes is contained in requiredNodes. 01593 */ 01594 st_foreach_item(requiredNodes, stGen, &node, &dummy) { 01595 if (!st_is_member(suppliedNodes, node)) { 01596 error_append("node "); 01597 error_append(Ntk_NodeReadName(node)); 01598 error_append(" required but not supplied\n"); 01599 returnFlag = FALSE; 01600 } 01601 } 01602 01603 st_free_table(requiredNodes); 01604 st_free_table(suppliedNodes); 01605 return returnFlag; 01606 } 01607 01608 01618 static void 01619 TimeOutHandle(void) 01620 { 01621 longjmp(timeOutEnv, 1); 01622 }