VIS

src/ord/ordCmd.c

Go to the documentation of this file.
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 }