VIS
|
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