VIS

src/spfd/spfdCmd.c

Go to the documentation of this file.
00001 
00021 #include "spfdInt.h"
00022 
00023 static char rcsid[] UNUSED = "$Id: spfdCmd.c,v 1.28 2002/09/09 01:04:28 fabio Exp $";
00024 
00025 /*---------------------------------------------------------------------------*/
00026 /* Constant declarations                                                     */
00027 /*---------------------------------------------------------------------------*/
00028 
00029 /*---------------------------------------------------------------------------*/
00030 /* Type declarations                                                         */
00031 /*---------------------------------------------------------------------------*/
00032 
00033 
00034 /*---------------------------------------------------------------------------*/
00035 /* Structure declarations                                                    */
00036 /*---------------------------------------------------------------------------*/
00037 
00038 
00039 /*---------------------------------------------------------------------------*/
00040 /* Variable declarations                                                     */
00041 /*---------------------------------------------------------------------------*/
00042 
00043 static jmp_buf timeOutEnv; /* time out */
00044 int spfdCreatedPart; /* Whether network BDDs were created in the package */
00045 int spfdVerbose; /* verbosity */
00046 float spfdAlpha; /* spfdAlpha * load + (1-spfdAlpha) * topDepth, is used to order
00047                 fanin nodes during SPFD computation */
00048 boolean spfdPerfSim; /* Perform simulation */
00049 boolean spfdNtkChanged; /* TRUE if network changes structurally or functionally */
00050 boolean spfdReprogNoWire; /* If TRUE, no functional changes are performed
00051                          unless required by structural changes */
00052 int spfdWiresAdded, spfdNumWiresRem; /* Number of wires added and removed */
00053 int spfdSortNodes; /* Method to sort nodes */
00054 int spfdMethod; /* Optimization method */
00055 
00056 /*---------------------------------------------------------------------------*/
00057 /* Macro declarations                                                        */
00058 /*---------------------------------------------------------------------------*/
00059 
00060 
00063 /*---------------------------------------------------------------------------*/
00064 /* Static function prototypes                                                */
00065 /*---------------------------------------------------------------------------*/
00066 
00067 static int CommandSpfdNetworkOptimize(Hrc_Manager_t **hmgr, int argc, char **argv);
00068 static int CommandSpfdPlaceOptimize(Hrc_Manager_t **hmgr, int argc, char **argv);
00069 static void TimeOutHandle(void);
00070 static int TestIsNetworkMultipleValued(Ntk_Network_t *network);
00071 static int SpfdSimultaneousPlacementAndLogicOpt(Ntk_Network_t *network, char *netFile, char *archFile, char *placeFile, char *routeFile, char *netOutFile, int regionDepth);
00072 
00076 /*---------------------------------------------------------------------------*/
00077 /* Definition of exported functions                                          */
00078 /*---------------------------------------------------------------------------*/
00079 
00089 void
00090 Spfd_Init(void)
00091 {
00092   Cmd_CommandAdd("spfd_pilo", CommandSpfdNetworkOptimize, 1);
00093   Cmd_CommandAdd("spfd_pdlo", CommandSpfdPlaceOptimize, 1);
00094 
00095 } /* End of Spfd_Init */
00096 
00106 void
00107 Spfd_End(void)
00108 {
00109 
00110 } /* End of Spfd_End */
00111 
00112 /*---------------------------------------------------------------------------*/
00113 /* Definition of internal functions                                          */
00114 /*---------------------------------------------------------------------------*/
00115 
00116 
00117 /*---------------------------------------------------------------------------*/
00118 /* Definition of static functions                                            */
00119 /*---------------------------------------------------------------------------*/
00267 static int
00268 CommandSpfdNetworkOptimize(
00269   Hrc_Manager_t **hmgr,
00270   int argc,
00271   char **argv)
00272 {
00273 
00274   Ntk_Network_t *network = NIL(Ntk_Network_t);
00275   graph_t *simPart;
00276   int status,percent,frequency,regionDepth;
00277   int c;
00278   long timeOutPeriod,initialTime,finalTime;
00279   char *simFile,*writeFile;
00280   char endPtr[128];
00281   FILE *fp = NIL(FILE);
00282   
00283   /* These are the default values. */
00284   spfdCreatedPart = 0; /* Do not create a new partition */
00285   timeOutPeriod   = 0;  
00286   simFile = NIL(char);  /* File containing simulation vectors */
00287   spfdVerbose = 0; /* verbosity */
00288   regionDepth = 1; /* Depth of cluster */
00289   percent = 10; /* Percent of total vectors to be simulated during opt. */
00290   frequency = 5; /* Perform simulation every frequency iterations */
00291   spfdSortNodes = RANDOM; /* Choose a random node for optimization */
00292   spfdMethod = 2;
00293   spfdAlpha = 0.5; 
00294   writeFile = NIL(char); /* File to output final optimized ckt. */
00295   spfdNtkChanged = FALSE; 
00296   spfdReprogNoWire = TRUE;
00297   spfdWiresAdded = 0;
00298   spfdNumWiresRem = 0;
00299   spfdPerfSim = FALSE; /* Default */
00300   
00301   if (bdd_get_package_name() != CUDD) {
00302     (void) fprintf(vis_stderr,
00303                    "** spfd error: The spfd package can be used "
00304                    "only with CUDD package\n");
00305     (void) fprintf(vis_stderr,
00306                    "** spfd error: Please link with CUDD package\n");
00307     return 0;
00308   }
00309         
00310   util_getopt_reset();
00311 
00312   while((c = util_getopt(argc, argv, "a:D:f:hi:m:p:rS:t:v:w:")) != EOF) {
00313     switch(c) {
00314     case 'a':
00315       spfdAlpha = (float) strtod(util_optarg,(char **)&endPtr);
00316       if (!strcmp(util_optarg,endPtr)) {
00317         (void) fprintf(vis_stdout,
00318                        "** spfd warning: Invalid value <%s> specified for -a\n",
00319                        util_optarg);
00320         (void) fprintf(vis_stdout,"** spfd warning: Assuming 0.5.\n");
00321         spfdAlpha = 0.5;
00322       } else if (spfdAlpha > 1.0 || spfdAlpha < 0.0) {
00323         (void) fprintf(vis_stdout,
00324                        "** spfd warning: Value for -a <%f> not in [0,1]\n",
00325                        spfdAlpha);
00326         (void) fprintf(vis_stdout,"** spfd warning: Assuming 0.5.\n");
00327         spfdAlpha = 0.5;
00328       }
00329       break;
00330     case 'D':
00331       regionDepth = atoi(util_optarg);
00332       break;
00333     case 'f': 
00334       if (!util_optarg) {
00335         (void) fprintf(vis_stderr,
00336                        "** spfd error: Simulation file not specified.\n");
00337         goto usage;
00338       } else {
00339         simFile = util_strsav(util_optarg);
00340         if ((fp = Cmd_FileOpen(simFile,"r",NIL(char *),1)) == NIL(FILE)) {
00341           (void) fprintf(vis_stderr,
00342                          "** spfd error: Could not open %s for reading.\n",
00343                          simFile);
00344           goto endgame;
00345         } else {
00346           fclose(fp);
00347         }
00348         spfdPerfSim = TRUE;
00349       }
00350       break;
00351     case 'h':
00352       goto usage;
00353     case 'i':
00354       frequency = atoi(util_optarg);
00355       break;
00356     case 'm':
00357       spfdMethod = atoi(util_optarg);
00358       if (spfdMethod > 3 || spfdMethod < 0) {
00359         (void) fprintf(vis_stderr, "** spfd warning: -m has invalid argument\n");
00360         (void) fprintf(vis_stderr, "** spfd warning: Using 2 instead.\n");
00361       }
00362       break;
00363     case 'p':
00364       percent = atoi(util_optarg);
00365       if (percent > 100 || percent < 0) {
00366         (void) fprintf(vis_stderr,
00367                        "** spfd warning: -p <%d> has invalid argument.\n",
00368                        percent);
00369         (void) fprintf(vis_stderr,
00370                        "** spfd warning: Using 10%% instead.\n");
00371       }
00372       break;
00373     case 'r':
00374       spfdReprogNoWire = FALSE;
00375       break;
00376     case 'S':
00377       spfdSortNodes = atoi(util_optarg);
00378       if (spfdSortNodes > 4 || spfdSortNodes < 0) {
00379         (void) fprintf(vis_stderr,
00380                        "** spfd warning: -S <%d> has invalid argument.\n",
00381                        spfdSortNodes);
00382         (void) fprintf(vis_stderr,
00383                        "** spfd warning: Using 0 (random) instead.\n");
00384       }
00385       break;
00386     case 't':
00387       timeOutPeriod = atoi(util_optarg);
00388       break;
00389     case 'v':
00390       spfdVerbose = atoi(util_optarg);
00391       break;
00392     case 'w':
00393       writeFile = util_strsav(util_optarg);
00394       if ((fp = Cmd_FileOpen(writeFile,"w",NIL(char *),1)) == NIL(FILE)) {
00395         (void) fprintf(vis_stderr,
00396                        "** spfd error: Could not open %s for writing.\n",
00397                        writeFile);
00398         goto endgame;
00399       } else {
00400         fclose(fp);
00401       }
00402       break;
00403     default:
00404       goto usage;
00405     }
00406   }
00407 
00408   if(Hrc_ManagerReadCurrentNode(*hmgr) == NIL(Hrc_Node_t)) {
00409     (void) fprintf(vis_stderr,"** spfd error: The hierarchy manager is empty."
00410                    " Read in design.\n");
00411     goto endgame;
00412   }
00413 
00414   network = (Ntk_Network_t *) 
00415     Hrc_NodeReadApplInfo(Hrc_ManagerReadCurrentNode(*hmgr), 
00416                          NTK_HRC_NODE_APPL_KEY);
00417 
00418   if(network == NIL(Ntk_Network_t)) {
00419     (void) fprintf(vis_stderr,"** spfd error: There is no network. ");
00420     (void) fprintf(vis_stderr,"Use flatten_hierarchy.\n");
00421     goto endgame;
00422   }
00423     
00424   /* Check if the current network has signals with multiple values. */
00425   if (TestIsNetworkMultipleValued(network)) {
00426     (void) fprintf(vis_stderr,"** spfd error: Circuit has multiple "
00427                    "valued variables.\n");
00428     (void) fprintf(vis_stderr,"** spfd error: The algorithm currently "
00429                    "supports only Boolean valued variables.\n");
00430     goto endgame;
00431   }
00432 
00433   if(Ntk_NetworkReadNumPrimaryInputs(network) !=
00434      Ntk_NetworkReadNumInputs(network)) {
00435     (void) fprintf(vis_stderr,"** spfd error: Pseudo inputs present "
00436                    "in the network.\n");
00437     (void) fprintf(vis_stderr,"** spfd error: The algorithm does not apply.\n");
00438     goto endgame;
00439   }
00440 
00441   if(Ntk_NetworkReadNumLatches(network) > 0) {
00442     (void) fprintf(vis_stderr,"** spfd error: Sequential circuit.\n");
00443     (void) fprintf(vis_stderr,"** spfd error: The command is only for combinational circuits.\n");
00444     goto endgame;
00445   }
00446   
00447   /* Access a 'total' partition */
00448   simPart = (graph_t *) Ntk_NetworkReadApplInfo(network,PART_NETWORK_APPL_KEY);
00449   if (simPart == NIL(graph_t) || 
00450       (Part_PartitionReadMethod(simPart) != Part_Total_c)) {
00451     simPart = Part_NetworkCreatePartition(network, 
00452                                           NIL(Hrc_Node_t),
00453                                           "dummy", (lsList) 0, 
00454                                           (lsList) 0, NIL(mdd_t),
00455                                           Part_Total_c,
00456                                           (lsList) 0, 
00457                                           FALSE, FALSE, TRUE);
00458     if (simPart == NIL(graph_t)) {
00459       (void) fprintf(vis_stderr,"** spfd error: Could not create partition.\n");
00460       goto endgame;
00461     }
00462     Ntk_NetworkAddApplInfo(network,PART_NETWORK_APPL_KEY,
00463                            (Ntk_ApplInfoFreeFn)Part_PartitionFreeCallback,
00464                            (void *)simPart);
00465     spfdCreatedPart = 1; /* Using new partition */
00466     (void) fprintf(vis_stdout,
00467                    "** spfd info: A new partition created.\n");
00468   }
00469 
00470   /* Start the timer.*/
00471   if (timeOutPeriod > 0){
00472     (void) signal(SIGALRM, (void(*)(int))TimeOutHandle);
00473     (void) alarm(timeOutPeriod);
00474     if (setjmp(timeOutEnv) > 0) {
00475       (void) fprintf(vis_stderr, "** spfd warning: Timeout occurred after ");
00476       (void) fprintf(vis_stderr, "%ld seconds.\n", timeOutPeriod);
00477       alarm(0);
00478       goto endgame;
00479     }
00480   }
00481 
00482   initialTime = util_cpu_time();
00483 
00484   if (!spfdPerfSim) {
00485     (void) fprintf(vis_stdout,
00486                    "** spfd info: Simulation vectors not specified.\n");
00487     if (spfdSortNodes == MAXSWCAP) {
00488       (void) fprintf(vis_stdout,
00489                      "** spfd info: Using method -S 2 instead of -S 1\n");
00490       spfdSortNodes = MAXFANOUT;
00491     } else if (spfdSortNodes == MINSWCAP) {
00492       (void) fprintf(vis_stdout,
00493                      "** spfd info: Using method -S 4 instead of -S 3\n");      
00494       spfdSortNodes = MINFANOUT;
00495     }
00496   }
00497   status = SpfdNetworkOptimize(network,simFile,percent,frequency,regionDepth);
00498 
00499   finalTime = util_cpu_time();
00500   if(status) {
00501     (void) fprintf(vis_stdout, "%-20s%10ld\n", "** spfd info: analysis time =",
00502                    (finalTime-initialTime)/1000);
00503   }
00504   else {
00505     (void) fprintf(vis_stdout, "** spfd error: Optimization failed.\n");
00506   }
00507 
00508   if (writeFile) {
00509     SpfdNetworkWriteBlifFile(network,writeFile);
00510     FREE(writeFile);
00511   }
00512 
00513   if (simFile)
00514     FREE(simFile);
00515 
00516   if (spfdCreatedPart)
00517     Ntk_NetworkFreeApplInfo(network,PART_NETWORK_APPL_KEY);
00518   
00519   alarm(0);
00520   return 0;  /* normal exit */
00521 
00522 endgame:
00523   /* Clean up */
00524   if (simFile)
00525     FREE(simFile);
00526 
00527   if (writeFile)
00528     FREE(writeFile);
00529 
00530   if (spfdCreatedPart)
00531     Ntk_NetworkFreeApplInfo(network,PART_NETWORK_APPL_KEY);
00532   
00533   return 1; /* Error exit */
00534 
00535 usage:
00536 
00537   (void) fprintf(vis_stderr, "\nusage: Also see \'help spfd_pilo\' for more details.\n\n");
00538   (void) fprintf(vis_stderr, "    -a <alpha>\t\t<alpha> should be between 0.0 and 1.0\n");
00539   (void) fprintf(vis_stderr, "             \t\talpha*(SA*numFanout) + (1.0-alpha)*top_depth is used\n");
00540   (void) fprintf(vis_stderr, "             \t\tto order nodes during SPFD computation.\n");
00541   (void) fprintf(vis_stderr, "             \t\tSA is the switching activity of the node.\n");
00542   (void) fprintf(vis_stderr, "             \t\tThe default value is 0.5.\n\n");
00543   (void) fprintf(vis_stderr, "    -D <depth>\t\tCollect nodes that are within the specified depth.\n");
00544   (void) fprintf(vis_stderr, "            \t\tfrom the node being optimized.\n");
00545   (void) fprintf(vis_stderr, "            \t\tThe default is 1.\n\n");
00546   (void) fprintf(vis_stderr, "    -f <filename>\tFile containing simulation vectors.\n");
00547   (void) fprintf(vis_stderr, "               \t\tSee help for the format.\n\n"); 
00548   (void) fprintf(vis_stderr, "    -h      \t\tCommand usage.\n\n");
00549   (void) fprintf(vis_stderr, "    -i <freq> \t\tPerform internal simulations after \n");
00550   (void) fprintf(vis_stderr, "            \t\tevery <freq> iterations.\n");
00551   (void) fprintf(vis_stderr, "            \t\tDefault is 5.\n\n");
00552   (void) fprintf(vis_stderr, "    -m <n> \t\tHeuristics to optimize a selected node:\n");
00553   (void) fprintf(vis_stderr, "           \t\t0: Reduce the selected node's support.\n");
00554   (void) fprintf(vis_stderr, "           \t\t1: Reprogram the selected node.\n");
00555   (void) fprintf(vis_stderr, "           \t\t2: Reprogram the selected node's fanin nodes. (default)\n");
00556   (void) fprintf(vis_stderr, "           \t\t3: Reduce the selected node's fanout wires.\n\n");
00557   (void) fprintf(vis_stderr, "    -p <percent>\tPercent of total pattern vectors that\n");
00558   (void) fprintf(vis_stderr, "            \t\tshould be used during internal simulations.\n");
00559   (void) fprintf(vis_stderr, "            \t\tDefault is 10%%.\n\n");
00560   (void) fprintf(vis_stderr, "    -r      \t\tDo not reprogram internal nodes if the network\n");
00561   (void) fprintf(vis_stderr, "            \t\thas not changed structurally.\n");
00562   (void) fprintf(vis_stderr, "            \t\tBy default, reprogram.\n\n");
00563   (void) fprintf(vis_stderr, "    -S <value> \t\tHeuristic to select nodes for optimization.\n");
00564   (void) fprintf(vis_stderr, "            \t\t0. Random node. (default) \n");
00565   (void) fprintf(vis_stderr, "            \t\t1. Node with max. SA*numFanout.\n");
00566   (void) fprintf(vis_stderr, "            \t\t2. Node with max. fanout.\n");
00567   (void) fprintf(vis_stderr, "            \t\t3. Node with min. SA*numFanout.\n");
00568   (void) fprintf(vis_stderr, "            \t\t4. Node with min. fanout.\n\n");
00569   (void) fprintf(vis_stderr, "    -t <N>  \t\tTime (s) limit for the command.\n\n");
00570   (void) fprintf(vis_stderr, "    -v <N>  \t\tVerbosity level.\n\n");  
00571   (void) fprintf(vis_stderr, "    -w <filename>\tFile to output final optimized circuit.\n\n");
00572   (void) fprintf(vis_stderr, "set options: \n");
00573   (void) fprintf(vis_stderr, "\tspfd_repl_rem <yes|no>\n");
00574   (void) fprintf(vis_stderr, "\t\tReplace and remove wires simultaneously?\n");
00575   return 1;    /* error exit */
00576 
00577 } /* End of CommandSpfdNetworkOptimize */
00578 
00579 
00761 static int
00762 CommandSpfdPlaceOptimize(
00763   Hrc_Manager_t **hmgr,
00764   int argc,
00765   char **argv)
00766 {
00767 
00768 #ifndef USE_VPR
00769   (void) fprintf(vis_stdout,"** spfd info: This command requires VPR "
00770                  "(Versatile Place and Route)\n");
00771   (void) fprintf(vis_stdout,"** spfd info: See \'help spfd_pdlo\' for more "
00772                  "information\n");
00773   (void) fprintf(vis_stdout,"** spfd info: on how to compile VIS with VPR.\n");
00774   (void) fprintf(vis_stdout,"** spfd info: Exiting calmly ...\n");
00775   return 0;
00776 #else
00777   
00778   Ntk_Network_t *network;
00779   graph_t *simPart;
00780   int status,regionDepth;
00781   int c;
00782   long timeOutPeriod,initialTime,finalTime;
00783   char *writeFile;
00784   char *netFile,*archFile,*placeFile,*routeFile;
00785   char *netOutFile;
00786   FILE *fp = NIL(FILE);
00787 
00788 
00789   /* These are the default values. */
00790   spfdCreatedPart = 0; /* Do not create a new partition */
00791   timeOutPeriod   = 0;  
00792   spfdVerbose = 0; /* verbosity */
00793   regionDepth = 1; /* Depth of cluster */
00794   writeFile = NIL(char); /* File to output final optimized ckt. */
00795   spfdNtkChanged = FALSE;
00796   spfdReprogNoWire = TRUE;
00797   netFile = archFile = NIL(char); /* Circuit specified in VPR's .net
00798                                      format and FPGA architecture file */
00799   placeFile = routeFile = NIL(char); /* File to store placement and
00800                                         routing information */
00801   spfdWiresAdded = 0;
00802   spfdNumWiresRem = 0;
00803   netOutFile = NIL(char); /* File to output the optimized circuit in
00804                              .net format */
00805   status = FALSE;
00806   
00807   if (bdd_get_package_name() != CUDD) {
00808     (void) fprintf(vis_stderr,
00809                    "** spfd error: The spfd package can be used "
00810                    "only with CUDD package\n");
00811     (void) fprintf(vis_stderr,
00812                    "** spfd error: Please link with CUDD package\n");
00813     return 0;
00814   }
00815 
00816   util_getopt_reset();
00817   while((c = util_getopt(argc, argv, "D:hn:rt:v:w:")) != EOF) {
00818     switch(c) {
00819     case 'D':
00820       regionDepth = atoi(util_optarg);
00821       break;
00822     case 'h':
00823       goto usage;
00824     case 'n':
00825       netOutFile = util_strsav(util_optarg);
00826       break;      
00827     case 'r':
00828       spfdReprogNoWire = FALSE;
00829       break;
00830     case 't':
00831       timeOutPeriod = atoi(util_optarg);
00832       break;
00833     case 'v':
00834       spfdVerbose = atoi(util_optarg);
00835       break;
00836     case 'w':
00837       writeFile = util_strsav(util_optarg);
00838       if ((fp = Cmd_FileOpen(writeFile,"w",NIL(char *),1)) == NIL(FILE)) {
00839         (void) fprintf(vis_stderr,
00840                        "** spfd error: Could not open %s for writing.\n",
00841                        writeFile);
00842         goto endgame;
00843       } else {
00844         fclose(fp);
00845       }
00846       break;
00847     default:
00848       goto usage;
00849     }
00850   }
00851 
00852   /* netFile, archFile, and placeFile are essential. The user can
00853      specify /dev/null for routeFile if they don't want to store the
00854      routing information */
00855   if (argc < 5 || argc < util_optind+4)
00856     goto usage;
00857 
00858   /* Get the net, architecture, place and route file names */
00859   netFile = argv[util_optind];
00860   archFile = argv[util_optind+1];
00861   placeFile = argv[util_optind+2];
00862   routeFile = argv[util_optind+3];
00863 
00864   if(Hrc_ManagerReadCurrentNode(*hmgr) == NIL(Hrc_Node_t)) {
00865     (void) fprintf(vis_stderr,"** spfd error: The hierarchy manager is empty. "
00866                    "Read in design.\n");
00867     goto endgame;
00868   }
00869 
00870   network = (Ntk_Network_t *) 
00871     Hrc_NodeReadApplInfo(Hrc_ManagerReadCurrentNode(*hmgr), 
00872                          NTK_HRC_NODE_APPL_KEY);
00873 
00874   if(network == NIL(Ntk_Network_t)) {
00875     (void) fprintf(vis_stderr,"** spfd error: There is no network. ");
00876     (void) fprintf(vis_stderr,"Use flatten_hierarchy.\n");
00877     goto endgame;
00878   }
00879 
00880   /* Check if the current network has signals with multiple values. */
00881   if (TestIsNetworkMultipleValued(network)) {
00882     (void) fprintf(vis_stderr,"** spfd error: Circuit has multiple "
00883                    "valued variables.\n");
00884     (void) fprintf(vis_stderr,"** spfd error: The algorithm applies "
00885                    "to Boolean variables only.\n");
00886     goto endgame;
00887   }
00888 
00889   if(Ntk_NetworkReadNumPrimaryInputs(network) !=
00890      Ntk_NetworkReadNumInputs(network)) {
00891     (void) fprintf(vis_stderr,"** spfd error: Pseudo inputs present "
00892                    "in the network.\n");
00893     (void) fprintf(vis_stderr,"** spfd error: The algorithm does not apply.\n");
00894     goto endgame;
00895   }
00896 
00897   /* Access a 'total' partition */
00898   simPart = (graph_t *) Ntk_NetworkReadApplInfo(network, 
00899                                                 PART_NETWORK_APPL_KEY);
00900   if (simPart == NIL(graph_t) || 
00901       (Part_PartitionReadMethod(simPart) != Part_Total_c)) {
00902     simPart = Part_NetworkCreatePartition(network, 
00903                                           NIL(Hrc_Node_t),
00904                                           "dummy", (lsList) 0, 
00905                                           (lsList) 0, NIL(mdd_t),
00906                                           Part_Total_c,
00907                                           (lsList) 0, 
00908                                           FALSE, FALSE, TRUE);
00909     if (simPart == NIL(graph_t)) {
00910       (void) fprintf(vis_stderr,"** spfd error: Could not create partition.\n");
00911       goto endgame;
00912     }
00913     Ntk_NetworkAddApplInfo(network,PART_NETWORK_APPL_KEY,
00914                            (Ntk_ApplInfoFreeFn)Part_PartitionFreeCallback,
00915                            (void *)simPart);
00916     spfdCreatedPart = 1; /* Using new partition */
00917     (void) fprintf(vis_stdout,
00918                    "** spfd info: A new partition created.\n");
00919   }
00920 
00921   /* Start the timer.*/
00922   if (timeOutPeriod > 0){
00923     (void) signal(SIGALRM, (void(*)(int))TimeOutHandle);
00924     (void) alarm(timeOutPeriod);
00925     if (setjmp(timeOutEnv) > 0) {
00926       (void) fprintf(vis_stderr, "** spfd warning: Timeout occurred after ");
00927       (void) fprintf(vis_stderr, "%ld seconds.\n", timeOutPeriod);
00928       alarm(0);
00929       goto endgame;
00930     }
00931   }
00932 
00933   initialTime = util_cpu_time();
00934 
00935   /* Call the optimization routine. */
00936   status = SpfdSimultaneousPlacementAndLogicOpt(network,netFile,archFile,
00937                                                 placeFile,routeFile,netOutFile,
00938                                                 regionDepth);
00939   
00940   finalTime = util_cpu_time();
00941   if(status) {
00942     (void) fprintf(vis_stdout, "%-20s%10ld\n", "** spfd info: analysis time =",
00943                    (finalTime-initialTime)/1000);
00944   }
00945   else {
00946     (void) fprintf(vis_stdout, "** spfd error: Optimization failed.\n");
00947   }
00948 
00949   if (writeFile) {
00950     SpfdNetworkWriteBlifFile(network,writeFile);
00951     FREE(writeFile);
00952   }
00953 
00954   if (netOutFile) {
00955     FREE(netOutFile);
00956   }
00957 
00958   if (spfdCreatedPart)
00959     Ntk_NetworkFreeApplInfo(network,PART_NETWORK_APPL_KEY);
00960   
00961   alarm(0);
00962   return 0;  /* normal exit */
00963 
00964 endgame:
00965   /* Clean up */
00966   if (writeFile)
00967     FREE(writeFile);
00968 
00969   if (netOutFile) {
00970     FREE(netOutFile);
00971   }
00972   
00973   if (spfdCreatedPart)
00974     Ntk_NetworkFreeApplInfo(network,PART_NETWORK_APPL_KEY);
00975   
00976   return 1; /* Error exit */
00977 
00978 usage:
00979 
00980   (void) fprintf(vis_stderr, "\nusage: Also see \'help spfd_pdlo\' for more details.\n\n");
00981   (void) fprintf(vis_stderr, "spfd_pdlo [options] net_file arch_file place_file route_file\n\n");
00982   (void) fprintf(vis_stderr, "    -D <depth>\t\tConsider region upto <depth>.\n\n");
00983   (void) fprintf(vis_stderr, "    -h      \t\tCommand usage.\n\n");
00984   (void) fprintf(vis_stderr, "    -n <filename>\tFile to output optimized\n");
00985   (void) fprintf(vis_stderr, "            \t\tcircuit in .net format.\n\n");
00986   (void) fprintf(vis_stderr, "    -r      \t\tDo not reprogram internal nodes if there are no\n");
00987   (void) fprintf(vis_stderr, "            \t\tstructural changes in the network.\n\n");
00988   (void) fprintf(vis_stderr, "    -t <N>  \t\tTime (s) limit for the command.\n\n");  
00989   (void) fprintf(vis_stderr, "    -v <N>  \t\tVerbosity level.\n\n");
00990   (void) fprintf(vis_stderr, "    -w <filename>\tFile to output final optimized circuit.\n\n");
00991   (void) fprintf(vis_stderr, "set options: \n");
00992   (void) fprintf(vis_stderr, "\tspfd_pdlo_logic_move_freq \"r1 m1 r2 m2 ...\"\n");
00993   (void) fprintf(vis_stderr, "\t\tPerform m1 logic moves per temperature whenever the rate\n");
00994   (void) fprintf(vis_stderr, "\t\tof acceptance during simulated annealing is greater than\n");
00995   (void) fprintf(vis_stderr, "\t\tor equal to r1, and so on. r1 > r2 > r3 ... \n");
00996   (void) fprintf(vis_stderr, "\t\tand 0 <= ri <= 1.0.\n\n");
00997   (void) fprintf(vis_stderr, "\tspfd_repl_rem <yes|no>\n");
00998   (void) fprintf(vis_stderr, "\t\tPerform both wire replacement and removal?\n\n");
00999   (void) fprintf(vis_stderr, "\tspfd_pdlo_timing\n");
01000   (void) fprintf(vis_stderr, "\t\tUse timing driven method.\n");
01001   (void) fprintf(vis_stderr, "\t\tIf not set, Bounding box method is used.\n\n");
01002   (void) fprintf(vis_stderr, "\tspfd_pdlo_timing_nodeorwire\n");
01003   (void) fprintf(vis_stderr, "\t\tProcess the fanouts of the most tcritical node. If not set,\n");
01004   (void) fprintf(vis_stderr, "\t\tprocess only the wires on the critical path.\n\n");
01005   (void) fprintf(vis_stderr, "\tspfd_pdlo_out_crit_nets_first\n");
01006   (void) fprintf(vis_stderr, "\t\tOutput the circuit in VPR\'s .net format with\n");
01007   (void) fprintf(vis_stderr, "\t\tnets appearing in the increasing order of their slack.\n");
01008   (void) fprintf(vis_stderr, "\t\tIf not set, the initial net order specified in the original\n");
01009   (void) fprintf(vis_stderr, "\t\tcircuit\'s .net file is used. The file specified in -n option\n");
01010   (void) fprintf(vis_stderr, "\t\tis used. This option is valid only if spfd_pdlo_timing is set.\n\n");
01011   (void) fprintf(vis_stderr, "\tspfd_pdlo_remap_clb_array\n");
01012   (void) fprintf(vis_stderr, "\t\tReduce the size of FPGA if necessary during\n");
01013   (void) fprintf(vis_stderr, "\t\tlogic optimization.\n\n");
01014   (void) fprintf(vis_stderr, "set options for VPR: Please see VPR's manual for more information.\n");
01015   (void) fprintf(vis_stderr, "    vpr_nodisp\n");
01016   (void) fprintf(vis_stderr, "    vpr_fix_pins\n");
01017   (void) fprintf(vis_stderr, "    vpr_nx\n");
01018   (void) fprintf(vis_stderr, "    vpr_ny\n");
01019   (void) fprintf(vis_stderr, "    vpr_fast\n");
01020   (void) fprintf(vis_stderr, "    vpr_init_t\n");
01021   (void) fprintf(vis_stderr, "    vpr_alpha_t \n");
01022   (void) fprintf(vis_stderr, "    vpr_exit_t\n");
01023   (void) fprintf(vis_stderr, "    vpr_inner_num\n");
01024   (void) fprintf(vis_stderr, "    vpr_seed\n");
01025   (void) fprintf(vis_stderr, "    vpr_place_cost_exp\n");
01026   (void) fprintf(vis_stderr, "    vpr_place_chan_width\n");
01027   return 1;    /* error exit */
01028 #endif /* ifdef USE_VPR */
01029 
01030 } /* End of CommandSpfdPlaceOptimize */
01031 
01032 
01042 static void
01043 TimeOutHandle(void)
01044 {
01045   longjmp(timeOutEnv, 1);
01046 }
01047 
01060 static int
01061 TestIsNetworkMultipleValued(Ntk_Network_t *network)
01062 {
01063   Ntk_Node_t *node;
01064   lsGen gen;
01065   Var_Variable_t *var;
01066   int numValues;
01067 
01068   Ntk_NetworkForEachNode(network,gen,node) {
01069     var = Ntk_NodeReadVariable(node);
01070     numValues = Var_VariableReadNumValues(var);
01071     if (numValues > 2)
01072       return 1;
01073   }
01074   return 0;
01075 }
01076 
01077 #ifndef USE_VPR
01078 
01085 static int 
01086 SpfdSimultaneousPlacementAndLogicOpt(
01087   Ntk_Network_t *network,
01088   char *netFile,
01089   char *archFile,
01090   char *placeFile,
01091   char *routeFile,
01092   char *netOutFile,
01093   int regionDepth)
01094 {
01095   return 0;
01096 }
01097 #endif