📄 setupvpr.c
字号:
} } } return column_type;}static voidSetupTiming(IN t_options Options, IN t_arch Arch, IN boolean TimingEnabled, IN enum e_operation Operation, IN struct s_placer_opts PlacerOpts, IN struct s_router_opts RouterOpts, OUT 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 voidSetupSwitches(IN t_arch Arch, INOUT struct s_det_routing_arch *RoutingArch, IN struct s_switch_inf *ArchSwitches, IN 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 voidSetupRoutingArch(IN t_arch Arch, OUT 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 voidSetupRouterOpts(IN t_options Options, IN boolean TimingEnabled, OUT 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 = 2; /* 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; }}static voidSetupAnnealSched(IN t_options Options, OUT 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_placer_opts structure based on users input. Error checking, * such as checking for conflicting params is assumed to be done beforehand */static voidSetupPlacerOpts(IN t_options Options, IN boolean TimingEnabled, OUT 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; } if(Options.Count[OT_ROUTE_ONLY]) { PlacerOpts->place_freq = PLACE_NEVER; }}static voidSetupOperation(IN t_options Options, OUT enum e_operation *Operation){ *Operation = PLACE_AND_ROUTE; /* DEFAULT */ if(Options.Count[OT_ROUTE_ONLY]) { *Operation = ROUTE_ONLY; } if(Options.Count[OT_PLACE_ONLY]) { *Operation = PLACE_ONLY; } 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.*/booleanIsTimingEnabled(IN t_options Options){ /* First priority to the '--timing_analysis' flag */ if(Options.Count[OT_TIMING_ANALYSIS]) { return Options.TimingAnalysis; } return TRUE;}/* If a block for a given type does not have subblocks, this creates a subblock for it. This is used to setup I/Os because I/Os have no subblocks in the netlist */static voidload_subblock_info_to_type(INOUT t_subblock_data * subblocks, INOUT t_type_ptr type){ int iblk, i; int *num_subblocks_per_block; t_subblock **subblock_inf; num_subblocks_per_block = subblocks->num_subblocks_per_block; subblock_inf = subblocks->subblock_inf; /* This is also a hack, IO's have subblocks prespecified */ if(type != IO_TYPE) { type_descriptors[type->index].max_subblock_inputs = type->num_receivers; type_descriptors[type->index].max_subblock_outputs = type->num_drivers; type_descriptors[type->index].max_subblocks = 1; } for(iblk = 0; iblk < num_blocks; iblk++) { if(block[iblk].type == type) { subblock_inf[iblk] = (t_subblock *) my_malloc(sizeof(t_subblock)); num_subblocks_per_block[iblk] = 1; subblock_inf[iblk][0].name = block[iblk].name; subblock_inf[iblk][0].inputs = (int *)my_malloc(type->max_subblock_inputs * sizeof(int)); subblock_inf[iblk][0].outputs = (int *)my_malloc(type->max_subblock_outputs * sizeof(int)); for(i = 0; i < type->num_pins; i++) { if(i < type->max_subblock_inputs) { subblock_inf[iblk][0].inputs[i] = (block[iblk].nets[i] == OPEN) ? OPEN : i; } else if(i < type->max_subblock_inputs + type->max_subblock_outputs) { subblock_inf[iblk][0].outputs[i - type-> max_subblock_inputs] = (block[iblk].nets[i] == OPEN) ? OPEN : i; } else { subblock_inf[iblk][0].clock = (block[iblk].nets[i] == OPEN) ? OPEN : i; } } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -