VPR-6.0

vpr/SRC/base/ReadOptions.c

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <string.h>
00003 #include <assert.h>
00004 #include "util.h"
00005 #include "vpr_types.h"
00006 #include "OptionTokens.h"
00007 #include "ReadOptions.h"
00008 
00009 /******** Function prototypes ********/
00010 
00011 static const char *const *ReadBaseToken(INP const char *const *Args,
00012                                         OUTP enum e_OptionBaseToken *Token);
00013 static void Error(INP const char *Token);
00014 static void ErrorOption(INP const char *Option);
00015 static const char *const *ProcessOption(INP const char *const *Args,
00016                                         INOUTP t_options * Options);
00017 static const char *const *ReadFloat(INP const char *const *Args,
00018                                     OUTP float *Val);
00019 static const char *const *ReadInt(INP const char *const *Args,
00020                                   OUTP int *Val);
00021 static const char *const *ReadOnOff(INP const char *const *Args,
00022                                     OUTP boolean * Val);
00023 static const char *const *ReadClusterSeed(INP const char *const *Args,
00024                                             OUTP enum e_cluster_seed *Type);
00025 static const char *const *ReadFixPins(INP const char *const *Args,
00026                                       OUTP char **PinFile);
00027 static const char *const *ReadPlaceAlgorithm(INP const char *const *Args,
00028                                              OUTP enum e_place_algorithm
00029                                              *Algo);
00030 static const char *const *ReadPlaceCostType(INP const char *const *Args,
00031                                             OUTP enum place_c_types *Type);
00032 static const char *const *ReadRouterAlgorithm(INP const char *const *Args,
00033                                               OUTP enum e_router_algorithm
00034                                               *Algo);
00035 static const char *const *ReadPackerAlgorithm(INP const char *const *Args,
00036                                               OUTP enum e_packer_algorithm
00037                                               *Algo);
00038 static const char *const *ReadBaseCostType(INP const char *const *Args,
00039                                         OUTP enum e_base_cost_type *BaseCostType);
00040 static const char *const *ReadRouteType(INP const char *const *Args,
00041                                         OUTP enum e_route_type *Type);
00042 static const char *const *ReadString(INP const char *const *Args,
00043                                      OUTP char **Val);
00044 
00045 
00046 /******** Subroutine implementations ********/
00047 
00048 void
00049 ReadOptions(INP int argc,
00050             INP char **argv,
00051             OUTP t_options * Options)
00052 {
00053     char **Args, **head;
00054 
00055     /* Clear values and pointers to zero */
00056     memset(Options, 0, sizeof(t_options));
00057 
00058     /* Alloc a new pointer list for args with a NULL at end.
00059      * This makes parsing the same as for archfile for consistency.
00060      * Skips the first arg as it is the program image path */
00061     --argc;
00062     ++argv;
00063     head = Args = (char **)my_malloc(sizeof(char *) * (argc + 1));
00064     memcpy(Args, argv, (sizeof(char *) * argc));
00065     Args[argc] = NULL;
00066 
00067     /* Go through the command line args. If they have hyphens they are 
00068      * options. Otherwise assume they are part of the four mandatory
00069      * arguments */
00070     while(*Args)
00071         {
00072             if(strncmp("--", *Args, 2) == 0)
00073                 {
00074                     *Args += 2; /* Skip the prefix */
00075                     Args =
00076                         (char **)ProcessOption((const char *const *)Args,
00077                                                Options);
00078                 }
00079             else if(strncmp("-", *Args, 1) == 0)
00080                 {
00081                     *Args += 1; /* Skip the prefix */
00082                     Args =
00083                         (char **)ProcessOption((const char *const *)Args,
00084                                                Options);
00085                 }
00086                 else if(NULL == Options->ArchFile)
00087                 {
00088                     Options->ArchFile = my_strdup(*Args);
00089                     ++Args;
00090                 }
00091             else if(NULL == Options->CircuitName)
00092                 {
00093                         Options->CircuitName = my_strdup(*Args);
00094                     ++Args;
00095                 }
00096             else
00097                 {
00098                     /* Not an option and arch and net already specified so fail */
00099                     Error(*Args);
00100                 }
00101         }
00102         free(head);
00103 }
00104 
00105 
00106 static const char *const *
00107 ProcessOption(INP const char *const *Args,
00108               INOUTP t_options * Options)
00109 {
00110     enum e_OptionBaseToken Token;
00111     const char *const *PrevArgs;
00112 
00113     PrevArgs = Args;
00114     Args = ReadBaseToken(Args, &Token);
00115 
00116     if(Token < OT_BASE_UNKNOWN)
00117         {
00118             ++Options->Count[Token];
00119         }
00120 
00121     switch (Token)
00122         {
00123         /* File naming options */
00124         case OT_BLIF_FILE:
00125                 return ReadString(Args, &Options->BlifFile);
00126         case OT_NET_FILE:
00127                 return ReadString(Args, &Options->NetFile);
00128         case OT_PLACE_FILE:
00129                 return ReadString(Args, &Options->PlaceFile);
00130         case OT_ROUTE_FILE:
00131                 return ReadString(Args, &Options->RouteFile);
00132         /* General Options */
00133     case OT_NODISP:
00134                 return Args;
00135         case OT_AUTO:
00136             return ReadInt(Args, &Options->GraphPause);
00137         case OT_PACK:
00138         case OT_ROUTE:
00139         case OT_PLACE:
00140             return Args;
00141         case OT_TIMING_ANALYZE_ONLY_WITH_NET_DELAY: 
00142                 return ReadFloat(Args, &Options->constant_net_delay);
00143         case OT_FAST:   
00144         case OT_FULL_STATS:
00145             return Args;
00146         case OT_TIMING_ANALYSIS:
00147             return ReadOnOff(Args, &Options->TimingAnalysis);
00148         case OT_OUTFILE_PREFIX:
00149             return ReadString(Args, &Options->OutFilePrefix);
00150 
00151         /* Clustering Options */
00152         case OT_GLOBAL_CLOCKS:
00153                 return ReadOnOff(Args, &Options->global_clocks);
00154         case OT_HILL_CLIMBING_FLAG:
00155                 return ReadOnOff(Args, &Options->hill_climbing_flag);
00156         case OT_SWEEP_HANGING_NETS_AND_INPUTS:
00157                 return ReadOnOff(Args, &Options->sweep_hanging_nets_and_inputs);
00158         case OT_TIMING_DRIVEN_CLUSTERING:
00159                 return ReadOnOff(Args, &Options->timing_driven);
00160         case OT_CLUSTER_SEED:
00161                 return ReadClusterSeed(Args, &Options->cluster_seed_type);
00162         case OT_ALPHA_CLUSTERING:
00163                 return ReadFloat(Args, &Options->alpha);
00164         case OT_BETA_CLUSTERING:
00165                 return ReadFloat(Args, &Options->beta);
00166         case OT_RECOMPUTE_TIMING_AFTER:
00167                 return ReadInt(Args, &Options->recompute_timing_after);
00168         case OT_CLUSTER_BLOCK_DELAY:
00169                 return ReadFloat(Args, &Options->block_delay);
00170         case OT_ALLOW_UNRELATED_CLUSTERING:
00171                 return ReadOnOff(Args, &Options->allow_unrelated_clustering);
00172         case OT_ALLOW_EARLY_EXIT:
00173                 return ReadOnOff(Args, &Options->allow_early_exit);
00174         case OT_INTRA_CLUSTER_NET_DELAY:
00175                 return ReadFloat(Args, &Options->intra_cluster_net_delay);
00176         case OT_INTER_CLUSTER_NET_DELAY:
00177                 return ReadFloat(Args, &Options->inter_cluster_net_delay);
00178         case OT_CONNECTION_DRIVEN_CLUSTERING:
00179                 return ReadOnOff(Args, &Options->connection_driven);
00180         case OT_SKIP_CLUSTERING:
00181                 return Args;
00182         case OT_PACKER_ALGORITHM:
00183                 return ReadPackerAlgorithm(Args, &Options->packer_algorithm);
00184         case OT_HACK_NO_LEGAL_FRAC_LUT:
00185                 return Args;
00186         case OT_HACK_SAFE_LATCH:
00187                 return Args;
00188 
00189 
00190         /* Placer Options */
00191         case OT_PLACE_ALGORITHM:
00192             return ReadPlaceAlgorithm(Args, &Options->PlaceAlgorithm);
00193         case OT_INIT_T:
00194             return ReadFloat(Args, &Options->PlaceInitT);
00195         case OT_EXIT_T:
00196             return ReadFloat(Args, &Options->PlaceExitT);
00197         case OT_ALPHA_T:
00198             return ReadFloat(Args, &Options->PlaceAlphaT);
00199         case OT_INNER_NUM:
00200             return ReadFloat(Args, &Options->PlaceInnerNum);
00201         case OT_SEED:
00202             return ReadInt(Args, &Options->Seed);
00203         case OT_PLACE_COST_EXP:
00204                 return ReadFloat(Args, &Options->place_cost_exp);
00205         case OT_PLACE_COST_TYPE:
00206             return ReadPlaceCostType(Args, &Options->PlaceCostType);
00207         case OT_PLACE_CHAN_WIDTH:
00208             return ReadInt(Args, &Options->PlaceChanWidth);
00209         case OT_NUM_REGIONS:
00210             return ReadInt(Args, &Options->PlaceNonlinearRegions);
00211         case OT_FIX_PINS:
00212             return ReadFixPins(Args, &Options->PinFile);
00213         case OT_ENABLE_TIMING_COMPUTATIONS:
00214                 return ReadOnOff(Args, &Options->ShowPlaceTiming);
00215         case OT_BLOCK_DIST:
00216                 return ReadInt(Args, &Options->block_dist);
00217 
00218         /* Placement Options Valid Only for Timing-Driven Placement */
00219         case OT_TIMING_TRADEOFF:
00220             return ReadFloat(Args, &Options->PlaceTimingTradeoff);
00221         case OT_RECOMPUTE_CRIT_ITER:
00222             return ReadInt(Args, &Options->RecomputeCritIter);
00223         case OT_INNER_LOOP_RECOMPUTE_DIVIDER:
00224                 return ReadInt(Args, &Options->inner_loop_recompute_divider);
00225         case OT_TD_PLACE_EXP_FIRST:
00226                 return ReadFloat(Args, &Options->place_exp_first);
00227         case OT_TD_PLACE_EXP_LAST:
00228                 return ReadFloat(Args, &Options->place_exp_last);
00229 
00230         /* Router Options */
00231         case OT_MAX_ROUTER_ITERATIONS:
00232                 return ReadInt(Args, &Options->max_router_iterations);
00233         case OT_BB_FACTOR:
00234                 return ReadInt(Args, &Options->bb_factor);
00235         case OT_INITIAL_PRES_FAC:
00236                 return ReadFloat(Args, &Options->initial_pres_fac);
00237         case OT_PRES_FAC_MULT:
00238                 return ReadFloat(Args, &Options->pres_fac_mult);
00239         case OT_ACC_FAC:
00240                 return ReadFloat(Args, &Options->acc_fac);
00241         case OT_FIRST_ITER_PRES_FAC:
00242                 return ReadFloat(Args, &Options->first_iter_pres_fac);
00243         case OT_BEND_COST:
00244                 return ReadFloat(Args, &Options->bend_cost);
00245         case OT_ROUTE_TYPE:
00246             return ReadRouteType(Args, &Options->RouteType);
00247         case OT_VERIFY_BINARY_SEARCH:
00248                 return Args;
00249         case OT_ROUTE_CHAN_WIDTH:
00250             return ReadInt(Args, &Options->RouteChanWidth);
00251         case OT_ROUTER_ALGORITHM:
00252             return ReadRouterAlgorithm(Args, &Options->RouterAlgorithm);
00253         case OT_BASE_COST_TYPE:
00254                 return ReadBaseCostType(Args, &Options->base_cost_type);
00255 
00256         /* Routing options valid only for timing-driven routing */
00257         case OT_ASTAR_FAC:
00258                 return ReadFloat(Args, &Options->astar_fac);
00259         case OT_MAX_CRITICALITY:
00260                 return ReadFloat(Args, &Options->max_criticality);
00261         case OT_CRITICALITY_EXP:
00262                 return ReadFloat(Args, &Options->criticality_exp);
00263         default:
00264             ErrorOption(*PrevArgs);
00265         }
00266     return NULL;
00267 }
00268 
00269 
00270 static const char *const *
00271 ReadBaseToken(INP const char *const *Args,
00272               OUTP enum e_OptionBaseToken *Token)
00273 {
00274     const struct s_TokenPair *Cur;
00275 
00276     /* Empty string is end of tokens marker */
00277     if(NULL == *Args)
00278         Error(*Args);
00279 
00280     /* Linear search for the pair */
00281     Cur = OptionBaseTokenList;
00282     while(Cur->Str)
00283         {
00284             if(strcmp(*Args, Cur->Str) == 0)
00285                 {
00286                     *Token = Cur->Enum;
00287                     return ++Args;
00288                 }
00289             ++Cur;
00290         }
00291 
00292     *Token = OT_BASE_UNKNOWN;
00293     return ++Args;
00294 }
00295 
00296 
00297 static const char *const *
00298 ReadToken(INP const char *const *Args,
00299           OUTP enum e_OptionArgToken *Token)
00300 {
00301     const struct s_TokenPair *Cur;
00302 
00303     /* Empty string is end of tokens marker */
00304     if(NULL == *Args)
00305         Error(*Args);
00306 
00307     /* Linear search for the pair */
00308     Cur = OptionArgTokenList;
00309     while(Cur->Str)
00310         {
00311             if(strcmp(*Args, Cur->Str) == 0)
00312                 {
00313                     *Token = Cur->Enum;
00314                     return ++Args;
00315                 }
00316             ++Cur;
00317         }
00318 
00319     *Token = OT_ARG_UNKNOWN;
00320     return ++Args;
00321 }
00322 
00323 
00324 /** Called for parse errors. Spits out a message and then exits program. */
00325 static void
00326 Error(INP const char *Token)
00327 {
00328     if(Token)
00329         {
00330             printf(ERRTAG "Unexpected token '%s' on command line\n", Token);
00331         }
00332     else
00333         {
00334             printf(ERRTAG "Missing token at end of command line\n");
00335         }
00336     exit(1);
00337 }
00338 
00339 
00340 static void
00341 ErrorOption(INP const char *Option)
00342 {
00343     printf(ERRTAG "Unexpected option '%s' on command line\n", Option);
00344     exit(1);
00345 }
00346 
00347 static const char *const *
00348 ReadClusterSeed(INP const char *const *Args,
00349                   OUTP enum e_cluster_seed *Type)
00350 {
00351     enum e_OptionArgToken Token;
00352     const char *const *PrevArgs;
00353 
00354     PrevArgs = Args;
00355     Args = ReadToken(Args, &Token);
00356     switch (Token)
00357         {
00358         case OT_TIMING:
00359             *Type = VPACK_TIMING;
00360             break;
00361         case OT_MAX_INPUTS:
00362             *Type = NONLINEAR_CONG;
00363             break;
00364         default:
00365             Error(*PrevArgs);
00366         }
00367 
00368     return Args;
00369 }
00370 
00371 static const char *const *
00372 ReadPackerAlgorithm(INP const char *const *Args,
00373                     OUTP enum e_packer_algorithm *Algo)
00374 {
00375     enum e_OptionArgToken Token;
00376     const char *const *PrevArgs;
00377 
00378     PrevArgs = Args;
00379     Args = ReadToken(Args, &Token);
00380     switch (Token)
00381         {
00382         case OT_GREEDY:
00383             *Algo = PACK_GREEDY;
00384             break;
00385         case OT_BRUTE_FORCE:
00386             *Algo = PACK_BRUTE_FORCE;
00387             break;
00388         default:
00389             Error(*PrevArgs);
00390         }
00391 
00392     return Args;
00393 }
00394 
00395 static const char *const *
00396 ReadRouterAlgorithm(INP const char *const *Args,
00397                     OUTP enum e_router_algorithm *Algo)
00398 {
00399     enum e_OptionArgToken Token;
00400     const char *const *PrevArgs;
00401 
00402     PrevArgs = Args;
00403     Args = ReadToken(Args, &Token);
00404     switch (Token)
00405         {
00406         case OT_BREADTH_FIRST:
00407             *Algo = BREADTH_FIRST;
00408             break;
00409         case OT_DIRECTED_SEARCH:
00410             *Algo = DIRECTED_SEARCH;
00411             break;
00412         case OT_TIMING_DRIVEN:
00413             *Algo = TIMING_DRIVEN;
00414             break;
00415         default:
00416             Error(*PrevArgs);
00417         }
00418 
00419     return Args;
00420 }
00421 
00422 static const char *const *
00423 ReadBaseCostType(INP const char *const *Args,
00424                     OUTP enum e_base_cost_type *BaseCostType)
00425 {
00426     enum e_OptionArgToken Token;
00427     const char *const *PrevArgs;
00428 
00429     PrevArgs = Args;
00430     Args = ReadToken(Args, &Token);
00431     switch (Token)
00432         {
00433         case OT_INTRINSIC_DELAY:
00434             *BaseCostType = INTRINSIC_DELAY;
00435             break;
00436         case OT_DELAY_NORMALIZED:
00437             *BaseCostType = DELAY_NORMALIZED;
00438             break;
00439         case OT_DEMAND_ONLY:
00440             *BaseCostType = DEMAND_ONLY;
00441             break;
00442         default:
00443             Error(*PrevArgs);
00444         }
00445 
00446     return Args;
00447 }
00448 
00449 
00450 static const char *const *
00451 ReadRouteType(INP const char *const *Args,
00452               OUTP enum e_route_type *Type)
00453 {
00454     enum e_OptionArgToken Token;
00455     const char *const *PrevArgs;
00456 
00457     PrevArgs = Args;
00458     Args = ReadToken(Args, &Token);
00459     switch (Token)
00460         {
00461         case OT_GLOBAL:
00462             *Type = GLOBAL;
00463             break;
00464         case OT_DETAILED:
00465             *Type = DETAILED;
00466             break;
00467         default:
00468             Error(*PrevArgs);
00469         }
00470 
00471     return Args;
00472 }
00473 
00474 
00475 static const char *const *
00476 ReadPlaceCostType(INP const char *const *Args,
00477                   OUTP enum place_c_types *Type)
00478 {
00479     enum e_OptionArgToken Token;
00480     const char *const *PrevArgs;
00481 
00482     PrevArgs = Args;
00483     Args = ReadToken(Args, &Token);
00484     switch (Token)
00485         {
00486         case OT_LINEAR:
00487             *Type = LINEAR_CONG;
00488             break;
00489         case OT_NONLINEAR:
00490             *Type = NONLINEAR_CONG;
00491             break;
00492         default:
00493             Error(*PrevArgs);
00494         }
00495 
00496     return Args;
00497 }
00498 
00499 
00500 static const char *const *
00501 ReadPlaceAlgorithm(INP const char *const *Args,
00502                    OUTP enum e_place_algorithm *Algo)
00503 {
00504     enum e_OptionArgToken Token;
00505     const char *const *PrevArgs;
00506 
00507     PrevArgs = Args;
00508     Args = ReadToken(Args, &Token);
00509     switch (Token)
00510         {
00511         case OT_BOUNDING_BOX:
00512             *Algo = BOUNDING_BOX_PLACE;
00513             break;
00514         case OT_NET_TIMING_DRIVEN:
00515             *Algo = NET_TIMING_DRIVEN_PLACE;
00516             break;
00517         case OT_PATH_TIMING_DRIVEN:
00518             *Algo = PATH_TIMING_DRIVEN_PLACE;
00519             break;
00520         default:
00521             Error(*PrevArgs);
00522         }
00523 
00524     return Args;
00525 }
00526 
00527 static const char *const *
00528 ReadFixPins(INP const char *const *Args,
00529             OUTP char **PinFile)
00530 {
00531     enum e_OptionArgToken Token;
00532     int Len;
00533         const char *const *PrevArgs = Args;
00534 
00535     Args = ReadToken(Args, &Token);
00536     if(OT_RANDOM != Token)
00537         {
00538             Len = 1 + strlen(*PrevArgs);
00539             *PinFile = (char *)my_malloc(Len * sizeof(char));
00540             memcpy(*PinFile, *PrevArgs, Len);
00541         }
00542     return Args;
00543 }
00544 
00545 
00546 static const char *const *
00547 ReadOnOff(INP const char *const *Args,
00548           OUTP boolean * Val)
00549 {
00550     enum e_OptionArgToken Token;
00551     const char *const *PrevArgs;
00552 
00553     PrevArgs = Args;
00554     Args = ReadToken(Args, &Token);
00555     switch (Token)
00556         {
00557         case OT_ON:
00558             *Val = TRUE;
00559             break;
00560         case OT_OFF:
00561             *Val = FALSE;
00562             break;
00563         default:
00564             Error(*PrevArgs);
00565         }
00566     return Args;
00567 }
00568 
00569 
00570 static const char *const *
00571 ReadInt(INP const char *const *Args,
00572         OUTP int *Val)
00573 {
00574     if(NULL == *Args)
00575         Error(*Args);
00576     if((**Args > '9') || (**Args < '0'))
00577         Error(*Args);
00578 
00579     *Val = atoi(*Args);
00580 
00581     return ++Args;
00582 }
00583 
00584 
00585 static const char *const *
00586 ReadFloat(INP const char *const *Args,
00587           OUTP float *Val)
00588 {
00589     if(NULL == *Args)
00590         {
00591             Error(*Args);
00592         }
00593 
00594     if((**Args != '-') &&
00595        (**Args != '.') && ((**Args > '9') || (**Args < '0')))
00596         {
00597             Error(*Args);
00598         }
00599 
00600     *Val = atof(*Args);
00601 
00602     return ++Args;
00603 }
00604 
00605 
00606 static const char *const *
00607 ReadString(INP const char *const *Args,
00608            OUTP char **Val)
00609 {
00610     if(NULL == *Args)
00611         {
00612             Error(*Args);
00613         }
00614 
00615     *Val = my_strdup(*Args);
00616 
00617     return ++Args;
00618 }