VIS

src/ntk/ntkCmd.c

Go to the documentation of this file.
00001 
00032 #include "ntkInt.h"
00033 
00034 static char rcsid[] UNUSED = "$Id: ntkCmd.c,v 1.19 2010/04/09 23:44:05 fabio Exp $";
00035 
00036 /*---------------------------------------------------------------------------*/
00037 /* Constant declarations                                                     */
00038 /*---------------------------------------------------------------------------*/
00039 /*
00040  * States of the state machine used to parse the input variable name list file.
00041  */
00042 #define STATE_TEST 0 /* next char is in first column */
00043 #define STATE_WAIT 1 /* wait until end of line '\n' is reached */
00044 #define STATE_IN   2 /* parsing a variable name */
00045 
00046 /*
00047  * Maximum permissible length of a variable name in the input variable name list file.
00048  */
00049 #define MAX_NAME_LENGTH 200
00050 
00051 int NtkDebug;
00052 
00055 /*---------------------------------------------------------------------------*/
00056 /* Static function prototypes                                                */
00057 /*---------------------------------------------------------------------------*/
00058 
00059 static int CommandPrintNetworkStats(Hrc_Manager_t ** hmgr, int argc, char ** argv);
00060 static int CommandPrintNetwork(Hrc_Manager_t ** hmgr, int argc, char ** argv);
00061 static int CommandPrintNetworkDot(Hrc_Manager_t ** hmgr, int argc, char ** argv);
00062 static int CommandWriteNetworkBlifMv(Hrc_Manager_t ** hmgr, int  argc, char ** argv);
00063 static int CommandFlattenHierarchy(Hrc_Manager_t ** hmgr, int argc, char ** argv);
00064 static int CommandTestNetworkAcyclic(Hrc_Manager_t ** hmgr, int argc, char ** argv);
00065 static int CommandInitVerify(Hrc_Manager_t ** hmgr, int argc, char ** argv);
00066 static int CommandNetworkSweep(Hrc_Manager_t ** hmgr, int argc, char ** argv);
00067 static boolean FileReadNameList(FILE * fp, lsList * nameList, int verbose);
00068 
00072 /*---------------------------------------------------------------------------*/
00073 /* Definition of exported functions                                          */
00074 /*---------------------------------------------------------------------------*/
00075 
00085 void
00086 Ntk_Init(void)
00087 {
00088   Cmd_CommandAdd("print_network_stats",   CommandPrintNetworkStats,   0);
00089   Cmd_CommandAdd("print_network",         CommandPrintNetwork,        0);
00090   Cmd_CommandAdd("print_network_dot",     CommandPrintNetworkDot,     0);
00091   Cmd_CommandAdd("flatten_hierarchy",     CommandFlattenHierarchy,    1);
00092   Cmd_CommandAdd("test_network_acyclic",  CommandTestNetworkAcyclic,  0);
00093   Cmd_CommandAdd("init_verify",           CommandInitVerify,          0);
00094   Cmd_CommandAdd("network_sweep",         CommandNetworkSweep,        1);
00095   Cmd_CommandAdd("write_network_blif_mv", CommandWriteNetworkBlifMv,  0);
00096 }
00097 
00098 
00108 void
00109 Ntk_End(void)
00110 {
00111 }
00112 
00113 
00127 Ntk_Network_t *
00128 Ntk_HrcManagerReadCurrentNetwork(Hrc_Manager_t *hmgr)
00129 {
00130   Hrc_Node_t *currentNode;
00131   Ntk_Network_t *network;
00132 
00133   assert(hmgr != NIL(Hrc_Manager_t));
00134   currentNode = Hrc_ManagerReadCurrentNode(hmgr);
00135   if (currentNode == NIL(Hrc_Node_t)) {
00136     (void) fprintf(vis_stderr, "The hierarchy manager is empty.  Read in design.\n");
00137     return NIL(Ntk_Network_t);
00138   }
00139 
00140   network = (Ntk_Network_t *) Hrc_NodeReadApplInfo(currentNode,
00141                                                    NTK_HRC_NODE_APPL_KEY);
00142   if (network == NIL(Ntk_Network_t)) {
00143     (void) fprintf(vis_stdout, "There is no network. Use flatten_hierarchy.\n");
00144     return NIL(Ntk_Network_t);
00145   }
00146 
00147   return network;
00148 }
00149 
00150   
00151 /*---------------------------------------------------------------------------*/
00152 /* Definition of internal functions                                          */
00153 /*---------------------------------------------------------------------------*/
00154 
00155 
00156 /*---------------------------------------------------------------------------*/
00157 /* Definition of static functions                                            */
00158 /*---------------------------------------------------------------------------*/
00159 
00217 static int
00218 CommandPrintNetworkStats(
00219   Hrc_Manager_t ** hmgr,
00220   int  argc,
00221   char ** argv)
00222 {
00223   int            c;
00224   Ntk_Network_t *network = Ntk_HrcManagerReadCurrentNetwork(*hmgr);
00225 
00226   /*
00227    * Parse the command line.
00228    */
00229   util_getopt_reset();
00230   while ((c = util_getopt(argc, argv, "h")) != EOF) {
00231     switch (c) {
00232       case 'h':
00233         goto usage;
00234       default:
00235         goto usage;
00236     }
00237   }
00238   
00239   if (network == NIL(Ntk_Network_t)) {
00240     return 1;
00241   }
00242 
00243   Ntk_NetworkPrintStats(vis_stdout, network);
00244   return 0;             /* normal exit */
00245 
00246 usage:
00247   (void) fprintf(vis_stderr, "usage: print_network_stats [-h]\n");
00248   (void) fprintf(vis_stderr, "   -h  print the command usage\n");
00249   return 1;             /* error exit */
00250 }
00251 
00252 
00308 static int
00309 CommandPrintNetwork(
00310   Hrc_Manager_t ** hmgr,
00311   int  argc,
00312   char ** argv)
00313 {
00314   int            c;
00315   boolean        printIo         = FALSE;  /* default */
00316   boolean        printTableStats = FALSE;  /* default */
00317   Ntk_Network_t *network         = Ntk_HrcManagerReadCurrentNetwork(*hmgr);
00318 
00319   /*
00320    * Parse the command line.
00321    */
00322   util_getopt_reset();
00323   while ((c = util_getopt(argc, argv, "fth")) != EOF) {
00324     switch (c) {
00325       case 'f':
00326         printIo = TRUE;
00327         break;
00328       case 't':
00329         printTableStats = TRUE;
00330         break;
00331       case 'h':
00332         goto usage;
00333       default:
00334         goto usage;
00335     }
00336   }
00337   
00338   if (network == NIL(Ntk_Network_t)) {
00339     return 1;
00340   }
00341 
00342   Ntk_NetworkPrint(vis_stdout, network, printIo, printTableStats);
00343   return 0;             /* normal exit */
00344 
00345 usage:
00346   (void) fprintf(vis_stderr, "usage: print_network [-f] [-h] [-t]\n");
00347   (void) fprintf(vis_stderr, "   -f  print fanins and fanouts of nodes\n");
00348   (void) fprintf(vis_stderr, "   -h  print the command usage\n");
00349   (void) fprintf(vis_stderr, "   -t  print table stats of nodes having tables\n");
00350   return 1;             /* error exit */
00351 }
00352 
00353 
00384 static int
00385 CommandPrintNetworkDot(
00386   Hrc_Manager_t ** hmgr,
00387   int  argc,
00388   char ** argv)
00389 {
00390   FILE *fp;
00391   int c, status;
00392   Ntk_Network_t *network = Ntk_HrcManagerReadCurrentNetwork(*hmgr);
00393 
00394   util_getopt_reset();
00395   while ((c = util_getopt(argc,argv,"h")) != EOF){
00396     switch(c){
00397       case 'h':
00398         goto usage;
00399       default:
00400         goto usage;
00401     }
00402   }
00403 
00404   /* Check if the network has been read in */
00405   if (network == NIL(Ntk_Network_t)) {
00406     return 1;
00407   }
00408 
00409   if (argc == 1) {
00410     fp = stdout;
00411   }
00412   else if (argc == 2) {
00413     fp = Cmd_FileOpen(*(++argv), "w", NIL(char *), /* silent */ 1);
00414     if (fp == NIL(FILE)) {
00415       (void) fprintf(vis_stderr, "Cannot write to %s\n", *argv);
00416       return 1;
00417     }
00418   }
00419   else {
00420     goto usage;
00421   }
00422 
00423   error_init();
00424   status = Ntk_NetworkPrintDot(fp, network);
00425   (void) fprintf(vis_stderr, "%s", error_string());
00426   fflush(fp);
00427   if (fp != stdout) {
00428     (void) fclose(fp);
00429   }
00430   return (status ? 0 : 1);
00431 
00432  usage:
00433   (void) fprintf(vis_stderr, "usage: print_network_dot [-h] [file]\n");
00434   (void) fprintf(vis_stderr, "    -h\t\tprint the command usage\n");
00435   return 1;
00436 }
00437 
00438 
00465 static int
00466 CommandWriteNetworkBlifMv(
00467   Hrc_Manager_t ** hmgr,
00468   int  argc,
00469   char ** argv)
00470 {
00471   FILE *fp;
00472   int c;
00473   boolean promotePseudo = FALSE;
00474   Ntk_Network_t *network = Ntk_HrcManagerReadCurrentNetwork(*hmgr);
00475 
00476   /* Check whether the network has been created. */
00477   if (network == NIL(Ntk_Network_t)) {
00478     return 1;
00479   }
00480 
00481   util_getopt_reset();
00482   while ((c = util_getopt(argc,argv,"hp")) != EOF){
00483     switch(c){
00484     case 'h':
00485       goto usage;
00486     case 'p':
00487       promotePseudo = TRUE;
00488       argv++;
00489       argc--;
00490       break;
00491     default:
00492       goto usage;
00493     }
00494   }
00495 
00496   if (argc == 1) {
00497     fp = vis_stdout;
00498   } else if (argc == 2) {
00499     fp = Cmd_FileOpen(*(++argv), "w", NIL(char *), /* silent */ 1);
00500     if (fp == NIL(FILE)) {
00501       (void) fprintf(vis_stderr, "Cannot write to %s\n", *argv);
00502       return 1;
00503     }
00504   } else {
00505     goto usage;
00506   }
00507 
00508   error_init();
00509   Ntk_NetworkWriteBlifMv(fp, network, promotePseudo);
00510   (void) fprintf(vis_stderr, "%s", error_string());
00511   fflush(fp);
00512   if (fp != vis_stdout) {
00513     (void) fclose(fp);
00514   }
00515   return 1;
00516 
00517  usage:
00518   (void) fprintf(vis_stderr, "usage: write_network_blif_mv [-h] [file]\n");
00519   (void) fprintf(vis_stderr, "    -h\t\tprint the command usage\n");
00520   (void) fprintf(vis_stderr, "    -p\t\tpromote pseudo inputs to primary inputs\n");
00521   return 1;
00522 
00523 } /* CommandWriteNetworkBlifMv */
00524 
00525 
00630 static int
00631 CommandFlattenHierarchy(
00632   Hrc_Manager_t ** hmgr,
00633   int  argc,
00634   char ** argv)
00635 {
00636   int            c;
00637   Ntk_Network_t *network;
00638   char          *fileName    = NIL(char);
00639   int            verbose     = 0;       /* default */
00640   int            sweep       = 1;  
00641   lsList         varNameList = (lsList) NULL;
00642   Hrc_Node_t    *currentNode = Hrc_ManagerReadCurrentNode(*hmgr);
00643   
00644   /*
00645    * Parse the command line.
00646    */
00647   util_getopt_reset();
00648   while ((c = util_getopt(argc, argv, "a:bhsv:")) != EOF) {
00649     switch (c) {
00650       case 'a':
00651         fileName = util_optarg;
00652         break;
00653       case 'b':
00654         break;
00655       case 'h':
00656         goto usage;
00657       case 's':
00658         sweep = 0;
00659         break;        
00660       case 'v':
00661         verbose = atoi(util_optarg);
00662         break;
00663       default:
00664         goto usage;
00665     }
00666   }
00667 
00668   if (currentNode == NIL(Hrc_Node_t)) { 
00669     (void) fprintf(vis_stdout, "The hierarchy manager is empty.  Read in design.\n");
00670     return 1;
00671   }
00672     
00673   /*
00674    * Process the file containing the variable names.
00675    */
00676   if (fileName != NIL(char)) {
00677     FILE *fp = Cmd_FileOpen(fileName, "r", NIL(char *), 0);
00678     if (fp == NIL(FILE)) {
00679       return 1;
00680     }
00681     else {
00682       boolean status;
00683       
00684       error_init();
00685       status = FileReadNameList(fp, &varNameList, verbose);
00686       (void) fclose(fp);
00687       if (status == FALSE) {
00688         (void) fprintf(vis_stderr, "Error reading variable name file:\n");
00689         (void) fprintf(vis_stderr, "%s", error_string());
00690         (void) fprintf(vis_stderr, "Cannot perform flatten_hierarchy.\n");
00691         return 1;
00692       }
00693     }
00694   }
00695 
00696   
00697   /*
00698    * If a network already exists, delete it.  Then create the new one, and
00699    * register it with the hrcNode.
00700    */
00701   network = (Ntk_Network_t *) Hrc_NodeReadApplInfo(currentNode,
00702                                                    NTK_HRC_NODE_APPL_KEY);
00703   if (network != NIL(Ntk_Network_t)) {
00704     (void) fprintf(vis_stdout, "Deleting current network and creating new one.\n");
00705     Hrc_NodeFreeApplInfo(currentNode, NTK_HRC_NODE_APPL_KEY);
00706   }
00707 
00708   error_init();
00709 
00710   network = Ntk_HrcNodeConvertToNetwork(currentNode, TRUE, varNameList);
00711 
00712   /* Clean up the varNameList. */
00713   if (varNameList != (lsList) NULL) {
00714     lsGen  gen;
00715     char  *varName;
00716     
00717     lsForEachItem(varNameList, gen, varName) {
00718       FREE(varName);
00719     }
00720     (void) lsDestroy(varNameList, (void (*) (lsGeneric)) NULL);
00721   }
00722   /* sweep network */
00723   if (network != NIL(Ntk_Network_t) && sweep ==1) {
00724     Ntk_NetworkSweep(network, verbose); 
00725   }
00726   
00727   if (network == NIL(Ntk_Network_t)) {
00728     (void) fprintf(vis_stderr, "%s", error_string());
00729     (void) fprintf(vis_stderr, "Cannot perform flatten_hierarchy.\n");
00730     return 1;
00731   }
00732   
00733   Hrc_NodeAddApplInfo(currentNode, NTK_HRC_NODE_APPL_KEY,
00734                       (Hrc_ApplInfoFreeFn) Ntk_NetworkFreeCallback,
00735                       (Hrc_ApplInfoChangeFn) NULL,  /* not currently used by hrc */
00736                       (void *) network);
00737 
00738   return 0;             /* normal exit */
00739 
00740 usage:
00741   (void) fprintf(vis_stderr, "usage: flatten_hierarchy [-a file] [-b] [-h] [-s] [-v #]\n");
00742   (void) fprintf(vis_stderr, "   -a file  variables to abstract\n");
00743   (void) fprintf(vis_stderr, "   -b       not used any longer\n");
00744   (void) fprintf(vis_stderr, "   -h       print the command usage\n");
00745   (void) fprintf(vis_stderr, "   -s       do not perform a sweep\n");  
00746   (void) fprintf(vis_stderr, "   -v #     verbosity level\n");
00747   return 1;             /* error exit */
00748 }
00749 
00750 
00775 static int
00776 CommandTestNetworkAcyclic(
00777   Hrc_Manager_t ** hmgr,
00778   int  argc,
00779   char ** argv)
00780 {
00781   int            c;
00782   Ntk_Network_t *network = Ntk_HrcManagerReadCurrentNetwork(*hmgr);
00783 
00784   /*
00785    * Parse the command line.
00786    */
00787   util_getopt_reset();
00788   while ((c = util_getopt(argc, argv, "h")) != EOF) {
00789     switch (c) {
00790       case 'h':
00791         goto usage;
00792       default:
00793         goto usage;
00794     }
00795   }
00796   
00797   if (network == NIL(Ntk_Network_t)) {
00798     return 1;
00799   }
00800 
00801   error_init();
00802   if (Ntk_NetworkTestIsAcyclic(network) == 0) {
00803     (void) fprintf(vis_stdout, "Combinational cycle found: ");
00804     (void) fprintf(vis_stdout, "%s", error_string());
00805     (void) fprintf(vis_stdout, "\n");
00806   }
00807   else {
00808     (void) fprintf(vis_stdout, "Network has no combinational cycles\n");
00809   }
00810   return 0;             /* normal exit */
00811 
00812 
00813 usage:
00814   (void) fprintf(vis_stderr, "usage: test_network_acyclic [-h]\n");
00815   (void) fprintf(vis_stderr, "   -h  print the command usage\n");
00816   return 1;             /* error exit */
00817 }
00818 
00819 
00860 static int
00861 CommandInitVerify(
00862   Hrc_Manager_t ** hmgr,
00863   int  argc,
00864   char ** argv)
00865 {
00866   int         c;
00867   Hrc_Node_t *currentNode = Hrc_ManagerReadCurrentNode(*hmgr);
00868   
00869   /*
00870    * Parse the command line.
00871    */
00872   util_getopt_reset();
00873   while ((c = util_getopt(argc, argv, "bh")) != EOF) {
00874     switch (c) {
00875       case 'b':
00876         break;
00877       case 'h':
00878         goto usage;
00879       default:
00880         goto usage;
00881     }
00882   }
00883 
00884   if (currentNode == NIL(Hrc_Node_t)) { 
00885     (void) fprintf(vis_stdout, "The hierarchy manager is empty.  Read in design.\n");
00886     return 1;
00887   }
00888     
00889   /*
00890    * Call the commands one-by-one, returning upon the first error.
00891    */
00892   if (Cmd_CommandExecute(hmgr, "flatten_hierarchy")) {
00893     return 1;
00894   }
00895   
00896   if (Cmd_CommandExecute(hmgr, "static_order")) {
00897     return 1;
00898   }
00899   
00900   if (Cmd_CommandExecute(hmgr, "build_partition_mdds")) {
00901     return 1;
00902   }
00903   
00904   return 0;             /* normal exit */
00905 
00906 
00907 usage:
00908   (void) fprintf(vis_stderr, "usage: init_verify [-b] [-h]\n");
00909   (void) fprintf(vis_stderr, "   -b  not used any longer.\n");
00910   (void) fprintf(vis_stderr, "   -h  print the command usage\n");
00911   return 1;             /* error exit */
00912 }
00913 
00914 
00944 static int
00945 CommandNetworkSweep(
00946   Hrc_Manager_t ** hmgr,
00947   int  argc,
00948   char ** argv)
00949 {
00950   int           c;
00951   Ntk_Network_t *network = Ntk_HrcManagerReadCurrentNetwork(*hmgr);
00952   int           verbosity = 0;
00953 
00954   /*
00955    * Parse the command line.
00956    */
00957   util_getopt_reset();
00958   while ((c = util_getopt(argc, argv, "hv")) != EOF) {
00959     switch (c) {
00960       case 'h':
00961         goto usage;
00962       case 'v':
00963         verbosity = 1;
00964         break;
00965       default:
00966         goto usage;
00967     }
00968   }
00969   
00970   if (network == NIL(Ntk_Network_t)) {
00971     return 1;
00972   }
00973   
00974   Ntk_NetworkSweep(network, verbosity);
00975   return 0;
00976 
00977 usage:
00978   (void) fprintf(vis_stderr, "usage: network_sweep [-h][-v]\n");
00979   (void) fprintf(vis_stderr, "   -h  print the command usage\n");
00980   (void) fprintf(vis_stderr, "   -v  print debug information\n");  
00981   return 1;             /* error exit */
00982 }
00983 
01004 static boolean
01005 FileReadNameList(
01006   FILE * fp,
01007   lsList * nameList /* of char *, for return */,
01008   int verbose)
01009 {
01010   int     c;
01011   int     state;
01012   int     curPosition = 0;
01013   char   *name;
01014   char    string[MAX_NAME_LENGTH];
01015   boolean returnFlag = TRUE;
01016   
01017   *nameList = lsCreate();
01018 
01019   state = STATE_TEST;
01020   while ((c = fgetc(fp)) != EOF) {
01021 
01022     switch (state) {
01023       case STATE_TEST:
01024         /* At start of a new line. */
01025         if (c == '#') {
01026           /* Line starting with comment character; wait for newline */
01027           state = STATE_WAIT;
01028         }
01029         else if ((c == ' ') || (c == '\t')) {
01030           /* Line starting with white space; wait for newline */
01031           state = STATE_WAIT;
01032         }
01033         else if (c == '\n') {
01034           /* Line starting with newline; go to next line */
01035           state = STATE_TEST;
01036         }
01037         else {
01038           /* Assume starting a name. */
01039           curPosition = 0;
01040           string[curPosition++] = c;
01041           state = STATE_IN;
01042         }
01043         break;
01044       case STATE_WAIT:
01045         /*
01046          * Waiting for the newline character.
01047          */
01048         state = (c == '\n') ? STATE_TEST : STATE_WAIT;
01049         break;
01050       case STATE_IN:
01051         /*
01052          * Parsing a name.  If white space reached, then terminate the
01053          * name and process it.  Else, continue parsing.
01054          */
01055         if ((c == ' ') || (c == '\n') || (c == '\t')) {
01056           string[curPosition] = '\0';
01057           name = util_strsav(string);
01058           if (verbose > 1) {
01059             (void) fprintf(vis_stdout, "Reading name: %s\n", name);
01060           }
01061           (void) lsNewEnd(*nameList, (lsGeneric) name, LS_NH);  
01062           
01063           state = (c == '\n') ? STATE_TEST : STATE_WAIT;
01064         }
01065         else {
01066           string[curPosition++] = c;
01067           if (curPosition >= MAX_NAME_LENGTH) {
01068             error_append("maximum name length exceeded");
01069             returnFlag = FALSE;
01070           }
01071           state = STATE_IN; /* redundant, but be explicit */
01072         }
01073         break;
01074       default:
01075         fail("unrecognized state");
01076     }
01077   }
01078 
01079   /*
01080    * Handle case where EOF terminates a name.
01081    */
01082   if (state == STATE_IN) {
01083     string[curPosition] = '\0';
01084     name = util_strsav(string);
01085     if (verbose > 1) {
01086       (void) fprintf(vis_stdout, "Reading name: %s\n", name);
01087     }
01088     (void) lsNewEnd(*nameList, (lsGeneric) name, LS_NH);  
01089           
01090   }
01091 
01092   if (returnFlag) {
01093     return TRUE;
01094   }
01095   else {
01096     (void) lsDestroy(*nameList, (void (*) (lsGeneric)) NULL);
01097     return FALSE;
01098   }
01099 }
01100 
01101