⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 setupvpr.c

📁 VPR布局布线源码
💻 C
📖 第 1 页 / 共 2 页
字号:
			}
		}
	}
    return column_type;
}


static void
SetupTiming(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 void
SetupSwitches(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 void
SetupRoutingArch(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 void
SetupRouterOpts(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 = 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;
	}
}


static void
SetupAnnealSched(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 void
SetupPlacerOpts(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 void
SetupOperation(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.
*/
boolean
IsTimingEnabled(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 void
load_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 + -