VIS

src/restr/restrCmd.c

Go to the documentation of this file.
00001 
00017 #include "restrInt.h"
00018 
00019 /*---------------------------------------------------------------------------*/
00020 /* Constant declarations                                                     */
00021 /*---------------------------------------------------------------------------*/
00022 
00023 
00024 /*---------------------------------------------------------------------------*/
00025 /* Type declarations                                                         */
00026 /*---------------------------------------------------------------------------*/
00027 
00028 
00029 /*---------------------------------------------------------------------------*/
00030 /* Structure declarations                                                    */
00031 /*---------------------------------------------------------------------------*/
00032 
00033 
00034 /*---------------------------------------------------------------------------*/
00035 /* Variable declarations                                                     */
00036 /*---------------------------------------------------------------------------*/
00037 
00038 static jmp_buf timeOutEnv;
00039 int restrCreatedPart;
00040 int restrCreatedFsm;
00041 boolean restrVerbose;
00042 
00045 /*---------------------------------------------------------------------------*/
00046 /* Static function prototypes                                                */
00047 /*---------------------------------------------------------------------------*/
00048 
00049 static int CommandRestructureFsm(Hrc_Manager_t **hmgr, int argc, char **argv);
00050 static void TimeOutHandle(void);
00051 static st_table * readInputProbabilities(Ntk_Network_t *network, FILE *fp);
00052 static void CleanUp(Ntk_Network_t *network1, st_table *inputProb, char *outOrderFileName, char *dumpFileName, char *prefix, int varOrdered, int restrCreatedPart, int restrCreatedFsm, char *probFile);
00053 static enum st_retval stCountFree(char *key, char *value, char *arg);
00054 static int IsPartitionValid(Ntk_Network_t *network, graph_t *partition);
00055 static int TestIsNetworkMultipleValued(Ntk_Network_t *network);
00056 
00060 /*---------------------------------------------------------------------------*/
00061 /* Definition of exported functions                                          */
00062 /*---------------------------------------------------------------------------*/
00063 
00073 void
00074 Restr_Init(void)
00075 {
00076   Cmd_CommandAdd("restruct_fsm", CommandRestructureFsm, 0);
00077 }
00078 
00088 void
00089 Restr_End(void)
00090 {
00091 
00092 } /* End of Restr_End */
00093 
00094 
00095 /*---------------------------------------------------------------------------*/
00096 /* Definition of internal functions                                          */
00097 /*---------------------------------------------------------------------------*/
00098 
00099 /*---------------------------------------------------------------------------*/
00100 /* Definition of static functions                                            */
00101 /*---------------------------------------------------------------------------*/
00102 
00103 
00279 static int
00280 CommandRestructureFsm(
00281   Hrc_Manager_t **hmgr,
00282   int argc,
00283   char **argv)
00284 {
00285   graph_t *partition = NIL(graph_t);
00286   Fsm_Fsm_t *fsm = NIL(Fsm_Fsm_t);
00287   Ntk_Network_t *network1 = NIL(Ntk_Network_t);
00288   Hrc_Node_t *currentNode = NIL(Hrc_Node_t);
00289   lsList dummy = (lsList) 0;
00290   char *modelName,*str;
00291   int timeOutPeriod;
00292   boolean status;
00293   int c;
00294   long initialTime, finalTime;
00295   RestructureHeuristic heuristic;
00296   boolean equivClasses, nonReachEquiv;
00297   boolean eqvMethod;
00298   int varOrdered;
00299   char *outOrderFileName,*blifName;
00300   char *dumpFileName,*probFile;
00301   int reorder,trySharing,realign;
00302   FILE *fp;
00303   st_table *inputProb = NULL;
00304 
00305     /* Synthesis related options */
00306   Synth_InfoData_t *synthInfo;
00307   int factoring, divisor;
00308   char *prefix;
00309   
00310   if (bdd_get_package_name() != CUDD) {
00311     (void) fprintf(vis_stderr,
00312                    "** restr error: The restr package can be used only with CUDD package\n");
00313     (void) fprintf(vis_stderr,"** restr error: Please link with CUDD package\n");
00314     return 0;
00315   }
00316         
00317   /* These are the default values. */
00318   timeOutPeriod   = 0;  
00319   status          = FALSE;
00320   restrVerbose    = 0;
00321   equivClasses    = 0;
00322   nonReachEquiv   = 0;
00323   eqvMethod       = 0;
00324   heuristic       = RestrHammingD_c;
00325   fp              = NIL(FILE);
00326   outOrderFileName = NIL(char);
00327   dumpFileName = NIL(char);
00328   probFile = NIL(char);
00329   restrCreatedPart = 0;
00330   restrCreatedFsm = 0;
00331   varOrdered = 0;
00332 
00333   /* Synthesis related default values */
00334   factoring = 0;
00335   divisor = 1;
00336   prefix = NIL(char);
00337   reorder = 0;
00338   trySharing = 0;
00339   realign = 0;
00340 
00341   util_getopt_reset();
00342 
00343   while((c = util_getopt(argc, argv, "f:d:i:EeNvD:o:t:s:F:R:TAh")) != EOF) {
00344     switch(c) {
00345     case 'f':
00346       factoring = atoi(util_optarg);
00347       break;
00348     case 'd':
00349       divisor = atoi(util_optarg);
00350       break;
00351     case 'i':
00352       prefix = util_strsav(util_optarg);
00353       break;
00354     case 'E':
00355       equivClasses = 1;
00356       break;
00357     case 'e':
00358       eqvMethod = 1;
00359       break;
00360     case 'N':
00361       nonReachEquiv = 1;
00362       break;
00363     case 'v':
00364       restrVerbose = 1;
00365       break;
00366     case 'D':
00367       dumpFileName = util_strsav(util_optarg);
00368       break;
00369     case 'o':
00370       outOrderFileName = util_strsav(util_optarg);
00371       /* Check if the file specified to dump variable order already exists */
00372       fp = Cmd_FileOpen(outOrderFileName,"r",NIL(char *),1);
00373       if (fp) {
00374         (void) fprintf(vis_stderr,"** restr error: Output order file %s already exists.\n",
00375                        outOrderFileName);
00376         (void) fprintf(vis_stderr,"** restr error: Please specify another name.\n");
00377         fclose(fp);
00378         FREE(outOrderFileName);
00379         goto endgame;
00380       }
00381       break;
00382     case 't':
00383       timeOutPeriod = atoi(util_optarg);
00384       break;
00385     case 's':
00386       str = util_strsav(util_optarg);
00387       if (strcmp(str,"ham") == 0) {
00388         heuristic = RestrHammingD_c;
00389       } else if (strcmp(str,"fanin") == 0) {
00390         heuristic = RestrFanin_c;
00391       } else if (strcmp(str,"faninout") == 0) {
00392         heuristic = RestrFaninFanout_c;
00393       } else if (strcmp(str,"cproj") == 0) {
00394         heuristic = RestrCProjection_c;
00395       } else {
00396         (void) fprintf(vis_stderr,"** restr warning: Invalid option %s\n",str);
00397         (void) fprintf(vis_stderr,"** restr warning: Using Hamming distance heuristic\n\n");
00398         heuristic = RestrHammingD_c;
00399       }
00400       FREE(str);
00401       break;
00402     case 'F':
00403       probFile = util_strsav(util_optarg);
00404       fp = Cmd_FileOpen(probFile,"r",NIL(char *),1);
00405       if (!fp) {
00406         fprintf(vis_stderr,"** restr warning: Cannot open %s \n",probFile);
00407         fprintf(vis_stderr,"** restr warning: Assuming equi probable primary inputs\n");
00408         FREE(probFile);
00409         probFile = NIL(char);
00410       } else {
00411         fclose(fp);
00412       }
00413       break;
00414     case 'R':
00415       /* Option to enable/disable reordering during synthesis
00416          (factorization) stage */
00417       reorder = atoi(util_optarg);
00418       break;
00419     case 'T':
00420       /* During factorization maximize sharing of nodes */
00421       trySharing = 1;
00422       break;
00423     case 'A':
00424       /* Realign ZDD variables after BDD variable reordering and vice
00425          versa */
00426       realign = 1;
00427       break;
00428     case 'h':
00429       goto usage;
00430     default:
00431       goto usage;
00432     }
00433   }
00434 
00435   if(Hrc_ManagerReadCurrentNode(*hmgr) == NIL(Hrc_Node_t)) {
00436     (void) fprintf(vis_stderr,"** restr error: The hierarchy manager is empty.");
00437     (void) fprintf(vis_stderr," Read in design.\n");
00438     goto endgame;
00439   }
00440 
00441   network1 = (Ntk_Network_t *) 
00442     Hrc_NodeReadApplInfo(Hrc_ManagerReadCurrentNode(*hmgr), 
00443                          NTK_HRC_NODE_APPL_KEY);
00444 
00445   if(network1 == NIL(Ntk_Network_t)) {
00446     (void) fprintf(vis_stderr,"** restr error: There is no network. ");
00447     (void) fprintf(vis_stderr,"Use flatten_hierarchy.\n");
00448     goto endgame;
00449   }
00450 
00451   if(!Ntk_NetworkReadNumLatches(network1)) {
00452     (void) fprintf(vis_stderr,"**restr error: No latches present in the ");
00453     (void) fprintf(vis_stderr,"current network.\n");
00454     (void) fprintf(vis_stderr,"** restr error: This algorithm does not apply.\n");
00455     goto endgame;
00456   }
00457 
00458   /* Check if the current network has signals with multiple values. */
00459   if (TestIsNetworkMultipleValued(network1)) {
00460     (void) fprintf(vis_stderr,"** restr error: Circuit has multiple valued variables.\n");
00461     (void) fprintf(vis_stderr,"** restr error: This algorithm applies to boolean signals only.\n");
00462     goto endgame;
00463   }
00464 
00465   if(Ntk_NetworkReadNumPrimaryInputs(network1) !=
00466      Ntk_NetworkReadNumInputs(network1)) {
00467     (void) fprintf(vis_stderr,"** restr error: Pseudo inputs present in the network.\n");
00468     (void) fprintf(vis_stderr,"** restr error: This algorithm does not apply.\n");
00469     goto endgame;
00470   }
00471 
00472   if (!dumpFileName)
00473     dumpFileName = util_strsav(Ntk_NetworkReadName(network1));
00474   /* Check if the output blif file already exists */
00475   blifName = util_strcat3(dumpFileName,".ml.blif","");
00476   fp = Cmd_FileOpen(blifName,"r",NIL(char *),1);
00477   if (fp) {
00478     (void) fprintf(vis_stderr,"** restr error: Output blif file %s already exists.\n",
00479                    blifName);
00480     (void) fprintf(vis_stderr,"** restr error: Please specify another name.\n");
00481     fclose(fp);
00482     FREE(blifName);
00483     goto endgame;
00484   }
00485   FREE(blifName);
00486 
00487 
00488   /* Check if the network has the variables ordered */
00489   if (Ord_NetworkTestAreVariablesOrdered(network1, Ord_InputAndLatch_c) == 
00490       FALSE) {
00491     Ord_NetworkOrderVariables(network1,Ord_RootsByDefault_c,
00492                               Ord_NodesByDefault_c, FALSE,
00493                               Ord_InputAndLatch_c,Ord_Unassigned_c,
00494                               dummy,0);
00495     varOrdered = 1;
00496   }
00497 
00498   /* If primary input probabilities are specified, read them */
00499   if (probFile) {
00500     fp = Cmd_FileOpen(probFile,"r",NIL(char *),1);
00501     inputProb = readInputProbabilities(network1,fp);
00502     fclose(fp);
00503     FREE(probFile);
00504     fp = NIL(FILE);
00505   }
00506 
00507   /* Check if there is an FSM already attached to the network */
00508   fsm = (Fsm_Fsm_t *) Ntk_NetworkReadApplInfo(network1, 
00509                                               FSM_NETWORK_APPL_KEY);
00510   if (fsm == NIL(Fsm_Fsm_t)) {
00511     partition = (graph_t *) Ntk_NetworkReadApplInfo(network1,
00512                                                     PART_NETWORK_APPL_KEY);
00513     /* If there is none then create one. */
00514     if (partition == NIL(graph_t) ||
00515         (!IsPartitionValid(network1,partition))) {
00516       currentNode = Hrc_ManagerReadCurrentNode(*hmgr);
00517       modelName = Hrc_NodeReadModelName(currentNode);
00518       partition = Part_NetworkCreatePartition(network1, currentNode,
00519                                               modelName, (lsList) 0, 
00520                                               (lsList) 0, NIL(mdd_t), 
00521                                               Part_InOut_c, (lsList) 0, 
00522                                               FALSE, FALSE, TRUE);
00523  
00524       Ntk_NetworkAddApplInfo(network1, RESTR_PART_NETWORK_APPL_KEY,
00525                              (Ntk_ApplInfoFreeFn) Part_PartitionFreeCallback,
00526                              (void *) partition);
00527       restrCreatedPart = 1;
00528     }
00529     fsm = Fsm_FsmCreateFromNetworkWithPartition(network1, 
00530                                                 Part_PartitionDuplicate(partition));
00531     if (fsm == NIL(Fsm_Fsm_t)) {
00532       (void) fprintf(vis_stderr,"** restr error: Could not create ");
00533       (void) fprintf(vis_stderr,"an Fsm\n");
00534       goto endgame;
00535     }
00536     Ntk_NetworkAddApplInfo(network1, RESTR_FSM_NETWORK_APPL_KEY,
00537                            (Ntk_ApplInfoFreeFn) Fsm_FsmFreeCallback,
00538                            (void *) fsm);
00539     restrCreatedFsm = 1;
00540   } else {
00541     partition = (graph_t *) Fsm_FsmReadPartition(fsm);
00542 
00543     if (partition == NIL(graph_t) || 
00544         (!IsPartitionValid(network1,partition))) {
00545       currentNode = Hrc_ManagerReadCurrentNode(*hmgr);
00546       modelName = Hrc_NodeReadModelName(currentNode);
00547       partition = Part_NetworkCreatePartition(network1, currentNode,
00548                                               modelName, (lsList) 0, 
00549                                               (lsList) 0, NIL(mdd_t), 
00550                                               Part_InOut_c, (lsList) 0, 
00551                                               FALSE, FALSE, TRUE);
00552       Ntk_NetworkAddApplInfo(network1, RESTR_PART_NETWORK_APPL_KEY,
00553                              (Ntk_ApplInfoFreeFn) Part_PartitionFreeCallback,
00554                              (void *) partition);
00555       restrCreatedPart = 1;
00556 
00557       fsm = Fsm_FsmCreateFromNetworkWithPartition(network1, 
00558                                                   Part_PartitionDuplicate(partition));
00559       if (fsm == NIL(Fsm_Fsm_t)) {
00560         (void) fprintf(vis_stderr,"** restr error: Could not create ");
00561         (void) fprintf(vis_stderr,"an Fsm\n");
00562         goto endgame;
00563       }
00564       Ntk_NetworkAddApplInfo(network1, RESTR_FSM_NETWORK_APPL_KEY,
00565                              (Ntk_ApplInfoFreeFn) Fsm_FsmFreeCallback,
00566                              (void *) fsm);
00567       restrCreatedFsm = 1;
00568     }
00569   }
00570 
00571   /* Start the timer before calling restruct. */
00572   if (timeOutPeriod > 0){
00573     (void) signal(SIGALRM, (void(*)(int))TimeOutHandle);
00574     (void) alarm(timeOutPeriod);
00575     if (setjmp(timeOutEnv) > 0) {
00576       (void) fprintf(vis_stderr, "** restr warning: Timeout occurred after ");
00577       (void) fprintf(vis_stderr, "%d seconds.\n", timeOutPeriod);
00578       alarm(0);
00579       goto endgame;
00580     }
00581   }
00582 
00583   /* Prepare the data structure for the synthesis package */
00584   synthInfo = Synth_InitializeInfo(factoring,divisor,0,
00585                                    reorder,trySharing,realign,
00586                                    dumpFileName,prefix,0);
00587 
00588   initialTime = util_cpu_time();
00589   status = RestrCommandRestructureFsm(fsm, heuristic,outOrderFileName,
00590                                       equivClasses,nonReachEquiv,
00591                                       eqvMethod,inputProb,synthInfo);
00592   finalTime = util_cpu_time();
00593   if(status) {
00594     (void) fprintf(vis_stdout, "%-20s%10ld\n", "RESTR: analysis time =",
00595                    (finalTime-initialTime)/1000);
00596 
00597   }
00598   else {
00599     (void) fprintf(vis_stdout, "** restr error: Could not restructure successfully.\n");
00600   }
00601     
00602   if (synthInfo)
00603     Synth_FreeInfo(synthInfo);
00604 
00605     /* Clean up */
00606   CleanUp(network1,inputProb,outOrderFileName,dumpFileName,prefix,
00607           varOrdered,restrCreatedPart,restrCreatedFsm,probFile);
00608 
00609   alarm(0);
00610   return 0;  /* normal exit */
00611 
00612 endgame:
00613   /* Clean up */
00614   CleanUp(network1,inputProb,outOrderFileName,dumpFileName,prefix,
00615           varOrdered,restrCreatedPart,restrCreatedFsm,probFile);
00616     
00617   return 1; /* Error exit */
00618 
00619 usage:
00620   if (outOrderFileName)
00621     FREE(outOrderFileName);
00622   if (dumpFileName)
00623     FREE(dumpFileName);
00624   if (prefix)
00625     FREE(prefix);
00626   if (probFile)
00627     FREE(probFile);
00628 
00629   (void) fprintf(vis_stderr, "\nusage: Also see help restruct_fsm for more details.\n\n");
00630   (void) fprintf(vis_stderr, "    -A      \t\tAllow realignment--during symbolic factorization--of BDD\n");
00631   (void) fprintf(vis_stderr, "            \t\tand ZDD variables after reordering.\n\n");
00632   (void) fprintf(vis_stderr, "    -D <fileHead>\tOutput file name for synthesized circuit.\n");
00633   (void) fprintf(vis_stderr, "            \t\tDefault: model_name.ml.blif\n\n");
00634   (void) fprintf(vis_stderr, "    -d <divMethod>\tChoose a divisor during synthesis. See\n");
00635   (void) fprintf(vis_stderr, "            \t\tsynthesize_network command for more details.\n");
00636   (void) fprintf(vis_stderr, "            \t\t0 : Fast divisor\n");
00637   (void) fprintf(vis_stderr, "            \t\t1 : Least occuring literal divisor (default)\n");
00638   (void) fprintf(vis_stderr, "            \t\t2 : Most occuring literal divisor\n");
00639   (void) fprintf(vis_stderr, "            \t\t3 : Level-0 kernel divisor\n\n");
00640   (void) fprintf(vis_stderr, "    -E      \t\tPrint the number of equivalence classes in the STG.\n\n");
00641   (void) fprintf(vis_stderr, "    -F <probFile>\tInput file with PI probabilities, one per line.\n\n");
00642   (void) fprintf(vis_stderr, "    -f <factMethod>\tChoose a factorization method. See synthesize_network\n");
00643   (void) fprintf(vis_stderr, "            \t\tfor more details.\n");
00644   (void) fprintf(vis_stderr, "            \t\t0 : Simple factoring (default)\n");
00645   (void) fprintf(vis_stderr, "            \t\t1 : Generic factoring\n\n");
00646   (void) fprintf(vis_stderr, "    -h      \t\tPrint command usage.\n\n");
00647   (void) fprintf(vis_stderr, "    -i <name>\t\tPrefix to be used to generate names for internal\n");
00648   (void) fprintf(vis_stderr, "            \t\tnodes during synthesis. Default: \"_n\"\n\n");
00649   (void) fprintf(vis_stderr, "    -N      \t\tExpand the reachable set R to include those states\n");
00650   (void) fprintf(vis_stderr, "            \t\twhich are equivalent to R but unreachable.\n");
00651   (void) fprintf(vis_stderr, "            \t\tThe default is not to include.\n\n");
00652   (void) fprintf(vis_stderr, "    -o <orderFile>\tFile to output BDD variable order at the end.\n\n");
00653   (void) fprintf(vis_stderr, "    -R <value>\t\tSet reordering (0-3)\n");
00654   (void) fprintf(vis_stderr, "            \t\t0 : no reordering (default)\n");
00655   (void) fprintf(vis_stderr, "            \t\t1 : reordering in only BDD\n");
00656   (void) fprintf(vis_stderr, "            \t\t2 : reordering on only ZDD\n");
00657   (void) fprintf(vis_stderr, "            \t\t3 : reordering on both\n\n");
00658   (void) fprintf(vis_stderr, "    -s <heuristic>\tHeuristic to perform restructuring.\n");
00659   (void) fprintf(vis_stderr, "            \t\tType help restruct_fsm for more details on each option.\n");
00660   (void) fprintf(vis_stderr, "            \t\tham : Hamming distance based heuristic. (Default)\n");
00661   (void) fprintf(vis_stderr, "            \t\tfanin : Fanin oriented heuristic.\n");
00662   (void) fprintf(vis_stderr, "            \t\tfaninout : Fanin-Fanout oriented heuristic.\n");
00663   (void) fprintf(vis_stderr, "            \t\tcproj : C-Projection based heuristic.\n\n");
00664   (void) fprintf(vis_stderr, "    -T      \t\tTry to share mode nodes during symbolic factorization.\n\n");
00665   (void) fprintf(vis_stderr, "    -t <seconds>\tTime in seconds to complete the command. The command\n");
00666   (void) fprintf(vis_stderr, "            \t\tis aborted if computation time goes above this limit.\n\n");
00667   (void) fprintf(vis_stderr, "    -v      \t\tTurn on verbosity.\n");
00668 
00669 
00670   return 1;    /* error exit */
00671 }
00672 
00682 static void
00683 TimeOutHandle(void)
00684 {
00685   longjmp(timeOutEnv, 1);
00686 }
00687 
00688 
00700 static st_table *
00701 readInputProbabilities(
00702   Ntk_Network_t *network,
00703   FILE *fp)
00704 
00705 {
00706   Ntk_Node_t *node;
00707   char name[MAX_NAME_LEN];
00708   double value;
00709   double *valuePtr;
00710   st_table *inputProb;
00711 
00712   inputProb = st_init_table(st_numcmp,st_numhash);
00713 
00714   while (fscanf(fp, "%s %lf\n", name, &value) != EOF) {
00715     node = Ntk_NetworkFindNodeByName(network,name);
00716     if (node == NIL(Ntk_Node_t)) {
00717       (void) fprintf(vis_stderr,"** restr error: No node by name %s in the network\n",name);
00718       (void) fprintf(vis_stderr,"** restr error: Aborting.\n");
00719       st_foreach(inputProb,stCountFree,NIL(char));
00720       st_free_table(inputProb);
00721       return NULL;
00722     }
00723     if (!Ntk_NodeTestIsPrimaryInput(node)) {
00724       fprintf(vis_stderr,"** restr warning: <%s> is not a primary input.\n",name);
00725       fprintf(vis_stderr,"** restr warning: Assuming equiprobable primary inputs\n");
00726       st_foreach(inputProb,stCountFree,NIL(char));
00727       st_free_table(inputProb);
00728       return NULL;
00729     }
00730     valuePtr = ALLOC(double,1);
00731     if (value > 1.0) {
00732       (void) fprintf(vis_stderr,"** restr warning: %s has prob. value greater than 1: %g\n",
00733                      name,value);
00734       (void) fprintf(vis_stderr,"** restr warning: Assuming a prob. value of 0.5\n");
00735       *valuePtr = 0.5;
00736     } else {
00737       *valuePtr = value;
00738     }
00739     st_insert(inputProb,(char *)(long)Ntk_NodeReadMddId(node),(char *)valuePtr);
00740   }
00741 
00742   return inputProb;
00743 }
00744 
00756 static void
00757 CleanUp(
00758   Ntk_Network_t *network1,
00759   st_table *inputProb,
00760   char *outOrderFileName,
00761   char *dumpFileName,
00762   char *prefix,
00763   int varOrdered,
00764   int restrCreatedPart,
00765   int restrCreatedFsm,
00766   char *probFile)
00767 {
00768   Ntk_Node_t *node;
00769   lsGen gen;
00770 
00771   if (inputProb) {
00772     st_foreach(inputProb,stCountFree,NIL(char));
00773     st_free_table(inputProb);
00774   }
00775     
00776   if (outOrderFileName)
00777     FREE(outOrderFileName);
00778   if (dumpFileName)
00779     FREE(dumpFileName);
00780   if (prefix)
00781     FREE(prefix);
00782   if (probFile)
00783     FREE(probFile);
00784 
00785   /* Set the mdd id's for all the primary inputs, latches and next
00786    * state nodes to UNASSIGNED if it was specifically set in this
00787    * routine.
00788    */
00789   if (varOrdered) {
00790     Ntk_NetworkForEachPrimaryInput(network1,gen,node) {
00791       Ntk_NodeSetMddId(node,NTK_UNASSIGNED_MDD_ID);
00792     }
00793     Ntk_NetworkForEachLatch(network1,gen,node) {
00794       Ntk_Node_t *shadow;
00795       shadow = Ntk_NodeReadShadow(node);
00796       Ntk_NodeSetMddId(node,NTK_UNASSIGNED_MDD_ID);    
00797       Ntk_NodeSetMddId(shadow,NTK_UNASSIGNED_MDD_ID);    
00798     }
00799   }
00800   /* Delete the partition hooked to the network if it was created in
00801    * this routine.
00802    */
00803   if (restrCreatedPart) {
00804     Ntk_NetworkFreeApplInfo(network1,RESTR_PART_NETWORK_APPL_KEY);
00805   }
00806   /* Delete the FSM hooked to the network if it was created in
00807    * this routine.
00808    */
00809   if (restrCreatedFsm) {
00810     Ntk_NetworkFreeApplInfo(network1,RESTR_FSM_NETWORK_APPL_KEY);
00811   }
00812 }
00813 
00825 static enum st_retval
00826 stCountFree(
00827   char *key,
00828   char *value,
00829   char *arg)
00830 {
00831   double        *d;
00832   
00833   d = (double *)value;
00834   FREE(d);
00835   return(ST_CONTINUE);
00836   
00837 } /* end of stCountfree */
00838 
00839 
00853 static int
00854 IsPartitionValid(Ntk_Network_t *network,
00855                  graph_t *partition)
00856 {
00857   Ntk_Node_t *node;
00858   lsGen gen;
00859   char *name;
00860 
00861   Ntk_NetworkForEachCombOutput(network, gen, node) {
00862     name = Ntk_NodeReadName(node);
00863     if(Part_PartitionFindVertexByName(partition, name) == NIL(vertex_t)) {
00864       return(0);
00865     }
00866   }
00867   Ntk_NetworkForEachCombInput(network, gen, node) {
00868     name = Ntk_NodeReadName(node);
00869     if(Part_PartitionFindVertexByName(partition, name) == NIL(vertex_t)) {
00870       return(0);
00871     }
00872   }
00873 
00874   return 1;
00875 }
00876 
00889 static int
00890 TestIsNetworkMultipleValued(Ntk_Network_t *network)
00891 {
00892   Ntk_Node_t *node;
00893   lsGen gen;
00894   Var_Variable_t *var;
00895   int numValues;
00896 
00897   Ntk_NetworkForEachNode(network,gen,node) {
00898     var = Ntk_NodeReadVariable(node);
00899     numValues = Var_VariableReadNumValues(var);
00900     if (numValues > 2)
00901       return 1;
00902   }
00903   return 0;
00904 }