#include <assert.h>
#include <string.h>
#include "util.h"
#include "vpr_types.h"
#include "check_netlist.h"
#include "OptionTokens.h"
#include "ReadOptions.h"
#include "read_netlist.h"
#include "globals.h"
#include "xml_arch.h"
#include "SetupVPR.h"
Go to the source code of this file.
Functions | |
static void | SetupOperation (IN t_options Options, OUT enum e_operation *Operation) |
static void | SetupPlacerOpts (IN t_options Options, IN boolean TimingEnabled, OUT struct s_placer_opts *PlacerOpts) |
static void | SetupAnnealSched (IN t_options Options, OUT struct s_annealing_sched *AnnealSched) |
static void | SetupRouterOpts (IN t_options Options, IN boolean TimingEnabled, OUT struct s_router_opts *RouterOpts) |
static void | SetupGlobalRoutingArch (OUT struct s_det_routing_arch *RoutingArch, OUT t_segment_inf **Segments) |
static void | SetupRoutingArch (IN t_arch Arch, OUT struct s_det_routing_arch *RoutingArch) |
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) |
static void | load_subblock_info_to_type (INOUT t_subblock_data *subblocks, INOUT t_type_ptr type) |
static void | InitArch (IN t_arch Arch) |
static void | alloc_and_load_grid (INOUT int *num_instances_type) |
static void | freeGrid () |
static void | CheckGrid (void) |
static t_type_ptr | find_type_col (IN int x) |
static void | SetupSwitches (IN t_arch Arch, INOUT struct s_det_routing_arch *RoutingArch, IN struct s_switch_inf *ArchSwitches, IN int NumArchSwitches) |
void | SetupVPR (IN t_options Options, IN boolean TimingEnabled, OUT t_arch *Arch, OUT enum e_operation *Operation, OUT struct s_placer_opts *PlacerOpts, OUT struct s_annealing_sched *AnnealSched, OUT struct s_router_opts *RouterOpts, OUT struct s_det_routing_arch *RoutingArch, OUT t_segment_inf **Segments, OUT t_timing_inf *Timing, OUT t_subblock_data *Subblocks, OUT boolean *ShowGraphics, OUT int *GraphPause) |
boolean | IsTimingEnabled (IN t_options Options) |
static void alloc_and_load_grid | ( | INOUT int * | num_instances_type | ) | [static] |
Definition at line 268 of file SetupVPR.c.
00269 { 00270 00271 int i, j; 00272 t_type_ptr type; 00273 00274 #ifdef SHOW_ARCH 00275 FILE *dump; 00276 #endif 00277 00278 /* If both nx and ny are 1, we only have one valid location for a clb. * 00279 * That's a major problem, as won't be able to move the clb and the * 00280 * find_to routine that tries moves in the placer will go into an * 00281 * infinite loop trying to move it. Exit with an error message * 00282 * instead. */ 00283 00284 if((nx == 1) && (ny == 1) && (num_blocks > 0)) 00285 { 00286 printf("Error:\n"); 00287 printf 00288 ("Sorry, can't place a circuit with only one valid location\n"); 00289 printf("for a logic block (clb).\n"); 00290 printf("Try me with a more realistic circuit!\n"); 00291 exit(1); 00292 } 00293 00294 /* To remove this limitation, change ylow etc. in t_rr_node to * 00295 * * be ints instead. Used shorts to save memory. */ 00296 if((nx > 32766) || (ny > 32766)) 00297 { 00298 printf("Error: nx and ny must be less than 32767, since the \n"); 00299 printf("router uses shorts (16-bit) to store coordinates.\n"); 00300 printf("nx: %d. ny: %d.\n", nx, ny); 00301 exit(1); 00302 } 00303 00304 assert(nx >= 1 && ny >= 1); 00305 00306 grid = (struct s_grid_tile **)alloc_matrix(0, (nx + 1), 00307 0, (ny + 1), 00308 sizeof(struct s_grid_tile)); 00309 00310 /* Clear the full grid to have no type (NULL), no capacity, etc */ 00311 for(i = 0; i <= (nx + 1); ++i) 00312 { 00313 for(j = 0; j <= (ny + 1); ++j) 00314 { 00315 memset(&grid[i][j], 0, (sizeof(struct s_grid_tile))); 00316 } 00317 } 00318 00319 for(i = 0; i < num_types; i++) 00320 { 00321 num_instances_type[i] = 0; 00322 } 00323 00324 /* Nothing goes in the corners. */ 00325 grid[0][0].type = grid[nx + 1][0].type = EMPTY_TYPE; 00326 grid[0][ny + 1].type = grid[nx + 1][ny + 1].type = EMPTY_TYPE; 00327 num_instances_type[EMPTY_TYPE->index] = 4; 00328 00329 for(i = 1; i <= nx; i++) 00330 { 00331 grid[i][0].blocks = 00332 (int *)my_malloc(sizeof(int) * IO_TYPE->capacity); 00333 grid[i][0].type = IO_TYPE; 00334 00335 grid[i][ny + 1].blocks = 00336 (int *)my_malloc(sizeof(int) * IO_TYPE->capacity); 00337 grid[i][ny + 1].type = IO_TYPE; 00338 00339 for(j = 0; j < IO_TYPE->capacity; j++) 00340 { 00341 grid[i][0].blocks[j] = EMPTY; 00342 grid[i][ny + 1].blocks[j] = EMPTY; 00343 } 00344 } 00345 00346 for(i = 1; i <= ny; i++) 00347 { 00348 grid[0][i].blocks = 00349 (int *)my_malloc(sizeof(int) * IO_TYPE->capacity); 00350 grid[0][i].type = IO_TYPE; 00351 00352 grid[nx + 1][i].blocks = 00353 (int *)my_malloc(sizeof(int) * IO_TYPE->capacity); 00354 grid[nx + 1][i].type = IO_TYPE; 00355 for(j = 0; j < IO_TYPE->capacity; j++) 00356 { 00357 grid[0][i].blocks[j] = EMPTY; 00358 grid[nx + 1][i].blocks[j] = EMPTY; 00359 } 00360 } 00361 00362 num_instances_type[IO_TYPE->index] = 2 * IO_TYPE->capacity * (nx + ny); 00363 00364 for(i = 1; i <= nx; i++) 00365 { /* Interior (LUT) cells */ 00366 type = find_type_col(i); 00367 for(j = 1; j <= ny; j++) 00368 { 00369 grid[i][j].type = type; 00370 grid[i][j].offset = (j - 1) % type->height; 00371 if(j + grid[i][j].type->height - 1 - grid[i][j].offset > 00372 ny) 00373 { 00374 grid[i][j].type = EMPTY_TYPE; 00375 grid[i][j].offset = 0; 00376 } 00377 00378 if(type->capacity > 1) 00379 { 00380 printf(ERRTAG 00381 "In FillArch() expected core blocks to have capacity <= 1 but " 00382 "(%d, %d) has type '%s' and capacity %d\n", 00383 i, j, grid[i][j].type->name, 00384 grid[i][j].type->capacity); 00385 exit(1); 00386 } 00387 00388 grid[i][j].blocks = (int *)my_malloc(sizeof(int)); 00389 grid[i][j].blocks[0] = EMPTY; 00390 if(grid[i][j].offset == 0) 00391 { 00392 num_instances_type[grid[i][j].type->index]++; 00393 } 00394 } 00395 } 00396 00397 CheckGrid(); 00398 00399 #ifdef SHOW_ARCH 00400 /* DEBUG code */ 00401 dump = my_fopen("grid_type_dump.txt", "w"); 00402 for(j = (ny + 1); j >= 0; --j) 00403 { 00404 for(i = 0; i <= (nx + 1); ++i) 00405 { 00406 fprintf(dump, "%c", grid[i][j].type->name[1]); 00407 } 00408 fprintf(dump, "\n"); 00409 } 00410 fclose(dump); 00411 #endif 00412 }
static void CheckGrid | ( | void | ) | [static] |
Definition at line 431 of file SetupVPR.c.
00432 { 00433 int i, j; 00434 00435 /* Check grid is valid */ 00436 for(i = 0; i <= (nx + 1); ++i) 00437 { 00438 for(j = 0; j <= (ny + 1); ++j) 00439 { 00440 if(NULL == grid[i][j].type) 00441 { 00442 printf(ERRTAG "grid[%d][%d] has no type.\n", i, 00443 j); 00444 exit(1); 00445 } 00446 00447 if(grid[i][j].usage != 0) 00448 { 00449 printf(ERRTAG 00450 "grid[%d][%d] has non-zero usage (%d) " 00451 "before netlist load.\n", i, j, 00452 grid[i][j].usage); 00453 exit(1); 00454 } 00455 00456 if((grid[i][j].offset < 0) || 00457 (grid[i][j].offset >= grid[i][j].type->height)) 00458 { 00459 printf(ERRTAG 00460 "grid[%d][%d] has invalid offset (%d)\n", 00461 i, j, grid[i][j].offset); 00462 exit(1); 00463 } 00464 00465 if((NULL == grid[i][j].blocks) && 00466 (grid[i][j].type->capacity > 0)) 00467 { 00468 printf(ERRTAG 00469 "grid[%d][%d] has no block list allocated.\n", 00470 i, j); 00471 exit(1); 00472 } 00473 } 00474 } 00475 }
static t_type_ptr find_type_col | ( | IN int | x | ) | [static] |
Definition at line 478 of file SetupVPR.c.
00479 { 00480 int i, j; 00481 int start, repeat; 00482 float rel; 00483 boolean match; 00484 int priority, num_loc; 00485 t_type_ptr column_type; 00486 00487 priority = FILL_TYPE->grid_loc_def[0].priority; 00488 column_type = FILL_TYPE; 00489 00490 for(i = 0; i < num_types; i++) 00491 { 00492 if(&type_descriptors[i] == IO_TYPE || 00493 &type_descriptors[i] == EMPTY_TYPE || 00494 &type_descriptors[i] == FILL_TYPE) 00495 continue; 00496 num_loc = type_descriptors[i].num_grid_loc_def; 00497 for(j = 0; j < num_loc; j++) 00498 { 00499 if(priority < 00500 type_descriptors[i].grid_loc_def[j].priority) 00501 { 00502 match = FALSE; 00503 if(type_descriptors[i].grid_loc_def[j]. 00504 grid_loc_type == COL_REPEAT) 00505 { 00506 start = 00507 type_descriptors[i].grid_loc_def[j]. 00508 start_col; 00509 repeat = 00510 type_descriptors[i].grid_loc_def[j]. 00511 repeat; 00512 if(start < 0) 00513 { 00514 start += (nx + 1); 00515 } 00516 if(x == start) 00517 { 00518 match = TRUE; 00519 } 00520 else if(repeat > 0 && x > start 00521 && start > 0) 00522 { 00523 if((x - start) % repeat == 0) 00524 { 00525 match = TRUE; 00526 } 00527 } 00528 } 00529 else if(type_descriptors[i].grid_loc_def[j]. 00530 grid_loc_type == COL_REL) 00531 { 00532 rel = 00533 type_descriptors[i].grid_loc_def[j]. 00534 col_rel; 00535 if(nint(rel * nx) == x) 00536 { 00537 match = TRUE; 00538 } 00539 } 00540 if(match) 00541 { 00542 priority = 00543 type_descriptors[i].grid_loc_def[j]. 00544 priority; 00545 column_type = &type_descriptors[i]; 00546 } 00547 } 00548 } 00549 } 00550 return column_type; 00551 }
static void freeGrid | ( | ) | [static] |
Definition at line 415 of file SetupVPR.c.
00416 { 00417 int i, j; 00418 00419 for(i = 0; i <= (nx + 1); ++i) 00420 { 00421 for(j = 0; j <= (ny + 1); ++j) 00422 { 00423 free(grid[i][j].blocks); 00424 } 00425 } 00426 free_matrix(grid, 0, nx + 1, 0, sizeof(struct s_grid_tile)); 00427 }
static void InitArch | ( | IN t_arch | Arch | ) | [static] |
Definition at line 130 of file SetupVPR.c.
00131 { 00132 int *num_instances_type, *num_blocks_type; 00133 int i; 00134 int current, high, low; 00135 boolean fit; 00136 00137 current = nint(sqrt(num_blocks)); /* current is the value of the smaller side of the FPGA */ 00138 low = 1; 00139 high = -1; 00140 00141 num_instances_type = my_calloc(num_types, sizeof(int)); 00142 num_blocks_type = my_calloc(num_types, sizeof(int)); 00143 00144 for(i = 0; i < num_blocks; i++) 00145 { 00146 num_blocks_type[block[i].type->index]++; 00147 } 00148 00149 if(Arch.clb_grid.IsAuto) 00150 { 00151 /* Auto-size FPGA, perform a binary search */ 00152 while(high == -1 || low < high) 00153 { 00154 /* Generate grid */ 00155 if(Arch.clb_grid.Aspect >= 1.0) 00156 { 00157 ny = current; 00158 nx = nint(current * Arch.clb_grid.Aspect); 00159 } 00160 else 00161 { 00162 nx = current; 00163 ny = nint(current / Arch.clb_grid.Aspect); 00164 } 00165 #if DEBUG 00166 printf("Auto-sizing FPGA, try x = %d y = %d\n", nx, ny); 00167 #endif 00168 alloc_and_load_grid(num_instances_type); 00169 freeGrid(); 00170 00171 /* Test if netlist fits in grid */ 00172 fit = TRUE; 00173 for(i = 0; i < num_types; i++) 00174 { 00175 if(num_blocks_type[i] > num_instances_type[i]) 00176 { 00177 fit = FALSE; 00178 break; 00179 } 00180 } 00181 00182 /* get next value */ 00183 if(!fit) 00184 { 00185 /* increase size of max */ 00186 if(high == -1) 00187 { 00188 current = current * 2; 00189 if(current > MAX_SHORT) 00190 { 00191 printf(ERRTAG 00192 "FPGA required is too large for current architecture settings\n"); 00193 exit(1); 00194 } 00195 } 00196 else 00197 { 00198 if(low == current) 00199 current++; 00200 low = current; 00201 current = low + ((high - low) / 2); 00202 } 00203 } 00204 else 00205 { 00206 high = current; 00207 current = low + ((high - low) / 2); 00208 } 00209 } 00210 /* Generate grid */ 00211 if(Arch.clb_grid.Aspect >= 1.0) 00212 { 00213 ny = current; 00214 nx = nint(current * Arch.clb_grid.Aspect); 00215 } 00216 else 00217 { 00218 nx = current; 00219 ny = nint(current / Arch.clb_grid.Aspect); 00220 } 00221 alloc_and_load_grid(num_instances_type); 00222 printf("FPGA auto-sized to, x = %d y = %d\n", nx, ny); 00223 } 00224 else 00225 { 00226 nx = Arch.clb_grid.W; 00227 ny = Arch.clb_grid.H; 00228 alloc_and_load_grid(num_instances_type); 00229 } 00230 00231 /* Test if netlist fits in grid */ 00232 fit = TRUE; 00233 for(i = 0; i < num_types; i++) 00234 { 00235 if(num_blocks_type[i] > num_instances_type[i]) 00236 { 00237 fit = FALSE; 00238 break; 00239 } 00240 } 00241 if(!fit) 00242 { 00243 printf(ERRTAG "Not enough physical locations for type %s, " 00244 "number of blocks is %d but number of locations is %d\n", 00245 num_blocks_type[i], num_instances_type[i]); 00246 exit(1); 00247 } 00248 00249 printf("\nResource Usage:\n"); 00250 for(i = 0; i < num_types; i++) 00251 { 00252 printf("Netlist %d\tblocks of type %s\n", 00253 num_blocks_type[i], type_descriptors[i].name); 00254 printf("Architecture %d\tblocks of type %s\n", 00255 num_instances_type[i], type_descriptors[i].name); 00256 } 00257 printf("\n"); 00258 chan_width_x = (int *)my_malloc((ny + 1) * sizeof(int)); 00259 chan_width_y = (int *)my_malloc((nx + 1) * sizeof(int)); 00260 00261 free(num_blocks_type); 00262 free(num_instances_type); 00263 }
Definition at line 1016 of file SetupVPR.c.
01017 { 01018 /* First priority to the '--timing_analysis' flag */ 01019 if(Options.Count[OT_TIMING_ANALYSIS]) 01020 { 01021 return Options.TimingAnalysis; 01022 } 01023 return TRUE; 01024 }
static void load_subblock_info_to_type | ( | INOUT t_subblock_data * | subblocks, | |
INOUT t_type_ptr | type | |||
) | [static] |
Definition at line 1029 of file SetupVPR.c.
01031 { 01032 int iblk, i; 01033 int *num_subblocks_per_block; 01034 t_subblock **subblock_inf; 01035 01036 num_subblocks_per_block = subblocks->num_subblocks_per_block; 01037 subblock_inf = subblocks->subblock_inf; 01038 01039 /* This is also a hack, IO's have subblocks prespecified */ 01040 if(type != IO_TYPE) 01041 { 01042 type_descriptors[type->index].max_subblock_inputs = 01043 type->num_receivers; 01044 type_descriptors[type->index].max_subblock_outputs = 01045 type->num_drivers; 01046 type_descriptors[type->index].max_subblocks = 1; 01047 } 01048 01049 for(iblk = 0; iblk < num_blocks; iblk++) 01050 { 01051 if(block[iblk].type == type) 01052 { 01053 subblock_inf[iblk] = 01054 (t_subblock *) my_malloc(sizeof(t_subblock)); 01055 num_subblocks_per_block[iblk] = 1; 01056 subblock_inf[iblk][0].name = block[iblk].name; 01057 subblock_inf[iblk][0].inputs = 01058 (int *)my_malloc(type->max_subblock_inputs * 01059 sizeof(int)); 01060 subblock_inf[iblk][0].outputs = 01061 (int *)my_malloc(type->max_subblock_outputs * 01062 sizeof(int)); 01063 for(i = 0; i < type->num_pins; i++) 01064 { 01065 if(i < type->max_subblock_inputs) 01066 { 01067 subblock_inf[iblk][0].inputs[i] = 01068 (block[iblk].nets[i] == 01069 OPEN) ? OPEN : i; 01070 } 01071 else if(i < 01072 type->max_subblock_inputs + 01073 type->max_subblock_outputs) 01074 { 01075 subblock_inf[iblk][0].outputs[i - 01076 type-> 01077 max_subblock_inputs] 01078 = 01079 (block[iblk].nets[i] == 01080 OPEN) ? OPEN : i; 01081 } 01082 else 01083 { 01084 subblock_inf[iblk][0].clock = 01085 (block[iblk].nets[i] == 01086 OPEN) ? OPEN : i; 01087 } 01088 } 01089 } 01090 } 01091 }
static void SetupAnnealSched | ( | IN t_options | Options, | |
OUT struct s_annealing_sched * | AnnealSched | |||
) | [static] |
Definition at line 799 of file SetupVPR.c.
00801 { 00802 AnnealSched->alpha_t = 0.8; /* DEFAULT */ 00803 if(Options.Count[OT_ALPHA_T]) 00804 { 00805 AnnealSched->alpha_t = Options.PlaceAlphaT; 00806 } 00807 if(AnnealSched->alpha_t >= 1 || AnnealSched->alpha_t <= 0) 00808 { 00809 printf(ERRTAG "alpha_t must be between 0 and 1 exclusive\n"); 00810 exit(1); 00811 } 00812 AnnealSched->exit_t = 0.01; /* DEFAULT */ 00813 if(Options.Count[OT_EXIT_T]) 00814 { 00815 AnnealSched->exit_t = Options.PlaceExitT; 00816 } 00817 if(AnnealSched->exit_t <= 0) 00818 { 00819 printf(ERRTAG "exit_t must be greater than 0\n"); 00820 exit(1); 00821 } 00822 AnnealSched->init_t = 100.0; /* DEFAULT */ 00823 if(Options.Count[OT_INIT_T]) 00824 { 00825 AnnealSched->init_t = Options.PlaceInitT; 00826 } 00827 if(AnnealSched->init_t <= 0) 00828 { 00829 printf(ERRTAG "init_t must be greater than 0\n"); 00830 exit(1); 00831 } 00832 if(AnnealSched->init_t < AnnealSched->exit_t) 00833 { 00834 printf(ERRTAG "init_t must be greater or equal to than exit_t\n"); 00835 exit(1); 00836 } 00837 AnnealSched->inner_num = 10.0; /* DEFAULT */ 00838 if(Options.Count[OT_FAST]) { 00839 AnnealSched->inner_num = 1.0; /* DEFAULT for fast*/ 00840 } 00841 if(Options.Count[OT_INNER_NUM]) 00842 { 00843 AnnealSched->inner_num = Options.PlaceInnerNum; 00844 } 00845 if(AnnealSched->inner_num <= 0) 00846 { 00847 printf(ERRTAG "init_t must be greater than 0\n"); 00848 exit(1); 00849 } 00850 AnnealSched->type = AUTO_SCHED; /* DEFAULT */ 00851 if((Options.Count[OT_ALPHA_T]) || 00852 (Options.Count[OT_EXIT_T]) || (Options.Count[OT_INIT_T])) 00853 { 00854 AnnealSched->type = USER_SCHED; 00855 } 00856 }
static void SetupGlobalRoutingArch | ( | OUT struct s_det_routing_arch * | RoutingArch, | |
OUT t_segment_inf ** | Segments | |||
) | [static] |
static void SetupOperation | ( | IN t_options | Options, | |
OUT enum e_operation * | Operation | |||
) | [static] |
Definition at line 993 of file SetupVPR.c.
00995 { 00996 *Operation = PLACE_AND_ROUTE; /* DEFAULT */ 00997 if(Options.Count[OT_ROUTE_ONLY]) 00998 { 00999 *Operation = ROUTE_ONLY; 01000 } 01001 if(Options.Count[OT_PLACE_ONLY]) 01002 { 01003 *Operation = PLACE_ONLY; 01004 } 01005 if(Options.Count[OT_TIMING_ANALYZE_ONLY_WITH_NET_DELAY]) 01006 { 01007 *Operation = TIMING_ANALYSIS_ONLY; 01008 } 01009 }
static void SetupPlacerOpts | ( | IN t_options | Options, | |
IN boolean | TimingEnabled, | |||
OUT struct s_placer_opts * | PlacerOpts | |||
) | [static] |
Definition at line 862 of file SetupVPR.c.
00865 { 00866 PlacerOpts->block_dist = 1; /* DEFAULT */ 00867 if(Options.Count[OT_BLOCK_DIST]) 00868 { 00869 PlacerOpts->block_dist = Options.block_dist; 00870 } 00871 00872 PlacerOpts->inner_loop_recompute_divider = 0; /* DEFAULT */ 00873 if(Options.Count[OT_INNER_LOOP_RECOMPUTE_DIVIDER]) 00874 { 00875 PlacerOpts->inner_loop_recompute_divider = Options.inner_loop_recompute_divider; 00876 } 00877 00878 PlacerOpts->place_cost_exp = 1.0; /* DEFAULT */ 00879 if(Options.Count[OT_PLACE_COST_EXP]) 00880 { 00881 PlacerOpts->place_cost_exp = Options.place_cost_exp; 00882 } 00883 00884 PlacerOpts->td_place_exp_first = 1; /* DEFAULT */ 00885 if(Options.Count[OT_TD_PLACE_EXP_FIRST]) 00886 { 00887 PlacerOpts->td_place_exp_first = Options.place_exp_first; 00888 } 00889 00890 PlacerOpts->td_place_exp_last = 8; /* DEFAULT */ 00891 if(Options.Count[OT_TD_PLACE_EXP_LAST]) 00892 { 00893 PlacerOpts->td_place_exp_last = Options.place_exp_last; 00894 } 00895 00896 PlacerOpts->place_cost_type = LINEAR_CONG; /* DEFAULT */ 00897 if(Options.Count[OT_PLACE_COST_TYPE]) 00898 { 00899 PlacerOpts->place_cost_type = Options.PlaceCostType; 00900 } 00901 00902 /* Depends on PlacerOpts->place_cost_type */ 00903 PlacerOpts->place_algorithm = BOUNDING_BOX_PLACE; /* DEFAULT */ 00904 if(TimingEnabled) 00905 { 00906 PlacerOpts->place_algorithm = PATH_TIMING_DRIVEN_PLACE; /* DEFAULT */ 00907 } 00908 if(NONLINEAR_CONG == PlacerOpts->place_cost_type) 00909 { 00910 PlacerOpts->place_algorithm = BOUNDING_BOX_PLACE; /* DEFAULT */ 00911 } 00912 if(Options.Count[OT_PLACE_ALGORITHM]) 00913 { 00914 PlacerOpts->place_algorithm = Options.PlaceAlgorithm; 00915 } 00916 00917 PlacerOpts->num_regions = 4; /* DEFAULT */ 00918 if(Options.Count[OT_NUM_REGIONS]) 00919 { 00920 PlacerOpts->num_regions = Options.PlaceNonlinearRegions; 00921 } 00922 00923 PlacerOpts->pad_loc_file = NULL; /* DEFAULT */ 00924 if(Options.Count[OT_FIX_PINS]) 00925 { 00926 if(Options.PinFile) 00927 { 00928 PlacerOpts->pad_loc_file = my_strdup(Options.PinFile); 00929 } 00930 } 00931 00932 PlacerOpts->pad_loc_type = FREE; /* DEFAULT */ 00933 if(Options.Count[OT_FIX_PINS]) 00934 { 00935 PlacerOpts->pad_loc_type = (Options.PinFile ? USER : RANDOM); 00936 } 00937 00938 /* Depends on PlacerOpts->place_cost_type */ 00939 PlacerOpts->place_chan_width = 100; /* DEFAULT */ 00940 if((NONLINEAR_CONG == PlacerOpts->place_cost_type) && 00941 (Options.Count[OT_ROUTE_CHAN_WIDTH])) 00942 { 00943 PlacerOpts->place_chan_width = Options.RouteChanWidth; 00944 } 00945 if(Options.Count[OT_PLACE_CHAN_WIDTH]) 00946 { 00947 PlacerOpts->place_chan_width = Options.PlaceChanWidth; 00948 } 00949 00950 PlacerOpts->recompute_crit_iter = 1; /* DEFAULT */ 00951 if(Options.Count[OT_RECOMPUTE_CRIT_ITER]) 00952 { 00953 PlacerOpts->recompute_crit_iter = Options.RecomputeCritIter; 00954 } 00955 00956 PlacerOpts->timing_tradeoff = 0.5; /* DEFAULT */ 00957 if(Options.Count[OT_TIMING_TRADEOFF]) 00958 { 00959 PlacerOpts->timing_tradeoff = Options.PlaceTimingTradeoff; 00960 } 00961 00962 /* Depends on PlacerOpts->place_algorithm */ 00963 PlacerOpts->enable_timing_computations = FALSE; /* DEFAULT */ 00964 if((PlacerOpts->place_algorithm == PATH_TIMING_DRIVEN_PLACE) || 00965 (PlacerOpts->place_algorithm == NET_TIMING_DRIVEN_PLACE)) 00966 { 00967 PlacerOpts->enable_timing_computations = TRUE; /* DEFAULT */ 00968 } 00969 if(Options.Count[OT_ENABLE_TIMING_COMPUTATIONS]) 00970 { 00971 PlacerOpts->enable_timing_computations = Options.ShowPlaceTiming; 00972 } 00973 00974 /* Depends on PlacerOpts->place_cost_type */ 00975 PlacerOpts->place_freq = PLACE_ONCE; /* DEFAULT */ 00976 if(NONLINEAR_CONG == PlacerOpts->place_cost_type) 00977 { 00978 PlacerOpts->place_freq = PLACE_ALWAYS; /* DEFAULT */ 00979 } 00980 if((Options.Count[OT_ROUTE_CHAN_WIDTH]) || 00981 (Options.Count[OT_PLACE_CHAN_WIDTH])) 00982 { 00983 PlacerOpts->place_freq = PLACE_ONCE; 00984 } 00985 if(Options.Count[OT_ROUTE_ONLY]) 00986 { 00987 PlacerOpts->place_freq = PLACE_NEVER; 00988 } 00989 }
static void SetupRouterOpts | ( | IN t_options | Options, | |
IN boolean | TimingEnabled, | |||
OUT struct s_router_opts * | RouterOpts | |||
) | [static] |
Definition at line 643 of file SetupVPR.c.
00646 { 00647 RouterOpts->astar_fac = 1.2; /* DEFAULT */ 00648 if(Options.Count[OT_ASTAR_FAC]) 00649 { 00650 RouterOpts->astar_fac = Options.astar_fac; 00651 } 00652 00653 RouterOpts->bb_factor = 3; /* DEFAULT */ 00654 if(Options.Count[OT_FAST]) 00655 { 00656 RouterOpts->bb_factor = 0; /* DEFAULT */ 00657 } 00658 if(Options.Count[OT_BB_FACTOR]) 00659 { 00660 RouterOpts->bb_factor = Options.bb_factor; 00661 } 00662 00663 RouterOpts->criticality_exp = 1.0; /* DEFAULT */ 00664 if(Options.Count[OT_CRITICALITY_EXP]) 00665 { 00666 RouterOpts->criticality_exp = Options.criticality_exp; 00667 } 00668 00669 RouterOpts->max_criticality = 0.99; /* DEFAULT */ 00670 if(Options.Count[OT_MAX_CRITICALITY]) 00671 { 00672 RouterOpts->max_criticality = Options.max_criticality; 00673 } 00674 00675 RouterOpts->max_router_iterations = 50; /* DEFAULT */ 00676 if(Options.Count[OT_FAST]) 00677 { 00678 RouterOpts->max_router_iterations = 10; 00679 } 00680 if(Options.Count[OT_MAX_ROUTER_ITERATIONS]) 00681 { 00682 RouterOpts->max_router_iterations = Options.max_router_iterations; 00683 } 00684 00685 RouterOpts->pres_fac_mult = 1.3; /* DEFAULT */ 00686 if(Options.Count[OT_PRES_FAC_MULT]) 00687 { 00688 RouterOpts->pres_fac_mult = Options.pres_fac_mult; 00689 } 00690 00691 00692 RouterOpts->route_type = DETAILED; /* DEFAULT */ 00693 if(Options.Count[OT_ROUTE_TYPE]) 00694 { 00695 RouterOpts->route_type = Options.RouteType; 00696 } 00697 00698 RouterOpts->full_stats = FALSE; /* DEFAULT */ 00699 if(Options.Count[OT_FULL_STATS]) 00700 { 00701 RouterOpts->full_stats = TRUE; 00702 } 00703 00704 RouterOpts->verify_binary_search = FALSE; /* DEFAULT */ 00705 if(Options.Count[OT_VERIFY_BINARY_SEARCH]) 00706 { 00707 RouterOpts->verify_binary_search = TRUE; 00708 } 00709 00710 /* Depends on RouteOpts->route_type */ 00711 RouterOpts->router_algorithm = DIRECTED_SEARCH; /* DEFAULT */ 00712 if(TimingEnabled) 00713 { 00714 RouterOpts->router_algorithm = TIMING_DRIVEN; /* DEFAULT */ 00715 } 00716 if(GLOBAL == RouterOpts->route_type) 00717 { 00718 RouterOpts->router_algorithm = DIRECTED_SEARCH; /* DEFAULT */ 00719 } 00720 if(Options.Count[OT_ROUTER_ALGORITHM]) 00721 { 00722 RouterOpts->router_algorithm = Options.RouterAlgorithm; 00723 } 00724 00725 RouterOpts->fixed_channel_width = NO_FIXED_CHANNEL_WIDTH; /* DEFAULT */ 00726 if(Options.Count[OT_ROUTE_CHAN_WIDTH]) 00727 { 00728 RouterOpts->fixed_channel_width = Options.RouteChanWidth; 00729 } 00730 00731 /* Depends on RouterOpts->router_algorithm */ 00732 RouterOpts->initial_pres_fac = 0.5; /* DEFAULT */ 00733 if(DIRECTED_SEARCH == RouterOpts->router_algorithm || 00734 Options.Count[OT_FAST]) 00735 { 00736 RouterOpts->initial_pres_fac = 10000.0; /* DEFAULT */ 00737 } 00738 if(Options.Count[OT_INITIAL_PRES_FAC]) 00739 { 00740 RouterOpts->initial_pres_fac = Options.initial_pres_fac; 00741 } 00742 00743 /* Depends on RouterOpts->router_algorithm */ 00744 RouterOpts->base_cost_type = DELAY_NORMALIZED; /* DEFAULT */ 00745 if(BREADTH_FIRST == RouterOpts->router_algorithm) 00746 { 00747 RouterOpts->base_cost_type = DEMAND_ONLY; /* DEFAULT */ 00748 } 00749 if(DIRECTED_SEARCH == RouterOpts->router_algorithm) 00750 { 00751 RouterOpts->base_cost_type = DEMAND_ONLY; /* DEFAULT */ 00752 } 00753 if(Options.Count[OT_BASE_COST_TYPE]) 00754 { 00755 RouterOpts->base_cost_type = Options.base_cost_type; 00756 } 00757 00758 /* Depends on RouterOpts->router_algorithm */ 00759 RouterOpts->first_iter_pres_fac = 0.5; /* DEFAULT */ 00760 if(BREADTH_FIRST == RouterOpts->router_algorithm) 00761 { 00762 RouterOpts->first_iter_pres_fac = 0.0; /* DEFAULT */ 00763 } 00764 if(DIRECTED_SEARCH == RouterOpts->router_algorithm || 00765 Options.Count[OT_FAST]) 00766 { 00767 RouterOpts->first_iter_pres_fac = 10000.0; /* DEFAULT */ 00768 } 00769 if(Options.Count[OT_FIRST_ITER_PRES_FAC]) 00770 { 00771 RouterOpts->first_iter_pres_fac = Options.first_iter_pres_fac; 00772 } 00773 00774 /* Depends on RouterOpts->router_algorithm */ 00775 RouterOpts->acc_fac = 1.0; 00776 if(BREADTH_FIRST == RouterOpts->router_algorithm) 00777 { 00778 RouterOpts->acc_fac = 0.2; 00779 } 00780 if(Options.Count[OT_ACC_FAC]) 00781 { 00782 RouterOpts->acc_fac = Options.acc_fac; 00783 } 00784 00785 /* Depends on RouterOpts->route_type */ 00786 RouterOpts->bend_cost = 0.0; /* DEFAULT */ 00787 if(GLOBAL == RouterOpts->route_type) 00788 { 00789 RouterOpts->bend_cost = 1.0; /* DEFAULT */ 00790 } 00791 if(Options.Count[OT_BEND_COST]) 00792 { 00793 RouterOpts->bend_cost = Options.bend_cost; 00794 } 00795 }
static void SetupRoutingArch | ( | IN t_arch | Arch, | |
OUT struct s_det_routing_arch * | RoutingArch | |||
) | [static] |
Definition at line 628 of file SetupVPR.c.
00630 { 00631 00632 RoutingArch->switch_block_type = Arch.SBType; 00633 RoutingArch->R_minW_nmos = Arch.R_minW_nmos; 00634 RoutingArch->R_minW_pmos = Arch.R_minW_pmos; 00635 RoutingArch->Fs = Arch.Fs; 00636 RoutingArch->directionality = BI_DIRECTIONAL; 00637 if(Arch.Segments) 00638 RoutingArch->directionality = Arch.Segments[0].directionality; 00639 }
static void SetupSwitches | ( | IN t_arch | Arch, | |
INOUT struct s_det_routing_arch * | RoutingArch, | |||
IN struct s_switch_inf * | ArchSwitches, | |||
IN int | NumArchSwitches | |||
) | [static] |
Definition at line 581 of file SetupVPR.c.
00585 { 00586 00587 RoutingArch->num_switch = NumArchSwitches; 00588 00589 /* Depends on RoutingArch->num_switch */ 00590 RoutingArch->wire_to_ipin_switch = RoutingArch->num_switch; 00591 ++RoutingArch->num_switch; 00592 00593 /* Depends on RoutingArch->num_switch */ 00594 RoutingArch->delayless_switch = RoutingArch->num_switch; 00595 RoutingArch->global_route_switch = RoutingArch->delayless_switch; 00596 ++RoutingArch->num_switch; 00597 00598 /* Alloc the list now that we know the final num_switch value */ 00599 switch_inf = 00600 (struct s_switch_inf *)my_malloc(sizeof(struct s_switch_inf) * 00601 RoutingArch->num_switch); 00602 00603 /* Copy the switch data from architecture file */ 00604 memcpy(switch_inf, ArchSwitches, 00605 sizeof(struct s_switch_inf) * NumArchSwitches); 00606 00607 /* Delayless switch for connecting sinks and sources with their pins. */ 00608 switch_inf[RoutingArch->delayless_switch].buffered = TRUE; 00609 switch_inf[RoutingArch->delayless_switch].R = 0.; 00610 switch_inf[RoutingArch->delayless_switch].Cin = 0.; 00611 switch_inf[RoutingArch->delayless_switch].Cout = 0.; 00612 switch_inf[RoutingArch->delayless_switch].Tdel = 0.; 00613 00614 /* The wire to ipin switch for all types. Curently all types 00615 * must share ipin switch. Some of the timing code would 00616 * need to be changed otherwise. */ 00617 switch_inf[RoutingArch->wire_to_ipin_switch].buffered = TRUE; 00618 switch_inf[RoutingArch->wire_to_ipin_switch].R = 0.; 00619 switch_inf[RoutingArch->wire_to_ipin_switch].Cin = Arch.C_ipin_cblock; 00620 switch_inf[RoutingArch->wire_to_ipin_switch].Cout = 0.; 00621 switch_inf[RoutingArch->wire_to_ipin_switch].Tdel = Arch.T_ipin_cblock; 00622 }
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 | |||
) | [static] |
Definition at line 555 of file SetupVPR.c.
00562 { 00563 00564 /* Don't do anything if they don't want timing */ 00565 if(FALSE == TimingEnabled) 00566 { 00567 memset(Timing, 0, sizeof(t_timing_inf)); 00568 Timing->timing_analysis_enabled = FALSE; 00569 return; 00570 } 00571 00572 Timing->C_ipin_cblock = Arch.C_ipin_cblock; 00573 Timing->T_ipin_cblock = Arch.T_ipin_cblock; 00574 Timing->timing_analysis_enabled = TimingEnabled; 00575 }
void SetupVPR | ( | IN t_options | Options, | |
IN boolean | TimingEnabled, | |||
OUT t_arch * | Arch, | |||
OUT enum e_operation * | Operation, | |||
OUT struct s_placer_opts * | PlacerOpts, | |||
OUT struct s_annealing_sched * | AnnealSched, | |||
OUT struct s_router_opts * | RouterOpts, | |||
OUT struct s_det_routing_arch * | RoutingArch, | |||
OUT t_segment_inf ** | Segments, | |||
OUT t_timing_inf * | Timing, | |||
OUT t_subblock_data * | Subblocks, | |||
OUT boolean * | ShowGraphics, | |||
OUT int * | GraphPause | |||
) |
Definition at line 49 of file SetupVPR.c.
00062 { 00063 00064 SetupOperation(Options, Operation); 00065 SetupPlacerOpts(Options, TimingEnabled, PlacerOpts); 00066 SetupAnnealSched(Options, AnnealSched); 00067 SetupRouterOpts(Options, TimingEnabled, RouterOpts); 00068 00069 XmlReadArch(Options.ArchFile, TimingEnabled, Arch, 00070 &type_descriptors, &num_types); 00071 00072 *Segments = Arch->Segments; 00073 RoutingArch->num_segment = Arch->num_segments; 00074 00075 SetupSwitches(*Arch, RoutingArch, Arch->Switches, Arch->num_switches); 00076 SetupRoutingArch(*Arch, RoutingArch); 00077 SetupTiming(Options, *Arch, TimingEnabled, *Operation, 00078 *PlacerOpts, *RouterOpts, Timing); 00079 00080 /* init global variables */ 00081 OutFilePrefix = Options.OutFilePrefix; 00082 grid_logic_tile_area = Arch->grid_logic_tile_area; 00083 ipin_mux_trans_size = Arch->ipin_mux_trans_size; 00084 00085 /* Set seed for pseudo-random placement, default seed to 1 */ 00086 PlacerOpts->seed = 1; 00087 if(Options.Count[OT_SEED]) 00088 { 00089 PlacerOpts->seed = Options.Seed; 00090 } 00091 my_srandom(PlacerOpts->seed); 00092 00093 *GraphPause = 1; /* DEFAULT */ 00094 if(Options.Count[OT_AUTO]) 00095 { 00096 *GraphPause = Options.GraphPause; 00097 } 00098 #ifdef NO_GRAPHICS 00099 *ShowGraphics = FALSE; /* DEFAULT */ 00100 #else /* NO_GRAPHICS */ 00101 *ShowGraphics = TRUE; /* DEFAULT */ 00102 if(Options.Count[OT_NODISP]) 00103 { 00104 *ShowGraphics = FALSE; 00105 } 00106 #endif /* NO_GRAPHICS */ 00107 00108 #ifdef CREATE_ECHO_FILES 00109 EchoArch("arch.echo", type_descriptors, num_types); 00110 #endif 00111 00112 if(Options.NetFile) 00113 { 00114 read_netlist(Options.NetFile, num_types, type_descriptors, 00115 IO_TYPE, 0, 1, Subblocks, &num_blocks, &block, 00116 &num_nets, &net); 00117 /* This is done so that all blocks have subblocks and can be treated the same */ 00118 load_subblock_info_to_type(Subblocks, IO_TYPE); 00119 check_netlist(Subblocks); 00120 } 00121 00122 InitArch(*Arch); 00123 }