| #include <assert.h> | |
| #include <string.h> | |
| #include "util.h" | |
| #include "vpr_types.h" | |
| #include "OptionTokens.h" | |
| #include "ReadOptions.h" | |
| #include "globals.h" | |
| #include "read_xml_arch_file.h" | |
| #include "SetupVPR.h" | |
| #include "pb_type_graph.h" | |
| static void SetupOperation(INP t_options Options, | |
| OUTP enum e_operation *Operation); | |
| static void SetupPackerOpts(INP t_options Options, | |
| INP boolean TimingEnabled, | |
| INP t_arch Arch, | |
| INP char *net_file, | |
| OUTP struct s_packer_opts *PackerOpts); | |
| static void SetupPlacerOpts(INP t_options Options, | |
| INP boolean TimingEnabled, | |
| OUTP struct s_placer_opts *PlacerOpts); | |
| static void SetupAnnealSched(INP t_options Options, | |
| OUTP struct s_annealing_sched *AnnealSched); | |
| static void SetupRouterOpts(INP t_options Options, | |
| INP boolean TimingEnabled, | |
| OUTP struct s_router_opts *RouterOpts); | |
| static void SetupRoutingArch(INP t_arch Arch, | |
| OUTP struct s_det_routing_arch *RoutingArch); | |
| static void SetupTiming(INP t_options Options, | |
| INP t_arch Arch, | |
| INP boolean TimingEnabled, | |
| INP enum e_operation Operation, | |
| INP struct s_placer_opts PlacerOpts, | |
| INP struct s_router_opts RouterOpts, | |
| OUTP t_timing_inf * Timing); | |
| static void SetupSwitches(INP t_arch Arch, | |
| INOUTP struct s_det_routing_arch *RoutingArch, | |
| INP struct s_switch_inf *ArchSwitches, | |
| INP int NumArchSwitches); | |
| /* Sets VPR parameters and defaults. Does not do any error checking | |
| * as this should have been done by the various input checkers */ | |
| void | |
| SetupVPR(INP t_options Options, | |
| INP boolean TimingEnabled, | |
| OUTP struct s_file_name_opts *FileNameOpts, | |
| OUTP t_arch * Arch, | |
| OUTP enum e_operation *Operation, | |
| OUTP t_model ** user_models, | |
| OUTP t_model ** library_models, | |
| OUTP struct s_packer_opts *PackerOpts, | |
| OUTP struct s_placer_opts *PlacerOpts, | |
| OUTP struct s_annealing_sched *AnnealSched, | |
| OUTP struct s_router_opts *RouterOpts, | |
| OUTP struct s_det_routing_arch *RoutingArch, | |
| OUTP t_segment_inf ** Segments, | |
| OUTP t_timing_inf * Timing, | |
| OUTP boolean * ShowGraphics, | |
| OUTP int *GraphPause) | |
| { | |
| int i, j, len; | |
| /* init default filenames */ | |
| if(Options.BlifFile == NULL) { | |
| len = strlen(Options.CircuitName) + 6; /* circuit_name.blif/0*/ | |
| if(Options.OutFilePrefix != NULL) { | |
| len += strlen(Options.OutFilePrefix); | |
| } | |
| Options.BlifFile = my_calloc(len,sizeof(char)); | |
| if(Options.OutFilePrefix == NULL) { | |
| sprintf(Options.BlifFile, "%s.blif", Options.CircuitName); | |
| } else { | |
| sprintf(Options.BlifFile, "%s%s.blif", Options.OutFilePrefix, Options.CircuitName); | |
| } | |
| } | |
| if(Options.NetFile == NULL) { | |
| len = strlen(Options.CircuitName) + 5; /* circuit_name.net/0*/ | |
| if(Options.OutFilePrefix != NULL) { | |
| len += strlen(Options.OutFilePrefix); | |
| } | |
| Options.NetFile = my_calloc(len,sizeof(char)); | |
| if(Options.OutFilePrefix == NULL) { | |
| sprintf(Options.NetFile, "%s.net", Options.CircuitName); | |
| } else { | |
| sprintf(Options.NetFile, "%s%s.net", Options.OutFilePrefix, Options.CircuitName); | |
| } | |
| } | |
| if(Options.PlaceFile == NULL) { | |
| len = strlen(Options.CircuitName) + 7; /* circuit_name.place/0*/ | |
| if(Options.OutFilePrefix != NULL) { | |
| len += strlen(Options.OutFilePrefix); | |
| } | |
| Options.PlaceFile = my_calloc(len,sizeof(char)); | |
| if(Options.OutFilePrefix == NULL) { | |
| sprintf(Options.PlaceFile, "%s.place", Options.CircuitName); | |
| } else { | |
| sprintf(Options.PlaceFile, "%s%s.place", Options.OutFilePrefix, Options.CircuitName); | |
| } | |
| } | |
| if(Options.RouteFile == NULL) { | |
| len = strlen(Options.CircuitName) + 7; /* circuit_name.route/0*/ | |
| if(Options.OutFilePrefix != NULL) { | |
| len += strlen(Options.OutFilePrefix); | |
| } | |
| Options.RouteFile = my_calloc(len,sizeof(char)); | |
| if(Options.OutFilePrefix == NULL) { | |
| sprintf(Options.RouteFile, "%s.route", Options.CircuitName); | |
| } else { | |
| sprintf(Options.RouteFile, "%s%s.route", Options.OutFilePrefix, Options.CircuitName); | |
| } | |
| } | |
| FileNameOpts->CircuitName = Options.CircuitName; | |
| FileNameOpts->ArchFile = Options.ArchFile; | |
| FileNameOpts->BlifFile = Options.BlifFile; | |
| FileNameOpts->NetFile = Options.NetFile; | |
| FileNameOpts->PlaceFile = Options.PlaceFile; | |
| FileNameOpts->RouteFile = Options.RouteFile; | |
| FileNameOpts->OutFilePrefix = Options.OutFilePrefix; | |
| SetupOperation(Options, Operation); | |
| SetupPlacerOpts(Options, TimingEnabled, PlacerOpts); | |
| SetupAnnealSched(Options, AnnealSched); | |
| SetupRouterOpts(Options, TimingEnabled, RouterOpts); | |
| XmlReadArch(Options.ArchFile, TimingEnabled, Arch, | |
| &type_descriptors, &num_types); | |
| *user_models = Arch->models; | |
| *library_models = Arch->model_library; | |
| /* TODO: this is inelegant, I should be populating this information in XmlReadArch */ | |
| EMPTY_TYPE = NULL; | |
| FILL_TYPE = NULL; | |
| IO_TYPE = NULL; | |
| for(i = 0; i < num_types; i++) { | |
| if(strcmp(type_descriptors[i].name, "<EMPTY>") == 0) { | |
| EMPTY_TYPE = &type_descriptors[i]; | |
| } else if(strcmp(type_descriptors[i].name, "io") == 0) { | |
| IO_TYPE = &type_descriptors[i]; | |
| } else { | |
| for(j = 0; j < type_descriptors[i].num_grid_loc_def; j++) { | |
| if(type_descriptors[i].grid_loc_def[j].grid_loc_type == FILL) { | |
| assert(FILL_TYPE == NULL); | |
| FILL_TYPE = &type_descriptors[i]; | |
| } | |
| } | |
| } | |
| } | |
| assert(EMPTY_TYPE != NULL && FILL_TYPE != NULL && IO_TYPE != NULL); | |
| *Segments = Arch->Segments; | |
| RoutingArch->num_segment = Arch->num_segments; | |
| SetupSwitches(*Arch, RoutingArch, Arch->Switches, Arch->num_switches); | |
| SetupRoutingArch(*Arch, RoutingArch); | |
| SetupTiming(Options, *Arch, TimingEnabled, *Operation, | |
| *PlacerOpts, *RouterOpts, Timing); | |
| SetupPackerOpts(Options, TimingEnabled, *Arch, Options.NetFile, PackerOpts); | |
| /* init global variables */ | |
| OutFilePrefix = Options.OutFilePrefix; | |
| grid_logic_tile_area = Arch->grid_logic_tile_area; | |
| ipin_mux_trans_size = Arch->ipin_mux_trans_size; | |
| /* Set seed for pseudo-random placement, default seed to 1 */ | |
| PlacerOpts->seed = 1; | |
| if(Options.Count[OT_SEED]) | |
| { | |
| PlacerOpts->seed = Options.Seed; | |
| } | |
| my_srandom(PlacerOpts->seed); | |
| printf("Building complex block graph \n"); | |
| alloc_and_load_all_pb_graphs(); | |
| #ifdef DUMP_PB_GRAPH | |
| echo_pb_graph("pb_graph.echo"); | |
| #endif | |
| *GraphPause = 1; /* DEFAULT */ | |
| if(Options.Count[OT_AUTO]) | |
| { | |
| *GraphPause = Options.GraphPause; | |
| } | |
| #ifdef NO_GRAPHICS | |
| *ShowGraphics = FALSE; /* DEFAULT */ | |
| #else /* NO_GRAPHICS */ | |
| *ShowGraphics = TRUE; /* DEFAULT */ | |
| if(Options.Count[OT_NODISP]) | |
| { | |
| *ShowGraphics = FALSE; | |
| } | |
| #endif /* NO_GRAPHICS */ | |
| #ifdef CREATE_ECHO_FILES | |
| EchoArch("arch.echo", type_descriptors, num_types, Arch); | |
| #endif | |
| } | |
| static void | |
| SetupTiming(INP t_options Options, | |
| INP t_arch Arch, | |
| INP boolean TimingEnabled, | |
| INP enum e_operation Operation, | |
| INP struct s_placer_opts PlacerOpts, | |
| INP struct s_router_opts RouterOpts, | |
| OUTP t_timing_inf * Timing) | |
| { | |
| /* Don't do anything if they don't want timing */ | |
| if(FALSE == TimingEnabled) | |
| { | |
| memset(Timing, 0, sizeof(t_timing_inf)); | |
| Timing->timing_analysis_enabled = FALSE; | |
| return; | |
| } | |
| Timing->C_ipin_cblock = Arch.C_ipin_cblock; | |
| Timing->T_ipin_cblock = Arch.T_ipin_cblock; | |
| Timing->timing_analysis_enabled = TimingEnabled; | |
| } | |
| /* This loads up VPR's switch_inf data by combining the switches from | |
| * the arch file with the special switches that VPR needs. */ | |
| static void | |
| SetupSwitches(INP t_arch Arch, | |
| INOUTP struct s_det_routing_arch *RoutingArch, | |
| INP struct s_switch_inf *ArchSwitches, | |
| INP int NumArchSwitches) | |
| { | |
| RoutingArch->num_switch = NumArchSwitches; | |
| /* Depends on RoutingArch->num_switch */ | |
| RoutingArch->wire_to_ipin_switch = RoutingArch->num_switch; | |
| ++RoutingArch->num_switch; | |
| /* Depends on RoutingArch->num_switch */ | |
| RoutingArch->delayless_switch = RoutingArch->num_switch; | |
| RoutingArch->global_route_switch = RoutingArch->delayless_switch; | |
| ++RoutingArch->num_switch; | |
| /* Alloc the list now that we know the final num_switch value */ | |
| switch_inf = | |
| (struct s_switch_inf *)my_malloc(sizeof(struct s_switch_inf) * | |
| RoutingArch->num_switch); | |
| /* Copy the switch data from architecture file */ | |
| memcpy(switch_inf, ArchSwitches, | |
| sizeof(struct s_switch_inf) * NumArchSwitches); | |
| /* Delayless switch for connecting sinks and sources with their pins. */ | |
| switch_inf[RoutingArch->delayless_switch].buffered = TRUE; | |
| switch_inf[RoutingArch->delayless_switch].R = 0.; | |
| switch_inf[RoutingArch->delayless_switch].Cin = 0.; | |
| switch_inf[RoutingArch->delayless_switch].Cout = 0.; | |
| switch_inf[RoutingArch->delayless_switch].Tdel = 0.; | |
| /* The wire to ipin switch for all types. Curently all types | |
| * must share ipin switch. Some of the timing code would | |
| * need to be changed otherwise. */ | |
| switch_inf[RoutingArch->wire_to_ipin_switch].buffered = TRUE; | |
| switch_inf[RoutingArch->wire_to_ipin_switch].R = 0.; | |
| switch_inf[RoutingArch->wire_to_ipin_switch].Cin = Arch.C_ipin_cblock; | |
| switch_inf[RoutingArch->wire_to_ipin_switch].Cout = 0.; | |
| switch_inf[RoutingArch->wire_to_ipin_switch].Tdel = Arch.T_ipin_cblock; | |
| } | |
| /* Sets up routing structures. Since checks are already done, this | |
| * just copies values across */ | |
| static void | |
| SetupRoutingArch(INP t_arch Arch, | |
| OUTP struct s_det_routing_arch *RoutingArch) | |
| { | |
| RoutingArch->switch_block_type = Arch.SBType; | |
| RoutingArch->R_minW_nmos = Arch.R_minW_nmos; | |
| RoutingArch->R_minW_pmos = Arch.R_minW_pmos; | |
| RoutingArch->Fs = Arch.Fs; | |
| RoutingArch->directionality = BI_DIRECTIONAL; | |
| if(Arch.Segments) | |
| RoutingArch->directionality = Arch.Segments[0].directionality; | |
| } | |
| static void | |
| SetupRouterOpts(INP t_options Options, | |
| INP boolean TimingEnabled, | |
| OUTP struct s_router_opts *RouterOpts) | |
| { | |
| RouterOpts->astar_fac = 1.2; /* DEFAULT */ | |
| if(Options.Count[OT_ASTAR_FAC]) | |
| { | |
| RouterOpts->astar_fac = Options.astar_fac; | |
| } | |
| RouterOpts->bb_factor = 3; /* DEFAULT */ | |
| if(Options.Count[OT_FAST]) | |
| { | |
| RouterOpts->bb_factor = 0; /* DEFAULT */ | |
| } | |
| if(Options.Count[OT_BB_FACTOR]) | |
| { | |
| RouterOpts->bb_factor = Options.bb_factor; | |
| } | |
| RouterOpts->criticality_exp = 1.0; /* DEFAULT */ | |
| if(Options.Count[OT_CRITICALITY_EXP]) | |
| { | |
| RouterOpts->criticality_exp = Options.criticality_exp; | |
| } | |
| RouterOpts->max_criticality = 0.99; /* DEFAULT */ | |
| if(Options.Count[OT_MAX_CRITICALITY]) | |
| { | |
| RouterOpts->max_criticality = Options.max_criticality; | |
| } | |
| RouterOpts->max_router_iterations = 50; /* DEFAULT */ | |
| if(Options.Count[OT_FAST]) | |
| { | |
| RouterOpts->max_router_iterations = 10; | |
| } | |
| if(Options.Count[OT_MAX_ROUTER_ITERATIONS]) | |
| { | |
| RouterOpts->max_router_iterations = Options.max_router_iterations; | |
| } | |
| RouterOpts->pres_fac_mult = 1.3; /* DEFAULT */ | |
| if(Options.Count[OT_PRES_FAC_MULT]) | |
| { | |
| RouterOpts->pres_fac_mult = Options.pres_fac_mult; | |
| } | |
| RouterOpts->route_type = DETAILED; /* DEFAULT */ | |
| if(Options.Count[OT_ROUTE_TYPE]) | |
| { | |
| RouterOpts->route_type = Options.RouteType; | |
| } | |
| RouterOpts->full_stats = FALSE; /* DEFAULT */ | |
| if(Options.Count[OT_FULL_STATS]) | |
| { | |
| RouterOpts->full_stats = TRUE; | |
| } | |
| RouterOpts->verify_binary_search = FALSE; /* DEFAULT */ | |
| if(Options.Count[OT_VERIFY_BINARY_SEARCH]) | |
| { | |
| RouterOpts->verify_binary_search = TRUE; | |
| } | |
| /* Depends on RouteOpts->route_type */ | |
| RouterOpts->router_algorithm = DIRECTED_SEARCH; /* DEFAULT */ | |
| if(TimingEnabled) | |
| { | |
| RouterOpts->router_algorithm = TIMING_DRIVEN; /* DEFAULT */ | |
| } | |
| if(GLOBAL == RouterOpts->route_type) | |
| { | |
| RouterOpts->router_algorithm = DIRECTED_SEARCH; /* DEFAULT */ | |
| } | |
| if(Options.Count[OT_ROUTER_ALGORITHM]) | |
| { | |
| RouterOpts->router_algorithm = Options.RouterAlgorithm; | |
| } | |
| RouterOpts->fixed_channel_width = NO_FIXED_CHANNEL_WIDTH; /* DEFAULT */ | |
| if(Options.Count[OT_ROUTE_CHAN_WIDTH]) | |
| { | |
| RouterOpts->fixed_channel_width = Options.RouteChanWidth; | |
| } | |
| /* Depends on RouterOpts->router_algorithm */ | |
| RouterOpts->initial_pres_fac = 0.5; /* DEFAULT */ | |
| if(DIRECTED_SEARCH == RouterOpts->router_algorithm || | |
| Options.Count[OT_FAST]) | |
| { | |
| RouterOpts->initial_pres_fac = 10000.0; /* DEFAULT */ | |
| } | |
| if(Options.Count[OT_INITIAL_PRES_FAC]) | |
| { | |
| RouterOpts->initial_pres_fac = Options.initial_pres_fac; | |
| } | |
| /* Depends on RouterOpts->router_algorithm */ | |
| RouterOpts->base_cost_type = DELAY_NORMALIZED; /* DEFAULT */ | |
| if(BREADTH_FIRST == RouterOpts->router_algorithm) | |
| { | |
| RouterOpts->base_cost_type = DEMAND_ONLY; /* DEFAULT */ | |
| } | |
| if(DIRECTED_SEARCH == RouterOpts->router_algorithm) | |
| { | |
| RouterOpts->base_cost_type = DEMAND_ONLY; /* DEFAULT */ | |
| } | |
| if(Options.Count[OT_BASE_COST_TYPE]) | |
| { | |
| RouterOpts->base_cost_type = Options.base_cost_type; | |
| } | |
| /* Depends on RouterOpts->router_algorithm */ | |
| RouterOpts->first_iter_pres_fac = 0.5; /* DEFAULT */ | |
| if(BREADTH_FIRST == RouterOpts->router_algorithm) | |
| { | |
| RouterOpts->first_iter_pres_fac = 0.0; /* DEFAULT */ | |
| } | |
| if(DIRECTED_SEARCH == RouterOpts->router_algorithm || | |
| Options.Count[OT_FAST]) | |
| { | |
| RouterOpts->first_iter_pres_fac = 10000.0; /* DEFAULT */ | |
| } | |
| if(Options.Count[OT_FIRST_ITER_PRES_FAC]) | |
| { | |
| RouterOpts->first_iter_pres_fac = Options.first_iter_pres_fac; | |
| } | |
| /* Depends on RouterOpts->router_algorithm */ | |
| RouterOpts->acc_fac = 1.0; | |
| if(BREADTH_FIRST == RouterOpts->router_algorithm) | |
| { | |
| RouterOpts->acc_fac = 0.2; | |
| } | |
| if(Options.Count[OT_ACC_FAC]) | |
| { | |
| RouterOpts->acc_fac = Options.acc_fac; | |
| } | |
| /* Depends on RouterOpts->route_type */ | |
| RouterOpts->bend_cost = 0.0; /* DEFAULT */ | |
| if(GLOBAL == RouterOpts->route_type) | |
| { | |
| RouterOpts->bend_cost = 1.0; /* DEFAULT */ | |
| } | |
| if(Options.Count[OT_BEND_COST]) | |
| { | |
| RouterOpts->bend_cost = Options.bend_cost; | |
| } | |
| RouterOpts->doRouting = FALSE; | |
| if(Options.Count[OT_ROUTE]) | |
| { | |
| RouterOpts->doRouting = TRUE; | |
| } else if (!Options.Count[OT_PACK] && !Options.Count[OT_PLACE] && !Options.Count[OT_ROUTE]) { | |
| if(!Options.Count[OT_TIMING_ANALYZE_ONLY_WITH_NET_DELAY]) | |
| RouterOpts->doRouting = TRUE; | |
| } | |
| } | |
| static void | |
| SetupAnnealSched(INP t_options Options, | |
| OUTP struct s_annealing_sched *AnnealSched) | |
| { | |
| AnnealSched->alpha_t = 0.8; /* DEFAULT */ | |
| if(Options.Count[OT_ALPHA_T]) | |
| { | |
| AnnealSched->alpha_t = Options.PlaceAlphaT; | |
| } | |
| if(AnnealSched->alpha_t >= 1 || AnnealSched->alpha_t <= 0) | |
| { | |
| printf(ERRTAG "alpha_t must be between 0 and 1 exclusive\n"); | |
| exit(1); | |
| } | |
| AnnealSched->exit_t = 0.01; /* DEFAULT */ | |
| if(Options.Count[OT_EXIT_T]) | |
| { | |
| AnnealSched->exit_t = Options.PlaceExitT; | |
| } | |
| if(AnnealSched->exit_t <= 0) | |
| { | |
| printf(ERRTAG "exit_t must be greater than 0\n"); | |
| exit(1); | |
| } | |
| AnnealSched->init_t = 100.0; /* DEFAULT */ | |
| if(Options.Count[OT_INIT_T]) | |
| { | |
| AnnealSched->init_t = Options.PlaceInitT; | |
| } | |
| if(AnnealSched->init_t <= 0) | |
| { | |
| printf(ERRTAG "init_t must be greater than 0\n"); | |
| exit(1); | |
| } | |
| if(AnnealSched->init_t < AnnealSched->exit_t) | |
| { | |
| printf(ERRTAG "init_t must be greater or equal to than exit_t\n"); | |
| exit(1); | |
| } | |
| AnnealSched->inner_num = 10.0; /* DEFAULT */ | |
| if(Options.Count[OT_FAST]) { | |
| AnnealSched->inner_num = 1.0; /* DEFAULT for fast*/ | |
| } | |
| if(Options.Count[OT_INNER_NUM]) | |
| { | |
| AnnealSched->inner_num = Options.PlaceInnerNum; | |
| } | |
| if(AnnealSched->inner_num <= 0) | |
| { | |
| printf(ERRTAG "init_t must be greater than 0\n"); | |
| exit(1); | |
| } | |
| AnnealSched->type = AUTO_SCHED; /* DEFAULT */ | |
| if((Options.Count[OT_ALPHA_T]) || | |
| (Options.Count[OT_EXIT_T]) || (Options.Count[OT_INIT_T])) | |
| { | |
| AnnealSched->type = USER_SCHED; | |
| } | |
| } | |
| /* Sets up the s_packer_opts structure baesd on users inputs and on the architecture specified. | |
| * Error checking, such as checking for conflicting params is assumed to be done beforehand | |
| */ | |
| void SetupPackerOpts(INP t_options Options, | |
| INP boolean TimingEnabled, | |
| INP t_arch Arch, | |
| INP char *net_file, | |
| OUTP struct s_packer_opts *PackerOpts) { | |
| if(Arch.clb_grid.IsAuto) { | |
| PackerOpts->aspect = Arch.clb_grid.Aspect; | |
| } else { | |
| PackerOpts->aspect = (float)Arch.clb_grid.H / (float)Arch.clb_grid.W; | |
| } | |
| PackerOpts->output_file = net_file; | |
| PackerOpts->hack_no_legal_frac_lut = FALSE; /* DEFAULT */ | |
| if(Options.Count[OT_HACK_NO_LEGAL_FRAC_LUT]) | |
| { | |
| PackerOpts->hack_no_legal_frac_lut = TRUE; | |
| } | |
| PackerOpts->hack_safe_latch = FALSE; /* DEFAULT */ | |
| if(Options.Count[OT_HACK_SAFE_LATCH]) | |
| { | |
| PackerOpts->hack_safe_latch = TRUE; | |
| } | |
| PackerOpts->blif_file_name = Options.BlifFile; | |
| PackerOpts->doPacking = FALSE; /* DEFAULT */ | |
| if(Options.Count[OT_PACK]) | |
| { | |
| PackerOpts->doPacking = TRUE; | |
| } else if (!Options.Count[OT_PACK] && !Options.Count[OT_PLACE] && !Options.Count[OT_ROUTE]) { | |
| if(!Options.Count[OT_TIMING_ANALYZE_ONLY_WITH_NET_DELAY]) | |
| PackerOpts->doPacking = TRUE; | |
| } | |
| PackerOpts->global_clocks = TRUE; /* DEFAULT */ | |
| if(Options.Count[OT_GLOBAL_CLOCKS]) | |
| { | |
| PackerOpts->global_clocks = Options.global_clocks; | |
| } | |
| PackerOpts->hill_climbing_flag = FALSE; /* DEFAULT */ | |
| if(Options.Count[OT_HILL_CLIMBING_FLAG]) | |
| { | |
| PackerOpts->hill_climbing_flag = Options.hill_climbing_flag; | |
| } | |
| PackerOpts->sweep_hanging_nets_and_inputs = TRUE; | |
| if(Options.Count[OT_SWEEP_HANGING_NETS_AND_INPUTS]) | |
| { | |
| PackerOpts->sweep_hanging_nets_and_inputs = Options.sweep_hanging_nets_and_inputs; | |
| } | |
| PackerOpts->skip_clustering = FALSE; /* DEFAULT */ | |
| if(Options.Count[OT_SKIP_CLUSTERING]) | |
| { | |
| PackerOpts->skip_clustering = TRUE; | |
| } | |
| PackerOpts->allow_unrelated_clustering = TRUE; /* DEFAULT */ | |
| if(Options.Count[OT_ALLOW_UNRELATED_CLUSTERING]) | |
| { | |
| PackerOpts->allow_unrelated_clustering = Options.allow_unrelated_clustering; | |
| } | |
| PackerOpts->allow_early_exit = FALSE; /* DEFAULT */ | |
| if(Options.Count[OT_ALLOW_EARLY_EXIT]) | |
| { | |
| PackerOpts->allow_early_exit = Options.allow_early_exit; | |
| } | |
| PackerOpts->connection_driven = TRUE; /* DEFAULT */ | |
| if(Options.Count[OT_CONNECTION_DRIVEN_CLUSTERING]) | |
| { | |
| PackerOpts->connection_driven = Options.connection_driven; | |
| } | |
| PackerOpts->timing_driven = TimingEnabled; /* DEFAULT */ | |
| if(Options.Count[OT_TIMING_DRIVEN_CLUSTERING]) | |
| { | |
| PackerOpts->timing_driven = Options.timing_driven; | |
| } | |
| PackerOpts->cluster_seed_type = (TimingEnabled ? VPACK_TIMING : VPACK_MAX_INPUTS); /* DEFAULT */ | |
| if(Options.Count[OT_CLUSTER_SEED]) | |
| { | |
| PackerOpts->cluster_seed_type = Options.cluster_seed_type; | |
| } | |
| PackerOpts->alpha=0.75; /* DEFAULT */ | |
| if(Options.Count[OT_ALPHA_CLUSTERING]) | |
| { | |
| PackerOpts->alpha= Options.alpha; | |
| } | |
| PackerOpts->beta=0.9; /* DEFAULT */ | |
| if(Options.Count[OT_BETA_CLUSTERING]) | |
| { | |
| PackerOpts->beta= Options.beta; | |
| } | |
| /* never recomputer timing */ | |
| PackerOpts->recompute_timing_after = MAX_SHORT; /* DEFAULT */ | |
| if(Options.Count[OT_RECOMPUTE_TIMING_AFTER]) | |
| { | |
| PackerOpts->recompute_timing_after = Options.recompute_timing_after; | |
| } | |
| PackerOpts->block_delay = 0; /* DEFAULT */ | |
| if(Options.Count[OT_CLUSTER_BLOCK_DELAY]) | |
| { | |
| PackerOpts->block_delay = Options.block_delay; | |
| } | |
| PackerOpts->intra_cluster_net_delay = 0; /* DEFAULT */ | |
| if(Options.Count[OT_INTRA_CLUSTER_NET_DELAY]) | |
| { | |
| PackerOpts->intra_cluster_net_delay = Options.intra_cluster_net_delay; | |
| } | |
| PackerOpts->inter_cluster_net_delay = 1.0; /* DEFAULT */ | |
| if(Options.Count[OT_INTER_CLUSTER_NET_DELAY]) | |
| { | |
| PackerOpts->inter_cluster_net_delay = Options.inter_cluster_net_delay; | |
| } | |
| PackerOpts->packer_algorithm = PACK_GREEDY; /* DEFAULT */ | |
| if(Options.Count[OT_PACKER_ALGORITHM]) | |
| { | |
| PackerOpts->packer_algorithm = Options.packer_algorithm; | |
| } | |
| } | |
| /* Sets up the s_placer_opts structure based on users input. Error checking, | |
| * such as checking for conflicting params is assumed to be done beforehand */ | |
| static void | |
| SetupPlacerOpts(INP t_options Options, | |
| INP boolean TimingEnabled, | |
| OUTP struct s_placer_opts *PlacerOpts) | |
| { | |
| PlacerOpts->block_dist = 1; /* DEFAULT */ | |
| if(Options.Count[OT_BLOCK_DIST]) | |
| { | |
| PlacerOpts->block_dist = Options.block_dist; | |
| } | |
| PlacerOpts->inner_loop_recompute_divider = 0; /* DEFAULT */ | |
| if(Options.Count[OT_INNER_LOOP_RECOMPUTE_DIVIDER]) | |
| { | |
| PlacerOpts->inner_loop_recompute_divider = Options.inner_loop_recompute_divider; | |
| } | |
| PlacerOpts->place_cost_exp = 1.0; /* DEFAULT */ | |
| if(Options.Count[OT_PLACE_COST_EXP]) | |
| { | |
| PlacerOpts->place_cost_exp = Options.place_cost_exp; | |
| } | |
| PlacerOpts->td_place_exp_first = 1; /* DEFAULT */ | |
| if(Options.Count[OT_TD_PLACE_EXP_FIRST]) | |
| { | |
| PlacerOpts->td_place_exp_first = Options.place_exp_first; | |
| } | |
| PlacerOpts->td_place_exp_last = 8; /* DEFAULT */ | |
| if(Options.Count[OT_TD_PLACE_EXP_LAST]) | |
| { | |
| PlacerOpts->td_place_exp_last = Options.place_exp_last; | |
| } | |
| PlacerOpts->place_cost_type = LINEAR_CONG; /* DEFAULT */ | |
| if(Options.Count[OT_PLACE_COST_TYPE]) | |
| { | |
| PlacerOpts->place_cost_type = Options.PlaceCostType; | |
| } | |
| /* Depends on PlacerOpts->place_cost_type */ | |
| PlacerOpts->place_algorithm = BOUNDING_BOX_PLACE; /* DEFAULT */ | |
| if(TimingEnabled) | |
| { | |
| PlacerOpts->place_algorithm = PATH_TIMING_DRIVEN_PLACE; /* DEFAULT */ | |
| } | |
| if(NONLINEAR_CONG == PlacerOpts->place_cost_type) | |
| { | |
| PlacerOpts->place_algorithm = BOUNDING_BOX_PLACE; /* DEFAULT */ | |
| } | |
| if(Options.Count[OT_PLACE_ALGORITHM]) | |
| { | |
| PlacerOpts->place_algorithm = Options.PlaceAlgorithm; | |
| } | |
| PlacerOpts->num_regions = 4; /* DEFAULT */ | |
| if(Options.Count[OT_NUM_REGIONS]) | |
| { | |
| PlacerOpts->num_regions = Options.PlaceNonlinearRegions; | |
| } | |
| PlacerOpts->pad_loc_file = NULL; /* DEFAULT */ | |
| if(Options.Count[OT_FIX_PINS]) | |
| { | |
| if(Options.PinFile) | |
| { | |
| PlacerOpts->pad_loc_file = my_strdup(Options.PinFile); | |
| } | |
| } | |
| PlacerOpts->pad_loc_type = FREE; /* DEFAULT */ | |
| if(Options.Count[OT_FIX_PINS]) | |
| { | |
| PlacerOpts->pad_loc_type = (Options.PinFile ? USER : RANDOM); | |
| } | |
| /* Depends on PlacerOpts->place_cost_type */ | |
| PlacerOpts->place_chan_width = 100; /* DEFAULT */ | |
| if((NONLINEAR_CONG == PlacerOpts->place_cost_type) && | |
| (Options.Count[OT_ROUTE_CHAN_WIDTH])) | |
| { | |
| PlacerOpts->place_chan_width = Options.RouteChanWidth; | |
| } | |
| if(Options.Count[OT_PLACE_CHAN_WIDTH]) | |
| { | |
| PlacerOpts->place_chan_width = Options.PlaceChanWidth; | |
| } | |
| PlacerOpts->recompute_crit_iter = 1; /* DEFAULT */ | |
| if(Options.Count[OT_RECOMPUTE_CRIT_ITER]) | |
| { | |
| PlacerOpts->recompute_crit_iter = Options.RecomputeCritIter; | |
| } | |
| PlacerOpts->timing_tradeoff = 0.5; /* DEFAULT */ | |
| if(Options.Count[OT_TIMING_TRADEOFF]) | |
| { | |
| PlacerOpts->timing_tradeoff = Options.PlaceTimingTradeoff; | |
| } | |
| /* Depends on PlacerOpts->place_algorithm */ | |
| PlacerOpts->enable_timing_computations = FALSE; /* DEFAULT */ | |
| if((PlacerOpts->place_algorithm == PATH_TIMING_DRIVEN_PLACE) || | |
| (PlacerOpts->place_algorithm == NET_TIMING_DRIVEN_PLACE)) | |
| { | |
| PlacerOpts->enable_timing_computations = TRUE; /* DEFAULT */ | |
| } | |
| if(Options.Count[OT_ENABLE_TIMING_COMPUTATIONS]) | |
| { | |
| PlacerOpts->enable_timing_computations = Options.ShowPlaceTiming; | |
| } | |
| /* Depends on PlacerOpts->place_cost_type */ | |
| PlacerOpts->place_freq = PLACE_ONCE; /* DEFAULT */ | |
| if(NONLINEAR_CONG == PlacerOpts->place_cost_type) | |
| { | |
| PlacerOpts->place_freq = PLACE_ALWAYS; /* DEFAULT */ | |
| } | |
| if((Options.Count[OT_ROUTE_CHAN_WIDTH]) || | |
| (Options.Count[OT_PLACE_CHAN_WIDTH])) | |
| { | |
| PlacerOpts->place_freq = PLACE_ONCE; | |
| } | |
| PlacerOpts->doPlacement = FALSE; /* DEFAULT */ | |
| if(Options.Count[OT_PLACE]) | |
| { | |
| PlacerOpts->doPlacement = TRUE; | |
| } else if (!Options.Count[OT_PACK] && !Options.Count[OT_PLACE] && !Options.Count[OT_ROUTE]) { | |
| if(!Options.Count[OT_TIMING_ANALYZE_ONLY_WITH_NET_DELAY]) | |
| PlacerOpts->doPlacement = TRUE; | |
| } | |
| if(PlacerOpts->doPlacement == FALSE) { | |
| PlacerOpts->place_freq = PLACE_NEVER; | |
| } | |
| } | |
| static void | |
| SetupOperation(INP t_options Options, | |
| OUTP enum e_operation *Operation) | |
| { | |
| *Operation = RUN_FLOW; /* DEFAULT */ | |
| if(Options.Count[OT_TIMING_ANALYZE_ONLY_WITH_NET_DELAY]) | |
| { | |
| *Operation = TIMING_ANALYSIS_ONLY; | |
| } | |
| } | |
| /* Determines whether timing analysis should be on or off. | |
| Unless otherwise specified, always default to timing. | |
| */ | |
| boolean | |
| IsTimingEnabled(INP t_options Options) | |
| { | |
| /* First priority to the '--timing_analysis' flag */ | |
| if(Options.Count[OT_TIMING_ANALYSIS]) | |
| { | |
| return Options.TimingAnalysis; | |
| } | |
| return TRUE; | |
| } | |