VPR-6.0
|
Go to the source code of this file.
Functions | |
boolean | IsTimingEnabled (INP t_options Options) |
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) |
void | CheckSetup (INP enum e_operation Operation, INP struct s_placer_opts PlacerOpts, INP struct s_annealing_sched AnnealSched, INP struct s_router_opts RouterOpts, INP struct s_det_routing_arch RoutingArch, INP t_segment_inf *Segments, INP t_timing_inf Timing, INP t_chan_width_dist Chans) |
void | CheckArch (INP t_arch Arch, INP boolean TimingEnabled) |
void | CheckOptions (INP t_options Options, INP boolean TimingEnabled) |
void | ShowSetup (INP t_options Options, INP t_arch Arch, INP boolean TimingEnabled, INP enum e_operation Operation, INP struct s_file_name_opts FileNameOpts, INP struct s_placer_opts PlacerOpts, INP struct s_annealing_sched AnnealSched, INP struct s_router_opts RouterOpts, INP struct s_det_routing_arch RoutingArch, INP t_segment_inf *Segments, INP t_timing_inf Timing) |
Definition at line 19 of file CheckArch.c.
{ CheckSwitches(Arch, TimingEnabled); CheckSegments(Arch); }
Checks that options don't conflict and that options aren't specified that may conflict.
Definition at line 14 of file CheckOptions.c.
{ boolean TimingPlacer; boolean TimingRouter; boolean default_flow; default_flow = (Options.Count[OT_ROUTE] == 0 && Options.Count[OT_PLACE] == 0 && Options.Count[OT_PACK] == 0 && Options.Count[OT_TIMING_ANALYZE_ONLY_WITH_NET_DELAY] == 0); const struct s_TokenPair *Cur; enum e_OptionBaseToken Yes; /* Check that all filenames were given */ if((NULL == Options.CircuitName) || (NULL == Options.ArchFile)) { printf(ERRTAG "Not enough args. Need at least 'vpr " "<archfile> <circuit_name>'\n"); exit(1); } /* Check that options aren't over specified */ Cur = OptionBaseTokenList; while(Cur->Str) { if(Options.Count[Cur->Enum] > 1) { printf(ERRTAG "Parameter '%s' was specified more than " "once on command line.\n", Cur->Str); exit(1); } ++Cur; } /* Todo: Add in checks for packer */ /* Check for conflicting parameters and determine if placer and * router are on. */ if(Options.Count[OT_TIMING_ANALYZE_ONLY_WITH_NET_DELAY] && (Options.Count[OT_PACK] || Options.Count[OT_PLACE] || Options.Count[OT_ROUTE])) { printf(ERRTAG "'cluster'/'route'/'place', and " "'timing_analysis_only_with_net_delay' are mutually " "exclusive flags\n"); exit(1); } /* If placing and timing is enabled, default to a timing placer */ TimingPlacer = ((Options.Count[OT_PLACE] || default_flow) && TimingEnabled); if(Options.Count[OT_PLACE_ALGORITHM] > 0) { if((PATH_TIMING_DRIVEN_PLACE != Options.PlaceAlgorithm) && (NET_TIMING_DRIVEN_PLACE != Options.PlaceAlgorithm)) { /* Turn off the timing placer if they request a different placer */ TimingPlacer = FALSE; } } /* If routing and timing is enabled, default to a timing router */ TimingRouter = ((Options.Count[OT_ROUTE] || default_flow) && TimingEnabled); if(Options.Count[OT_ROUTER_ALGORITHM] > 0) { if(TIMING_DRIVEN != Options.RouterAlgorithm) { /* Turn off the timing router if they request a different router */ TimingRouter = FALSE; } } Yes = OT_BASE_UNKNOWN; if(Options.Count[OT_SEED] > 0) { Yes = OT_SEED; } if(Options.Count[OT_INNER_NUM] > 0) { Yes = OT_INNER_NUM; } if(Options.Count[OT_INIT_T] > 0) { Yes = OT_INIT_T; } if(Options.Count[OT_ALPHA_T] > 0) { Yes = OT_ALPHA_T; } if(Options.Count[OT_EXIT_T] > 0) { Yes = OT_EXIT_T; } if(Options.Count[OT_FIX_PINS] > 0) { Yes = OT_FIX_PINS; } if(Options.Count[OT_PLACE_ALGORITHM] > 0) { Yes = OT_PLACE_ALGORITHM; } if(Options.Count[OT_PLACE_COST_TYPE] > 0) { Yes = OT_PLACE_COST_TYPE; } if(Options.Count[OT_PLACE_COST_EXP] > 0) { Yes = OT_PLACE_COST_EXP; } if(Options.Count[OT_PLACE_CHAN_WIDTH] > 0) { Yes = OT_PLACE_CHAN_WIDTH; } if(Options.Count[OT_NUM_REGIONS] > 0) { Yes = OT_NUM_REGIONS; } if(Options.Count[OT_ENABLE_TIMING_COMPUTATIONS] > 0) { Yes = OT_ENABLE_TIMING_COMPUTATIONS; } if(Options.Count[OT_BLOCK_DIST] > 0) { Yes = OT_BLOCK_DIST; } /* Make sure if place is off none of those options were given */ if((Options.Count[OT_PLACE] == 0) && !default_flow && (Yes < OT_BASE_UNKNOWN)) { Cur = OptionBaseTokenList; while(Cur->Str) { if(Yes == Cur->Enum) { printf(ERRTAG "Option '%s' is not allowed when placement is " "not run.\n", Cur->Str); exit(1); } ++Cur; } } Yes = OT_BASE_UNKNOWN; if(Options.Count[OT_TIMING_TRADEOFF] > 0) { Yes = OT_TIMING_TRADEOFF; } if(Options.Count[OT_RECOMPUTE_CRIT_ITER] > 0) { Yes = OT_RECOMPUTE_CRIT_ITER; } if(Options.Count[OT_INNER_LOOP_RECOMPUTE_DIVIDER] > 0) { Yes = OT_INNER_LOOP_RECOMPUTE_DIVIDER; } if(Options.Count[OT_TD_PLACE_EXP_FIRST] > 0) { Yes = OT_TD_PLACE_EXP_FIRST; } if(Options.Count[OT_TD_PLACE_EXP_LAST] > 0) { Yes = OT_TD_PLACE_EXP_LAST; } /* Make sure if place is off none of those options were given */ if((FALSE == TimingPlacer) && (Yes < OT_BASE_UNKNOWN)) { Cur = OptionBaseTokenList; while(Cur->Str) { if(Yes == Cur->Enum) { printf(ERRTAG "Option '%s' is not allowed when timing placement is " "not used.\n", Cur->Str); exit(1); } ++Cur; } } Yes = OT_BASE_UNKNOWN; if(Options.Count[OT_ROUTE_TYPE] > 0) { Yes = OT_ROUTE_TYPE; } if(Options.Count[OT_ROUTE_CHAN_WIDTH] > 0) { Yes = OT_ROUTE_CHAN_WIDTH; } if(Options.Count[OT_ROUTER_ALGORITHM] > 0) { Yes = OT_ROUTER_ALGORITHM; } if(Options.Count[OT_MAX_ROUTER_ITERATIONS] > 0) { Yes = OT_MAX_ROUTER_ITERATIONS; } if(Options.Count[OT_INITIAL_PRES_FAC] > 0) { Yes = OT_INITIAL_PRES_FAC; } if(Options.Count[OT_FIRST_ITER_PRES_FAC] > 0) { Yes = OT_FIRST_ITER_PRES_FAC; } if(Options.Count[OT_PRES_FAC_MULT] > 0) { Yes = OT_PRES_FAC_MULT; } if(Options.Count[OT_ACC_FAC] > 0) { Yes = OT_ACC_FAC; } if(Options.Count[OT_BB_FACTOR] > 0) { Yes = OT_BB_FACTOR; } if(Options.Count[OT_BASE_COST_TYPE] > 0) { Yes = OT_BASE_COST_TYPE; } if(Options.Count[OT_BEND_COST] > 0) { Yes = OT_BEND_COST; } if(Options.Count[OT_BASE_COST_TYPE] > 0) { Yes = OT_BASE_COST_TYPE; } if(Options.Count[OT_ASTAR_FAC] > 0) { Yes = OT_ASTAR_FAC; } Yes = OT_BASE_UNKNOWN; if(Options.Count[OT_MAX_CRITICALITY] > 0) { Yes = OT_MAX_CRITICALITY; } if(Options.Count[OT_CRITICALITY_EXP] > 0) { Yes = OT_CRITICALITY_EXP; } /* Make sure if timing router is off none of those options were given */ if((FALSE == TimingRouter) && (Yes < OT_BASE_UNKNOWN)) { Cur = OptionBaseTokenList; while(Cur->Str) { if(Yes == Cur->Enum) { printf(ERRTAG "Option '%s' is not allowed when timing router is " "not used.\n", Cur->Str); exit(1); } ++Cur; } } }
void CheckSetup | ( | INP enum e_operation | Operation, |
INP struct s_placer_opts | PlacerOpts, | ||
INP struct s_annealing_sched | AnnealSched, | ||
INP struct s_router_opts | RouterOpts, | ||
INP struct s_det_routing_arch | RoutingArch, | ||
INP t_segment_inf * | Segments, | ||
INP t_timing_inf | Timing, | ||
INP t_chan_width_dist | Chans | ||
) |
Definition at line 11 of file CheckSetup.c.
{ int i; int Tmp; if((NONLINEAR_CONG == PlacerOpts.place_cost_type) && (!PlacerOpts.doPlacement || !RouterOpts.doRouting) && (PLACE_ALWAYS == PlacerOpts.place_freq)) { printf(ERRTAG "Replacing using the nonlinear congestion option " "for each channel width makes sense only for full " "place and route.\n"); exit(1); } if((NONLINEAR_CONG == PlacerOpts.place_cost_type) && (BOUNDING_BOX_PLACE != PlacerOpts.place_algorithm)) { /* Note that this may work together, but I have not tested it */ printf(ERRTAG "Cannot use non-linear placement only supported with " "bounding box placement\n"); exit(1); } if((GLOBAL == RouterOpts.route_type) && (TIMING_DRIVEN == RouterOpts.router_algorithm)) { printf(ERRTAG "The global router does not support timing-drvien " "routing.\n"); exit(1); } if((GLOBAL == RouterOpts.route_type) && (BOUNDING_BOX_PLACE != PlacerOpts.place_algorithm)) { /* Works, but very weird. Can't optimize timing well, since you're * not doing proper architecture delay modelling. */ printf(WARNTAG "Using global routing with timing-driven placement. " "This is allowed, but strange, and circuit speed will suffer.\n"); } if((FALSE == Timing.timing_analysis_enabled) && ((PlacerOpts.place_algorithm == NET_TIMING_DRIVEN_PLACE) || (PlacerOpts.place_algorithm == PATH_TIMING_DRIVEN_PLACE))) { /* May work, not tested */ printf(ERRTAG "Timing analysis must be enabled for timing-driven placement\n"); exit(1); } if(!PlacerOpts.doPlacement && (USER == PlacerOpts.pad_loc_type)) { printf(ERRTAG "A pad location file requires that placement is enabled.\n"); exit(1); } if(RouterOpts.doRouting) { if((TIMING_DRIVEN == RouterOpts.router_algorithm) && (FALSE == Timing.timing_analysis_enabled)) { printf(ERRTAG "Cannot perform timing-driven routing when timing " "analysis is disabled.\n"); exit(1); } if((FALSE == Timing.timing_analysis_enabled) && (DEMAND_ONLY != RouterOpts.base_cost_type)) { printf(ERRTAG "base_cost_type must be demand_only when timing " "analysis is disabled.\n"); exit(1); } } if((TIMING_ANALYSIS_ONLY == Operation) && (FALSE == Timing.timing_analysis_enabled)) { printf(ERRTAG "-timing_analyze_only_with_net_delay option requires " "that timing analysis not be disabled.\n"); exit(1); } if((NONLINEAR_CONG == PlacerOpts.place_cost_type) && ((PlacerOpts.num_regions > nx) || (PlacerOpts.num_regions > ny))) { printf(ERRTAG "Cannot use more regions than clbs in " "placement cost function.\n"); exit(1); } if(DETAILED == RouterOpts.route_type) { if((Chans.chan_x_dist.type != UNIFORM) || (Chans.chan_y_dist.type != UNIFORM) || (Chans.chan_x_dist.peak != Chans.chan_y_dist.peak) || (Chans.chan_x_dist.peak != Chans.chan_width_io)) { printf(ERRTAG "Detailed routing currently only supported " "on FPGAs with all channels of equal width.\n"); exit(1); } } for(i = 0; i < RoutingArch.num_segment; ++i) { Tmp = Segments[i].opin_switch; if(FALSE == switch_inf[Tmp].buffered) { printf(ERRTAG "opin_switch (#%d) of segment type #%d " "is not buffered.\n", Tmp, i); exit(1); } } if(UNI_DIRECTIONAL == RoutingArch.directionality) { if((RouterOpts.fixed_channel_width != NO_FIXED_CHANNEL_WIDTH) && (RouterOpts.fixed_channel_width % 2 > 0)) { printf(ERRTAG "Routing channel width must be even for unidirectional\n"); exit(1); } if((PlacerOpts.place_chan_width != NO_FIXED_CHANNEL_WIDTH) && (PlacerOpts.place_chan_width % 2 > 0)) { printf(ERRTAG "Place channel width must be even for unidirectional\n"); exit(1); } } }
Determines whether timing analysis should be on or off. Unless otherwise specified, always default to timing.
Definition at line 814 of file SetupVPR.c.
{ /* First priority to the '--timing_analysis' flag */ if(Options.Count[OT_TIMING_ANALYSIS]) { return Options.TimingAnalysis; } return TRUE; }
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 | ||
) |
Sets VPR parameters and defaults. Does not do any error checking as this should have been done by the various input checkers
Definition at line 45 of file SetupVPR.c.
{ 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 }
void ShowSetup | ( | INP t_options | Options, |
INP t_arch | Arch, | ||
INP boolean | TimingEnabled, | ||
INP enum e_operation | Operation, | ||
INP struct s_file_name_opts | FileNameOpts, | ||
INP struct s_placer_opts | PlacerOpts, | ||
INP struct s_annealing_sched | AnnealSched, | ||
INP struct s_router_opts | RouterOpts, | ||
INP struct s_det_routing_arch | RoutingArch, | ||
INP t_segment_inf * | Segments, | ||
INP t_timing_inf | Timing | ||
) |
Definition at line 24 of file ShowSetup.c.
{ int i, j, num_p_inputs, num_p_outputs; int *num_blocks_type; num_blocks_type = my_calloc(num_types, sizeof(int)); printf("Timing analysis: %s\n", (TimingEnabled ? "ON" : "OFF")); printf("\n"); printf("Circuit netlist file: %s\n", FileNameOpts.NetFile); printf("Circuit placement file: %s\n", FileNameOpts.PlaceFile); printf("Circuit routing file: %s\n", FileNameOpts.RouteFile); ShowOperation(Operation); printf("Placer: %s\n", (PlacerOpts.doPlacement ? "ENABLED" : "DISABLED")); printf("Router: %s\n", (RouterOpts.doRouting ? "ENABLED" : "DISABLED")); if(PlacerOpts.doPlacement) { ShowPlacerOpts(Options, PlacerOpts, AnnealSched); } if(RouterOpts.doRouting) { ShowRouterOpts(RouterOpts); } if(DETAILED == RouterOpts.route_type) ShowRoutingArch(RoutingArch); printf("\n"); printf("Netlist num_nets: %d\n", num_nets); printf("Netlist num_blocks: %d\n", num_blocks); for(i = 0; i < num_types; i++) { num_blocks_type[i] = 0; } /* Count I/O input and output pads */ num_p_inputs = 0; num_p_outputs = 0; for(i = 0; i < num_blocks; i++) { num_blocks_type[block[i].type->index]++; if(block[i].type == IO_TYPE) { for(j = 0; j < IO_TYPE->num_pins; j++) { if(block[i].nets[j] != OPEN) { if(IO_TYPE-> class_inf[IO_TYPE->pin_class[j]]. type == DRIVER) { num_p_inputs++; } else { assert(IO_TYPE-> class_inf[IO_TYPE-> pin_class[j]]. type == RECEIVER); num_p_outputs++; } } } } } for(i = 0; i < num_types; i++) { if(IO_TYPE != &type_descriptors[i]) { printf("Netlist %s blocks: %d\n", type_descriptors[i].name, num_blocks_type[i]); } } /* Print out each block separately instead */ printf("Netlist inputs pins: %d\n", num_p_inputs); printf("Netlist output pins: %d\n", num_p_outputs); printf("\n"); free(num_blocks_type); }