VIS

src/res/resCmd.c

Go to the documentation of this file.
00001 
00026 #include "resInt.h" 
00027 
00028 static char rcsid[] UNUSED = "$Id: resCmd.c,v 1.58 2010/04/10 00:38:26 fabio Exp $";
00029 
00030 /*---------------------------------------------------------------------------*/
00031 /* Constant declarations                                                     */
00032 /*---------------------------------------------------------------------------*/
00033 
00034 
00035 /*---------------------------------------------------------------------------*/
00036 /* Type declarations                                                         */
00037 /*---------------------------------------------------------------------------*/
00038 
00039 
00040 /*---------------------------------------------------------------------------*/
00041 /* Structure declarations                                                    */
00042 /*---------------------------------------------------------------------------*/
00043 
00044 
00045 /*---------------------------------------------------------------------------*/
00046 /* Variable declarations                                                     */
00047 /*---------------------------------------------------------------------------*/
00048 
00049 static jmp_buf timeOutEnv;
00050 
00051 /*---------------------------------------------------------------------------*/
00052 /* Macro declarations                                                        */
00053 /*---------------------------------------------------------------------------*/
00054 
00055 
00058 /*---------------------------------------------------------------------------*/
00059 /* Static function prototypes                                                */
00060 /*---------------------------------------------------------------------------*/
00061 
00062 static int CommandResVerify(Hrc_Manager_t ** hmgr, int argc, char ** argv);
00063 static void TimeOutHandle(void);
00064 static st_table * ReadMatchingPairs(char *fileName, Ntk_Network_t *ntk1, Ntk_Network_t *ntk2);
00065 static array_t * ReadOutputOrder(char *fileName, Ntk_Network_t *ntk1);
00066 static array_t * GenerateDefaultOutputOrder(Ntk_Network_t *specNetwork);
00067 static int CheckForMultiValueNode(Ntk_Network_t *network);
00068 
00072 /*---------------------------------------------------------------------------*/
00073 /* Definition of exported functions                                          */
00074 /*---------------------------------------------------------------------------*/
00075 
00085 void
00086 Res_Init(void)
00087 {
00088   Cmd_CommandAdd("res_verify", CommandResVerify, /* doesn't changes_network */ 0);
00089 }
00090 
00091 
00101 void
00102 Res_End(void)
00103 {
00104   /*
00105    * For example, free any global memory (if any) which the test package is
00106    * responsible for.
00107    */
00108 }
00109 
00110 /*---------------------------------------------------------------------------*/
00111 /* Definition of internal functions                                          */
00112 /*---------------------------------------------------------------------------*/
00113 
00114 
00115 /*---------------------------------------------------------------------------*/
00116 /* Definition of static functions                                            */
00117 /*---------------------------------------------------------------------------*/
00118 
00392 static int
00393 CommandResVerify(Hrc_Manager_t ** hmgr,
00394                  int  argc,
00395                  char ** argv)
00396 {
00397   static int           timeOutPeriod; /* CPU seconds allowed */
00398   static array_t       *outputOrderArray;   /* required to specify the outputs
00399                                        * starting with MSB first */
00400   static Hrc_Manager_t *implHmgr;     /* Auxiliary hierarchy manager */
00401   static Hrc_Manager_t *specHmgr;     /* Auxiliary hierarchy manager */
00402   static Hrc_Node_t    *currentNode;  /* node in the hierarchy */
00403   static Ntk_Network_t *specNetwork;  /* spec network */
00404   static Ntk_Network_t *implNetwork;  /* implementation network */
00405   static st_table      *inputMatch;   /* List of pairs of input name match */
00406   static st_table      *outputMatch;  /* List of pairs of output name match */
00407   int                  outputsToVerifyDirectly; /* number of outputs to
00408                                                  * directly verify
00409                                                  */
00410   int                  c;             /* To process the command line options */
00411   /* Flush previous verification if any */
00412   int                  success;       /* Outcome of the verification */
00413   int                  status;        /* Status of the call to the function */
00414   char                 *specFileName;  /* File to read the specification from */
00415   char                 *impFileName;  /* File to read the implementation from */
00416   char                 *fileMatchOut; /* File specifying the output matching */
00417   char                 *fileMatchIn;  /* File specifying the input matching */
00418   char                 *fileOutputOrder; /*file name that contains the order of
00419                                            outputs starting with MSB */
00420   boolean              isInBlifMv;    /* Format to be read in */
00421   st_generator         *stGen;        /* generator to step through the table */
00422   char                 *key, *value;  /* variables for the st_table */
00423   int i;
00424   int defaultOutputOrder;             /* flag to indicate default order to
00425                                        * be taken, if no output order file
00426                                        * is specified
00427                                        */
00428   char                 *strptr;       /* variable to hold return value
00429                                        * of strtol
00430                                        */
00431   int                  allFlag;
00432   
00433   if (bdd_get_package_name() != CUDD) {
00434     fprintf(vis_stdout, "** res error: Residue Verification is available with the CUDD package only.\n");
00435     return 0;
00436   }
00437   /* Default values for some variables */
00438   timeOutPeriod = 0;
00439   allFlag = 1;
00440   outputsToVerifyDirectly = 0;
00441   outputOrderArray = NIL(array_t);
00442   implHmgr = NIL(Hrc_Manager_t);
00443   specHmgr = NIL(Hrc_Manager_t);
00444   currentNode = NIL(Hrc_Node_t);
00445   specNetwork = NIL(Ntk_Network_t);
00446   implNetwork = NIL(Ntk_Network_t);
00447   inputMatch = NIL(st_table);
00448   outputMatch = NIL(st_table);
00449   impFileName = NIL(char);
00450   specFileName = NIL(char);
00451   isInBlifMv = FALSE;
00452   fileMatchOut = NIL(char);
00453   fileMatchIn = NIL(char);
00454   status = 1;
00455   fileOutputOrder = NIL(char);
00456   defaultOutputOrder = 0;
00457   
00458   /*
00459    * Parse command line options.
00460    */
00461   util_getopt_reset();
00462   while ((c = util_getopt(argc, argv, "bd:hi:m:n:o:Os:t:")) != EOF) {
00463     switch(c) {
00464     case 'b':
00465       isInBlifMv = TRUE;
00466       break;
00467     case 'd':
00468       /* number of outputs to verify directly */
00469       /*      outputsToVerifyDirectly = atoi(util_optarg); */
00470       outputsToVerifyDirectly = (int)strtol(util_optarg, &strptr, 0);
00471       allFlag = strcmp(util_optarg, "all");
00472       break;
00473     case 'h':
00474       goto usage;
00475     case 'i':
00476       impFileName = util_optarg;
00477       break;
00478     case 'm':
00479       fileMatchOut = util_optarg;
00480       break;
00481     case 'n':
00482       fileMatchIn = util_optarg;
00483       break;
00484     case 'o':
00485       fileOutputOrder = util_optarg;
00486       break;
00487     case 'O':
00488       defaultOutputOrder = 1;
00489       break;
00490     case 's':
00491       specFileName = util_optarg;
00492       break;
00493     case 't':
00494       timeOutPeriod = atoi(util_optarg);
00495       break;
00496     default:
00497       goto usage;
00498     }
00499   }
00500 
00501   /* Obtain the Specification network either from file or hierarchy manager */
00502   if (specFileName != NIL(char)) {
00503 
00504     /* Read blif or blif-mv depending on the flag */
00505     error_init();
00506     if (isInBlifMv) {
00507       FILE *fp; /* Used to read from files */
00508 
00509       /* Open the file */
00510       fp = Cmd_FileOpen(specFileName, "r", NIL(char *), TRUE);
00511       if (fp != NULL) {
00512         specHmgr = Io_BlifMvRead(fp, NIL(Hrc_Manager_t),
00513                                  0, /* No Cannonical */
00514                                  0, /* No incremental */
00515                                  0  /* No verbosity */);
00516         fclose(fp);
00517       } else {
00518         fprintf(vis_stderr, "** res error: Specification file required(may not exist in path)\n");
00519         goto usage;
00520       }
00521 
00522     } /* End of then */ 
00523     else {
00524       specHmgr = Io_BlifRead(specFileName, 0 /* No verbosity */);
00525     } /* End of if-then-else */
00526 
00527     /* Check if the read has been performed correctly */
00528     if (specHmgr == NIL(Hrc_Manager_t)) {
00529       (void) fprintf(vis_stderr, "%s", error_string());
00530       (void) fprintf(vis_stderr, "Cannot read blif file %s.\n", impFileName);
00531       goto cleanup;
00532     }
00533     
00534     /* Hierarchy manager successfully created */
00535     error_init();
00536     currentNode = Hrc_ManagerReadCurrentNode(specHmgr);
00537     specNetwork = Ntk_HrcNodeConvertToNetwork(currentNode, TRUE, (lsList)0);
00538     if (specNetwork == NIL(Ntk_Network_t)) {
00539       (void) fprintf(vis_stderr, "%s", error_string());
00540       (void) fprintf(vis_stderr, "Cannot perform flatten_hierarchy.\n");
00541       goto cleanup;
00542     }
00543   } else {
00544     /* Check if any circuit has been read in */
00545     currentNode = Hrc_ManagerReadCurrentNode(*hmgr);
00546     if (currentNode == NIL(Hrc_Node_t)) {
00547       (void) fprintf(vis_stderr, "The hierarchy manager is empty. ");
00548       (void) fprintf(vis_stderr, "Read in design.\n");
00549       goto cleanup;
00550     }
00551 
00552     /* Check if the network has been created with flatten_hierarchy */
00553     specNetwork = Ntk_HrcManagerReadCurrentNetwork(*hmgr);
00554     if (specNetwork == NIL(Ntk_Network_t)) {
00555       goto cleanup;
00556     } /* End of if */
00557   }
00558 
00559   /* Obtain the implementation network from file */
00560   if (impFileName != NIL(char)) {
00561 
00562     /* Read blif or blif-mv depending on the flag */
00563     error_init();
00564     if (isInBlifMv) {
00565       FILE *fp; /* Used to read from files */
00566 
00567       /* Open the file */
00568       fp = Cmd_FileOpen(impFileName, "r", NIL(char *), TRUE);
00569 
00570       if (fp != NULL) {
00571         implHmgr = Io_BlifMvRead(fp, NIL(Hrc_Manager_t),
00572                                  0, /* No Cannonical */
00573                                  0, /* No incremental */
00574                                  0  /* No verbosity */);
00575         fclose(fp);
00576       } else {
00577         fprintf(vis_stderr, "** res error: Implementation file required(may not exist in path)\n");
00578         goto usage;
00579       }
00580 
00581     }  else { /* End of then */
00582       implHmgr = Io_BlifRead(impFileName, 0 /* No verbosity */);
00583     } /* End of if-then-else */
00584 
00585     /* Check if the read has been performed correctly */
00586     if (implHmgr == NIL(Hrc_Manager_t)) {
00587       (void) fprintf(vis_stderr, "%s", error_string());
00588       (void) fprintf(vis_stderr, "Cannot read blif file %s.\n", impFileName);
00589       goto cleanup;
00590     }
00591     
00592     /* Hierarchy manager successfully created */
00593     error_init();
00594     currentNode = Hrc_ManagerReadCurrentNode(implHmgr);
00595     implNetwork = Ntk_HrcNodeConvertToNetwork(currentNode, TRUE, NULL);
00596     if (implNetwork == NIL(Ntk_Network_t)) {
00597       (void) fprintf(vis_stderr, "%s", error_string());
00598       (void) fprintf(vis_stderr, "Cannot perform flatten_hierarchy.\n");
00599       goto cleanup;
00600     }
00601   }
00602   else {
00603     /* The option -1 has not been provided in the command line */
00604     goto usage;
00605   }
00606   /* At this point both networks have been built */
00607 
00608   /* Check that no node in the two network is multi-valued */
00609   if (CheckForMultiValueNode(specNetwork)) {
00610     fprintf(vis_stderr, "** res error: Specification has multivalued network\n");
00611     fprintf(vis_stderr, "** res error: Residue verification does not support multi-valued variables, variables have to be binary.\n");
00612     goto cleanup;
00613   }
00614   if (CheckForMultiValueNode(implNetwork)) {
00615     fprintf(vis_stderr, "** res error: Implementation has multivalued network\n");
00616     fprintf(vis_stderr, "** res error: Residue verification does not support multi-valued variables, variables have to be binary.\n");
00617     goto cleanup;
00618   }
00619   
00620   /* Check that both networks have the same number of inputs and outputs */
00621   if ((Ntk_NetworkReadNumCombInputs(implNetwork) != 
00622        Ntk_NetworkReadNumCombInputs(specNetwork)) ||
00623       (Ntk_NetworkReadNumCombOutputs(implNetwork) != 
00624        Ntk_NetworkReadNumCombOutputs(specNetwork))) {
00625 
00626     (void) fprintf(vis_stderr, "** res error: Networks do not have equal number of inputs ");
00627     (void) fprintf(vis_stderr, "or outputs\n");
00628     goto cleanup;
00629   } /* End of if */  
00630 
00631   /* Check if there has been some name matching file provided for outputs. */
00632   if (fileMatchOut != NIL(char)) {
00633     outputMatch = ReadMatchingPairs(fileMatchOut, implNetwork, specNetwork);
00634     if (outputMatch == NIL(st_table)) {
00635       (void) fprintf(vis_stderr, "** res error: Error reading Output match file ");
00636       (void) fprintf(vis_stderr, "%s\n", fileMatchOut);
00637       goto cleanup;
00638     } /* End of if */
00639   } /* End of if */
00640 
00641   /* Check if there has been some name matching file provided for inputs. */
00642   if (fileMatchIn != NIL(char)) {
00643     inputMatch = ReadMatchingPairs(fileMatchIn, implNetwork, specNetwork);
00644     if (inputMatch == NIL(st_table)) {
00645       (void) fprintf(vis_stderr, "** res error: Error reading Input match file ");
00646       (void) fprintf(vis_stderr, "%s\n", fileMatchIn);
00647       /* Clean up */
00648       goto cleanup;
00649     } /* End of if */
00650   } /* End of if */
00651 
00652   /* Transfer names of outputs starting with MSB from the file to an
00653    * array_t
00654    */
00655   if (fileOutputOrder != NIL(char)) {
00656     outputOrderArray = ReadOutputOrder(fileOutputOrder, specNetwork);
00657   } else if (defaultOutputOrder) {
00658     outputOrderArray = GenerateDefaultOutputOrder(specNetwork);
00659   }
00660     
00661   if (outputOrderArray == NIL(array_t)) {
00662     /* Clean up */
00663     fprintf(vis_stderr, "** res error: Output order(msb first) required for residue method.\n");
00664     goto usage;
00665   } else if  (array_n(outputOrderArray) != Ntk_NetworkReadNumCombOutputs(specNetwork)) {
00666     fprintf(vis_stderr, "** res error: Number of Outputs seem to be %d\n", Ntk_NetworkReadNumCombOutputs(specNetwork));
00667     fprintf(vis_stderr, "** res error: The output order seems to contain %d outputs\n", array_n(outputOrderArray));
00668     fprintf(vis_stderr, "** res error: Partial Orders or mismatch in the above two numbers is not allowed in the -o option\n");
00669     goto usage;
00670   }
00671   /* Start the timer before calling the verifyer */
00672   if (timeOutPeriod > 0) {
00673     (void) signal(SIGALRM, (void(*)(int))TimeOutHandle);
00674     (void) alarm(timeOutPeriod);
00675 
00676     /* The second time setjmp is called, it returns here !!*/
00677     if (setjmp(timeOutEnv) > 0) {
00678       (void) fprintf(vis_stdout, "Residue Verification timeout occurred after%d seconds.\n", 
00679                      timeOutPeriod);
00680       alarm(0);
00681 
00682       /* Note that there is a huge memory leak here. */
00683       goto cleanup;
00684     } /* End of if */
00685   }
00686 
00687   /* number of outputs to directly verify should be less than the
00688    * number of outputs for the circuit. If all flag set, number of
00689    * directly verified circuit, set it to number of combinational
00690    * outputs.
00691    */
00692   if (allFlag == 0) {
00693     outputsToVerifyDirectly = Ntk_NetworkReadNumCombOutputs(specNetwork);
00694   }
00695   if (outputsToVerifyDirectly > Ntk_NetworkReadNumCombOutputs(specNetwork)) {
00696     fprintf(vis_stderr, "** res error: More outputs to directly verify than that exist in the circuit\n");
00697     goto usage;
00698   }
00699     
00700   error_init();
00701 
00702 
00703   /* main procedure for residue verification */
00704   status = Res_NetworkResidueVerify(specNetwork,
00705                                     implNetwork,
00706                                     outputsToVerifyDirectly,
00707                                     outputOrderArray,
00708                                     outputMatch,
00709                                     inputMatch);
00710     
00711   /* Deactivate the alarm */
00712   alarm(0);
00713   
00714   /* If the computation succeded store the result in specNetwork */
00715   if (status == 0) {
00716     Res_ResidueInfo_t *residueInfo;
00717 
00718     residueInfo = (Res_ResidueInfo_t *) Ntk_NetworkReadApplInfo(specNetwork, 
00719                                                                 RES_NETWORK_APPL_KEY);
00720 
00721     /* Print out the error string in case success is false */
00722     success = Res_ResidueInfoReadSuccess(residueInfo);
00723     switch (success) {
00724     case FALSE:
00725       (void) fprintf(vis_stdout, "Residue Verification failed !\n");
00726       break;
00727     case TRUE:
00728       (void) fprintf(vis_stdout, "Residue Verification successful\n");
00729       break;
00730     default:
00731       (void) fprintf(vis_stderr, "** res error: Residue Verification unable to produce ");
00732       (void) fprintf(vis_stderr, "result\n");
00733       break;
00734     }
00735   } else {
00736     (void) fprintf(vis_stderr, "%s", error_string());
00737   }
00738 
00739   /* Clean up */
00740   error_cleanup();
00741   goto cleanup;
00742   
00743     /* update with all functions */
00744 usage:
00745   (void) fprintf(vis_stderr, "usage: res_verify [-b]  ");
00746   (void) fprintf(vis_stderr, "[-d n] [-h] -i impl file\n       ");
00747   (void) fprintf(vis_stderr, "[-m file] [-n file] -o file [-s spec file] ");
00748   (void) fprintf(vis_stderr, "[-t secs]\n");
00749   (void) fprintf(vis_stderr, "   -b        The file format to be read is ");
00750   (void) fprintf(vis_stderr, "blif-mv (default is blif)\n");
00751   (void) fprintf(vis_stderr, "   -d n      Number of outputs to verify ");
00752   (void) fprintf(vis_stderr, "directly\n");
00753   (void) fprintf(vis_stderr, "   -h        Print the usage of the command\n");
00754   (void) fprintf(vis_stderr, "   -i impl   Implementation file (required)\n");
00755   (void) fprintf(vis_stderr, "   -m file   File specifying the matching pair ");
00756   (void) fprintf(vis_stderr, "of names for the outputs\n");
00757   (void) fprintf(vis_stderr, "   -n file   File specifying the matching pair");
00758   (void) fprintf(vis_stderr, " of names for the inputs\n");
00759   (void) fprintf(vis_stderr, "   -o        Output order starting with MSB (required or -O required)\n");
00760   (void) fprintf(vis_stderr, "   -O        Default output order (required or -o required)\n");
00761   (void) fprintf(vis_stderr, "   -s file   Specification File\n");
00762   (void) fprintf(vis_stderr, "   -t secs   Seconds allowed for computation\n");
00763 
00764   
00765   /* Clean up */
00766 cleanup:
00767   if ((specFileName == NIL(char)) && (specHmgr != NIL(Hrc_Manager_t))) {
00768     int zerorefcountbdds;
00769     bdd_manager *ddManager;
00770     Hrc_ManagerFree(specHmgr);
00771     if (specNetwork != NIL(Ntk_Network_t)) {
00772       ddManager = (bdd_manager *)Ntk_NetworkReadMddManager(specNetwork);
00773       if (ddManager != NIL(bdd_manager)) {
00774         zerorefcountbdds = bdd_check_zero_ref((bdd_manager *)Ntk_NetworkReadMddManager(specNetwork));
00775         if (zerorefcountbdds) {
00776           fprintf(vis_stdout, "Number of Nodes with non zero ref count are %d\n", zerorefcountbdds);
00777           fprintf(vis_stdout, "Size of DD manager = %d\n", bdd_num_vars(ddManager));
00778         }
00779       }
00780     }
00781     Ntk_NetworkFree(specNetwork);
00782   }
00783   if (implHmgr != NIL(Hrc_Manager_t)) {
00784     Hrc_ManagerFree(implHmgr);
00785     /* dont free manager if not set here */
00786     if ((specNetwork != NIL(Ntk_Network_t)) &&
00787         ((bdd_manager *)Ntk_NetworkReadMddManager(specNetwork) != NIL(bdd_manager))) {
00788       Ntk_NetworkSetMddManager(implNetwork, NIL(bdd_manager));
00789     }
00790     Ntk_NetworkFree(implNetwork);
00791   }
00792   if (outputMatch != NIL(st_table)) {
00793     st_foreach_item(outputMatch, stGen, &key, &value) {
00794       /* free only the key, cos the value appears as a key also */
00795       FREE(key);
00796     }
00797     st_free_table(outputMatch);
00798   } /* End of if */
00799   if (inputMatch != NIL(st_table)) {
00800     st_foreach_item(inputMatch, stGen, &key, &value) {
00801       /* free only the key, cos the value appears as a key also */
00802       FREE(key);
00803     }
00804     st_free_table(inputMatch);
00805   }
00806   if (outputOrderArray != NIL(array_t)) {
00807     char * name;
00808     arrayForEachItem(char *, outputOrderArray, i, name) {
00809       FREE(name);
00810     }
00811     array_free(outputOrderArray);
00812   }    
00813   return status;
00814 }  /* End of CommandResVerify */
00815 
00816 
00829 static void
00830 TimeOutHandle(void)
00831 {
00832   longjmp(timeOutEnv, 1);
00833 } /* End of TimeOutHandle */
00834 
00848 static st_table *
00849 ReadMatchingPairs(char *fileName,
00850                   Ntk_Network_t *ntk1,
00851                   Ntk_Network_t *ntk2)
00852 {
00853   st_table *result = NIL(st_table);
00854   int check;
00855   char name1[80], name2[80]; /* Note the size of buffer is used in fscanf */
00856   char *ptr1, *ptr2;
00857   FILE *fp;
00858 #if HAVE_MKSTEMP && HAVE_CLOSE
00859   int  fd;
00860 #else
00861   char buffer[512];
00862 #endif
00863   char *realFileName, *blifMvFileName, *visDirectoryName;
00864   char command[512];
00865   int cmdStatus;
00866   
00867   fp = Cmd_FileOpen(fileName, "r", &realFileName, 1 /* silent */);
00868   
00869   if (fp == NIL(FILE)) {
00870     FREE(realFileName);
00871     (void) fprintf(vis_stderr, "** res error: Cannot open %s to read.\n", fileName);
00872     return result;
00873   } /* End of if */
00874   
00875   if (fp != stdin){
00876     (void)fclose(fp);
00877   }  
00878 
00879 #if HAVE_MKSTEMP && HAVE_CLOSE
00880   blifMvFileName = util_strsav("/tmp/vis.XXXXXX");
00881   fd = mkstemp(blifMvFileName);
00882   if (fd == -1){
00883 #else
00884   blifMvFileName = util_strsav(tmpnam(buffer));
00885   if (blifMvFileName == NIL(char)){
00886 #endif
00887     FREE(realFileName);
00888     (void)fprintf(vis_stderr,"** res error: Could not create temporary file. ");
00889     (void)fprintf(vis_stderr,"** res error: Clean up /tmp an try again.\n");
00890     return NIL(st_table);
00891   }
00892 #if HAVE_MKSTEMP && HAVE_CLOSE
00893   close(fd);
00894 #endif
00895    /* Invoking an awk script */
00896   visDirectoryName = Vm_VisObtainLibrary();
00897   (void)sprintf(command,"sed 's/^\\./@/g' %s | sed 's/\\./$/g' | sed 's/^@/\\./g' | sed 's/{/</g' | sed 's/}/>/g'| sed 's/(/<</g' | sed 's/)/>>/g' > %s", realFileName, blifMvFileName);
00898   /* the following is missing two new sed processings 
00899   (void)sprintf(command,"sed 's/^\\./@/g' %s | sed 's/\\./$/g' | sed 's/^@/\\./g' | sed 's/{/</g' | sed 's/}/>/g'| %s -f %s/ioBlifToMv.nawk > %s", realFileName, NAWK, visDirectoryName, blifMvFileName);
00900   */
00901   cmdStatus = system(command);
00902   FREE(visDirectoryName);
00903   FREE(realFileName);
00904   if (cmdStatus != 0) {
00905     return NIL(st_table);
00906   }
00907 
00908   fp = Cmd_FileOpen(blifMvFileName, "r", NIL(char *), 1);
00909   assert(fp != NIL(FILE));
00910 
00911 
00912   result = st_init_table(st_ptrcmp, st_ptrhash);
00913   while (!feof(fp)) {
00914     check = fscanf(fp, "%80s %80s", name1, name2);
00915     if (check != 2 && check != EOF) {
00916       st_free_table(result);
00917       result = NIL(st_table);
00918       return result;
00919     } /* End of if */
00920     
00921     if (Ntk_NetworkFindNodeByName(ntk1, name1) == NIL(Ntk_Node_t) &&
00922         Ntk_NetworkFindNodeByName(ntk2, name1) == NIL(Ntk_Node_t)) {
00923       (void) fprintf(vis_stderr, "** res error: While reading matching file. ");
00924       (void) fprintf(vis_stderr, "** res error: Node %s not found in any of the networks.\n", 
00925                      name1);
00926       st_free_table(result);
00927       result = NIL(st_table);
00928       return result;
00929     }
00930     
00931     if (Ntk_NetworkFindNodeByName(ntk1, name2) == NIL(Ntk_Node_t) &&
00932         Ntk_NetworkFindNodeByName(ntk2, name2) == NIL(Ntk_Node_t)) {
00933       (void) fprintf(vis_stderr, "** res error: While reading matching file. ");
00934       (void) fprintf(vis_stderr, "** res error: Node %s not found in any of the networks.\n", 
00935                      name2);
00936       st_free_table(result);
00937       result = NIL(st_table);
00938       return result;
00939     }
00940 
00941     ptr1 = util_strsav(name1);
00942     ptr2 = util_strsav(name2);
00943     st_insert(result, ptr1, ptr2);
00944     st_insert(result, ptr2, ptr1);
00945   } /* End of while */
00946   
00947   fclose(fp);
00948 #if HAVE_UNLINK
00949   unlink(blifMvFileName);
00950 #endif
00951   FREE(blifMvFileName);
00952 
00953   return result;
00954 } /* End of ReadMatchingPairs */
00955 
00968 static array_t *
00969 ReadOutputOrder(char *fileName,
00970                 Ntk_Network_t *ntk1)
00971 {
00972   FILE *fp;
00973 #if HAVE_MKSTEMP && HAVE_CLOSE
00974   int  fd;
00975 #else
00976   char buffer[512];
00977 #endif
00978   array_t *result = NIL(array_t);
00979   int check;
00980   char name1[80]; /* Note the size of buffer is used in fscanf */
00981   char *ptr1;
00982   char *realFileName, *blifMvFileName, *visDirectoryName;
00983   char command[512];
00984   int cmdStatus;
00985   
00986   fp = Cmd_FileOpen(fileName, "r", &realFileName, 1 /* silent */);
00987   
00988   if (fp == NIL(FILE)) {
00989     FREE(realFileName);
00990     (void) fprintf(vis_stderr, "** res error: Cannot open %s to read.\n", fileName);
00991     return result;
00992   } /* End of if */
00993 
00994   if (fp != stdin){
00995     (void)fclose(fp);
00996   }  
00997 
00998 #if HAVE_MKSTEMP && HAVE_CLOSE
00999   blifMvFileName = util_strsav("/tmp/vis.XXXXXX");
01000   fd = mkstemp(blifMvFileName);
01001   if (fd == -1){
01002 #else
01003   blifMvFileName = util_strsav(tmpnam(buffer));
01004   if (blifMvFileName == NIL(char)){
01005 #endif
01006     FREE(realFileName);
01007     (void)fprintf(vis_stderr,"** res error: Could not create temporary file. ");
01008     (void)fprintf(vis_stderr,"** res error: Clean up /tmp an try again.\n");
01009     return NIL(array_t);
01010   }
01011 #if HAVE_MKSTEMP && HAVE_CLOSE
01012   close(fd);
01013 #endif
01014   /* Invoking an awk script */
01015   visDirectoryName = Vm_VisObtainLibrary();
01016   (void)sprintf(command,"sed 's/^\\./@/g' %s | sed 's/\\./$/g' | sed 's/^@/\\./g' | sed 's/{/</g' | sed 's/}/>/g'| sed 's/(/<</g' | sed 's/)/>>/g' > %s", realFileName, blifMvFileName);
01017   /* the following is missing two new sed processings 
01018   (void)sprintf(command,"sed 's/^\\./@/g' %s | sed 's/\\./$/g' | sed 's/^@/\\./g' | sed 's/{/</g' | sed 's/}/>/g'| %s -f %s/ioBlifToMv.nawk > %s", realFileName, NAWK, visDirectoryName, blifMvFileName);
01019   */
01020   cmdStatus = system(command);
01021   FREE(visDirectoryName);
01022   FREE(realFileName);
01023   if (cmdStatus != 0) {
01024     return NIL(array_t);
01025   }
01026 
01027   fp = Cmd_FileOpen(blifMvFileName, "r", NIL(char *), 1);
01028   assert(fp != NIL(FILE));
01029   
01030   result = array_alloc(char *, 0);
01031   while (!feof(fp)) {
01032     check = fscanf(fp, "%80s", name1);
01033     if (check != EOF) {
01034       if (check != 1) {
01035         array_free(result);
01036         result = NIL(array_t);
01037         return result;
01038       } /* End of if */
01039       
01040       if (Ntk_NetworkFindNodeByName(ntk1, name1) == NIL(Ntk_Node_t)) {
01041         (void) fprintf(vis_stderr, "** res error: While reading output order file. ");
01042         (void) fprintf(vis_stderr, "** res error: Node %s not found in the network.\n", 
01043                        name1);
01044         array_free(result);
01045         result = NIL(array_t);
01046         return result;
01047       }
01048       ptr1 = util_strsav(name1);
01049       array_insert_last(char *, result, ptr1);
01050     }
01051   } /* End of while */
01052 #ifdef DEBUG
01053   arrayForEachItem(char *,result, i, ptr1) {
01054     fprintf(vis_stdout, "%s\n", ptr1);
01055   }
01056 #endif  
01057 
01058   fclose(fp);
01059 #if HAVE_UNLINK
01060   unlink(blifMvFileName);
01061 #endif
01062   FREE(blifMvFileName);
01063 
01064   return result;
01065 } /* End of ReadMatchingPairs */
01066 
01067 
01079 static array_t *
01080 GenerateDefaultOutputOrder(Ntk_Network_t *specNetwork)
01081 {
01082   array_t *outputOrderArray;
01083   lsGen listGen;
01084   Ntk_Node_t *nodePtr;
01085   char *name, *ptr1;
01086   int i;
01087 
01088   i = 0;
01089   outputOrderArray = array_alloc(char *,
01090                                  Ntk_NetworkReadNumCombOutputs(specNetwork));
01091   Ntk_NetworkForEachCombOutput(specNetwork, listGen, nodePtr) {
01092     name = Ntk_NodeReadName(nodePtr);
01093     ptr1 = util_strsav(name);
01094     array_insert(char *, outputOrderArray, i, ptr1);
01095     i++;
01096   }
01097   return outputOrderArray;
01098 }
01099 
01112 static int
01113 CheckForMultiValueNode(Ntk_Network_t *network)
01114 {
01115   lsGen listGen;
01116   Ntk_Node_t *nodePtr;
01117   Var_Variable_t * var;
01118   
01119   Ntk_NetworkForEachNode(network, listGen, nodePtr) {
01120     var = Ntk_NodeReadVariable(nodePtr);
01121     if ((Var_VariableReadNumValues(var) > 2) ||
01122         (!Var_VariableTestIsEnumerative(var))) {
01123       return 1;
01124     }
01125   }
01126   return 0;
01127 }