blob: 82024d8cd92b3fa2eba61dcc897cdfb164fd788c [file] [log] [blame]
#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;
}