00001 #include <assert.h>
00002 #include <string.h>
00003 #include "util.h"
00004 #include "vpr_types.h"
00005 #include "check_netlist.h"
00006 #include "OptionTokens.h"
00007 #include "ReadOptions.h"
00008 #include "read_netlist.h"
00009 #include "globals.h"
00010 #include "xml_arch.h"
00011 #include "SetupVPR.h"
00012
00013 static void SetupOperation(IN t_options Options,
00014 OUT enum e_operation *Operation);
00015 static void SetupPlacerOpts(IN t_options Options,
00016 IN boolean TimingEnabled,
00017 OUT struct s_placer_opts *PlacerOpts);
00018 static void SetupAnnealSched(IN t_options Options,
00019 OUT struct s_annealing_sched *AnnealSched);
00020 static void SetupRouterOpts(IN t_options Options,
00021 IN boolean TimingEnabled,
00022 OUT struct s_router_opts *RouterOpts);
00023 static void SetupGlobalRoutingArch(OUT struct s_det_routing_arch *RoutingArch,
00024 OUT t_segment_inf ** Segments);
00025 static void SetupRoutingArch(IN t_arch Arch,
00026 OUT struct s_det_routing_arch *RoutingArch);
00027 static void SetupTiming(IN t_options Options,
00028 IN t_arch Arch,
00029 IN boolean TimingEnabled,
00030 IN enum e_operation Operation,
00031 IN struct s_placer_opts PlacerOpts,
00032 IN struct s_router_opts RouterOpts,
00033 OUT t_timing_inf * Timing);
00034 static void load_subblock_info_to_type(INOUT t_subblock_data * subblocks,
00035 INOUT t_type_ptr type);
00036 static void InitArch(IN t_arch Arch);
00037 static void alloc_and_load_grid(INOUT int *num_instances_type);
00038 static void freeGrid();
00039 static void CheckGrid(void);
00040 static t_type_ptr find_type_col(IN int x);
00041 static void SetupSwitches(IN t_arch Arch,
00042 INOUT struct s_det_routing_arch *RoutingArch,
00043 IN struct s_switch_inf *ArchSwitches,
00044 IN int NumArchSwitches);
00045
00046
00047
00048 void
00049 SetupVPR(IN t_options Options,
00050 IN boolean TimingEnabled,
00051 OUT t_arch * Arch,
00052 OUT enum e_operation *Operation,
00053 OUT struct s_placer_opts *PlacerOpts,
00054 OUT struct s_annealing_sched *AnnealSched,
00055 OUT struct s_router_opts *RouterOpts,
00056 OUT struct s_det_routing_arch *RoutingArch,
00057 OUT t_segment_inf ** Segments,
00058 OUT t_timing_inf * Timing,
00059 OUT t_subblock_data * Subblocks,
00060 OUT boolean * ShowGraphics,
00061 OUT int *GraphPause)
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
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
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;
00094 if(Options.Count[OT_AUTO])
00095 {
00096 *GraphPause = Options.GraphPause;
00097 }
00098 #ifdef NO_GRAPHICS
00099 *ShowGraphics = FALSE;
00100 #else
00101 *ShowGraphics = TRUE;
00102 if(Options.Count[OT_NODISP])
00103 {
00104 *ShowGraphics = FALSE;
00105 }
00106 #endif
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
00118 load_subblock_info_to_type(Subblocks, IO_TYPE);
00119 check_netlist(Subblocks);
00120 }
00121
00122 InitArch(*Arch);
00123 }
00124
00125
00126
00127
00128
00129 static void
00130 InitArch(IN t_arch Arch)
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));
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
00152 while(high == -1 || low < high)
00153 {
00154
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
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
00183 if(!fit)
00184 {
00185
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
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
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 }
00264
00265
00266
00267 static void
00268 alloc_and_load_grid(INOUT int *num_instances_type)
00269 {
00270
00271 int i, j;
00272 t_type_ptr type;
00273
00274 #ifdef SHOW_ARCH
00275 FILE *dump;
00276 #endif
00277
00278
00279
00280
00281
00282
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
00295
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
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
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 {
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
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 }
00413
00414 static void
00415 freeGrid()
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 }
00428
00429
00430 static void
00431 CheckGrid()
00432 {
00433 int i, j;
00434
00435
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 }
00476
00477 static t_type_ptr
00478 find_type_col(IN int x)
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 }
00552
00553
00554 static void
00555 SetupTiming(IN t_options Options,
00556 IN t_arch Arch,
00557 IN boolean TimingEnabled,
00558 IN enum e_operation Operation,
00559 IN struct s_placer_opts PlacerOpts,
00560 IN struct s_router_opts RouterOpts,
00561 OUT t_timing_inf * Timing)
00562 {
00563
00564
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 }
00576
00577
00578
00579
00580 static void
00581 SetupSwitches(IN t_arch Arch,
00582 INOUT struct s_det_routing_arch *RoutingArch,
00583 IN struct s_switch_inf *ArchSwitches,
00584 IN int NumArchSwitches)
00585 {
00586
00587 RoutingArch->num_switch = NumArchSwitches;
00588
00589
00590 RoutingArch->wire_to_ipin_switch = RoutingArch->num_switch;
00591 ++RoutingArch->num_switch;
00592
00593
00594 RoutingArch->delayless_switch = RoutingArch->num_switch;
00595 RoutingArch->global_route_switch = RoutingArch->delayless_switch;
00596 ++RoutingArch->num_switch;
00597
00598
00599 switch_inf =
00600 (struct s_switch_inf *)my_malloc(sizeof(struct s_switch_inf) *
00601 RoutingArch->num_switch);
00602
00603
00604 memcpy(switch_inf, ArchSwitches,
00605 sizeof(struct s_switch_inf) * NumArchSwitches);
00606
00607
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
00615
00616
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 }
00623
00624
00625
00626
00627 static void
00628 SetupRoutingArch(IN t_arch Arch,
00629 OUT struct s_det_routing_arch *RoutingArch)
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 }
00640
00641
00642 static void
00643 SetupRouterOpts(IN t_options Options,
00644 IN boolean TimingEnabled,
00645 OUT struct s_router_opts *RouterOpts)
00646 {
00647 RouterOpts->astar_fac = 1.2;
00648 if(Options.Count[OT_ASTAR_FAC])
00649 {
00650 RouterOpts->astar_fac = Options.astar_fac;
00651 }
00652
00653 RouterOpts->bb_factor = 3;
00654 if(Options.Count[OT_FAST])
00655 {
00656 RouterOpts->bb_factor = 0;
00657 }
00658 if(Options.Count[OT_BB_FACTOR])
00659 {
00660 RouterOpts->bb_factor = Options.bb_factor;
00661 }
00662
00663 RouterOpts->criticality_exp = 1.0;
00664 if(Options.Count[OT_CRITICALITY_EXP])
00665 {
00666 RouterOpts->criticality_exp = Options.criticality_exp;
00667 }
00668
00669 RouterOpts->max_criticality = 0.99;
00670 if(Options.Count[OT_MAX_CRITICALITY])
00671 {
00672 RouterOpts->max_criticality = Options.max_criticality;
00673 }
00674
00675 RouterOpts->max_router_iterations = 50;
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;
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;
00693 if(Options.Count[OT_ROUTE_TYPE])
00694 {
00695 RouterOpts->route_type = Options.RouteType;
00696 }
00697
00698 RouterOpts->full_stats = FALSE;
00699 if(Options.Count[OT_FULL_STATS])
00700 {
00701 RouterOpts->full_stats = TRUE;
00702 }
00703
00704 RouterOpts->verify_binary_search = FALSE;
00705 if(Options.Count[OT_VERIFY_BINARY_SEARCH])
00706 {
00707 RouterOpts->verify_binary_search = TRUE;
00708 }
00709
00710
00711 RouterOpts->router_algorithm = DIRECTED_SEARCH;
00712 if(TimingEnabled)
00713 {
00714 RouterOpts->router_algorithm = TIMING_DRIVEN;
00715 }
00716 if(GLOBAL == RouterOpts->route_type)
00717 {
00718 RouterOpts->router_algorithm = DIRECTED_SEARCH;
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;
00726 if(Options.Count[OT_ROUTE_CHAN_WIDTH])
00727 {
00728 RouterOpts->fixed_channel_width = Options.RouteChanWidth;
00729 }
00730
00731
00732 RouterOpts->initial_pres_fac = 0.5;
00733 if(DIRECTED_SEARCH == RouterOpts->router_algorithm ||
00734 Options.Count[OT_FAST])
00735 {
00736 RouterOpts->initial_pres_fac = 10000.0;
00737 }
00738 if(Options.Count[OT_INITIAL_PRES_FAC])
00739 {
00740 RouterOpts->initial_pres_fac = Options.initial_pres_fac;
00741 }
00742
00743
00744 RouterOpts->base_cost_type = DELAY_NORMALIZED;
00745 if(BREADTH_FIRST == RouterOpts->router_algorithm)
00746 {
00747 RouterOpts->base_cost_type = DEMAND_ONLY;
00748 }
00749 if(DIRECTED_SEARCH == RouterOpts->router_algorithm)
00750 {
00751 RouterOpts->base_cost_type = DEMAND_ONLY;
00752 }
00753 if(Options.Count[OT_BASE_COST_TYPE])
00754 {
00755 RouterOpts->base_cost_type = Options.base_cost_type;
00756 }
00757
00758
00759 RouterOpts->first_iter_pres_fac = 0.5;
00760 if(BREADTH_FIRST == RouterOpts->router_algorithm)
00761 {
00762 RouterOpts->first_iter_pres_fac = 0.0;
00763 }
00764 if(DIRECTED_SEARCH == RouterOpts->router_algorithm ||
00765 Options.Count[OT_FAST])
00766 {
00767 RouterOpts->first_iter_pres_fac = 10000.0;
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
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
00786 RouterOpts->bend_cost = 0.0;
00787 if(GLOBAL == RouterOpts->route_type)
00788 {
00789 RouterOpts->bend_cost = 1.0;
00790 }
00791 if(Options.Count[OT_BEND_COST])
00792 {
00793 RouterOpts->bend_cost = Options.bend_cost;
00794 }
00795 }
00796
00797
00798 static void
00799 SetupAnnealSched(IN t_options Options,
00800 OUT struct s_annealing_sched *AnnealSched)
00801 {
00802 AnnealSched->alpha_t = 0.8;
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;
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;
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;
00838 if(Options.Count[OT_FAST]) {
00839 AnnealSched->inner_num = 1.0;
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;
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 }
00857
00858
00859
00860
00861 static void
00862 SetupPlacerOpts(IN t_options Options,
00863 IN boolean TimingEnabled,
00864 OUT struct s_placer_opts *PlacerOpts)
00865 {
00866 PlacerOpts->block_dist = 1;
00867 if(Options.Count[OT_BLOCK_DIST])
00868 {
00869 PlacerOpts->block_dist = Options.block_dist;
00870 }
00871
00872 PlacerOpts->inner_loop_recompute_divider = 0;
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;
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;
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;
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;
00897 if(Options.Count[OT_PLACE_COST_TYPE])
00898 {
00899 PlacerOpts->place_cost_type = Options.PlaceCostType;
00900 }
00901
00902
00903 PlacerOpts->place_algorithm = BOUNDING_BOX_PLACE;
00904 if(TimingEnabled)
00905 {
00906 PlacerOpts->place_algorithm = PATH_TIMING_DRIVEN_PLACE;
00907 }
00908 if(NONLINEAR_CONG == PlacerOpts->place_cost_type)
00909 {
00910 PlacerOpts->place_algorithm = BOUNDING_BOX_PLACE;
00911 }
00912 if(Options.Count[OT_PLACE_ALGORITHM])
00913 {
00914 PlacerOpts->place_algorithm = Options.PlaceAlgorithm;
00915 }
00916
00917 PlacerOpts->num_regions = 4;
00918 if(Options.Count[OT_NUM_REGIONS])
00919 {
00920 PlacerOpts->num_regions = Options.PlaceNonlinearRegions;
00921 }
00922
00923 PlacerOpts->pad_loc_file = NULL;
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;
00933 if(Options.Count[OT_FIX_PINS])
00934 {
00935 PlacerOpts->pad_loc_type = (Options.PinFile ? USER : RANDOM);
00936 }
00937
00938
00939 PlacerOpts->place_chan_width = 100;
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;
00951 if(Options.Count[OT_RECOMPUTE_CRIT_ITER])
00952 {
00953 PlacerOpts->recompute_crit_iter = Options.RecomputeCritIter;
00954 }
00955
00956 PlacerOpts->timing_tradeoff = 0.5;
00957 if(Options.Count[OT_TIMING_TRADEOFF])
00958 {
00959 PlacerOpts->timing_tradeoff = Options.PlaceTimingTradeoff;
00960 }
00961
00962
00963 PlacerOpts->enable_timing_computations = FALSE;
00964 if((PlacerOpts->place_algorithm == PATH_TIMING_DRIVEN_PLACE) ||
00965 (PlacerOpts->place_algorithm == NET_TIMING_DRIVEN_PLACE))
00966 {
00967 PlacerOpts->enable_timing_computations = TRUE;
00968 }
00969 if(Options.Count[OT_ENABLE_TIMING_COMPUTATIONS])
00970 {
00971 PlacerOpts->enable_timing_computations = Options.ShowPlaceTiming;
00972 }
00973
00974
00975 PlacerOpts->place_freq = PLACE_ONCE;
00976 if(NONLINEAR_CONG == PlacerOpts->place_cost_type)
00977 {
00978 PlacerOpts->place_freq = PLACE_ALWAYS;
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 }
00990
00991
00992 static void
00993 SetupOperation(IN t_options Options,
00994 OUT enum e_operation *Operation)
00995 {
00996 *Operation = PLACE_AND_ROUTE;
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 }
01010
01011
01012
01013
01014
01015 boolean
01016 IsTimingEnabled(IN t_options Options)
01017 {
01018
01019 if(Options.Count[OT_TIMING_ANALYSIS])
01020 {
01021 return Options.TimingAnalysis;
01022 }
01023 return TRUE;
01024 }
01025
01026
01027
01028 static void
01029 load_subblock_info_to_type(INOUT t_subblock_data * subblocks,
01030 INOUT t_type_ptr type)
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
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 }