VPR-6.0
|
00001 #include <stdio.h> 00002 #include <string.h> 00003 #include <assert.h> 00004 #include <time.h> 00005 00006 #include "util.h" 00007 #include "vpr_types.h" 00008 #include "globals.h" 00009 #include "graphics.h" 00010 #include "read_netlist.h" 00011 #include "check_netlist.h" 00012 #include "print_netlist.h" 00013 #include "draw.h" 00014 #include "place_and_route.h" 00015 #include "pack.h" 00016 #include "SetupGrid.h" 00017 #include "stats.h" 00018 #include "path_delay.h" 00019 #include "OptionTokens.h" 00020 #include "ReadOptions.h" 00021 #include "read_xml_arch_file.h" 00022 #include "SetupVPR.h" 00023 #include "rr_graph.h" 00024 #include "pb_type_graph.h" 00025 00026 /******** Global variables ********/ 00027 int Fs_seed = -1; 00028 00029 int W_seed = -1; 00030 int binary_search = -1; 00031 00032 float grid_logic_tile_area = 0; 00033 float ipin_mux_trans_size = 0; 00034 00035 /* t-vpack globals begin */ 00036 int num_logical_nets = 0, num_logical_blocks = 0, num_saved_logical_blocks = 0, num_saved_logical_nets = 0, num_subckts = 0; 00037 int num_p_inputs = 0, num_p_outputs = 0, num_luts = 0, num_latches = 0; 00038 struct s_net *vpack_net = NULL, *saved_logical_nets = NULL; 00039 struct s_logical_block *logical_block = NULL, *saved_logical_blocks = NULL; 00040 struct s_subckt *subckt = NULL; 00041 char *blif_circuit_name = NULL; 00042 /* t-vpack globals end */ 00043 00044 /******** Netlist to be mapped stuff ********/ 00045 00046 int num_nets = 0; 00047 struct s_net *clb_net = NULL; 00048 00049 int num_blocks = 0; 00050 struct s_block *block = NULL; 00051 00052 int num_ff = 0; 00053 int num_const_gen = 0; 00054 00055 int *clb_to_vpack_net_mapping = NULL; /**< [0..num_clb_nets - 1] */ 00056 int *vpack_to_clb_net_mapping = NULL; /**< [0..num_vpack_nets - 1] */ 00057 00058 /* This identifies the t_type_ptr of an IO block */ 00059 int num_types = 0; 00060 struct s_type_descriptor *type_descriptors = NULL; 00061 00062 t_type_ptr IO_TYPE = NULL; 00063 t_type_ptr EMPTY_TYPE = NULL; 00064 t_type_ptr FILL_TYPE = NULL; 00065 00066 00067 /******** Physical architecture stuff ********/ 00068 00069 int nx = 0; 00070 int ny = 0; 00071 00072 /* TRUE if this is a global clb pin -- an input pin to which the netlist can * 00073 * connect global signals, but which does not connect into the normal * 00074 * routing via muxes etc. Marking pins like this (only clocks in my work) * 00075 * stops them from screwing up the input switch pattern in the rr_graph * 00076 * generator and from creating extra switches that the area model would * 00077 * count. */ 00078 00079 int *chan_width_x = NULL; /**< [0..ny] */ 00080 int *chan_width_y = NULL; /**< [0..nx] */ 00081 00082 struct s_grid_tile **grid = NULL; /**< [0..(nx+1)][0..(ny+1)] Physical block list */ 00083 00084 00085 /******** Structures defining the routing ********/ 00086 00087 /**@{*/ 00088 /** Linked list start pointers. Define the routing. */ 00089 struct s_trace **trace_head = NULL; /**< [0..(num_nets-1)] */ 00090 struct s_trace **trace_tail = NULL; /**< [0..(num_nets-1)] */ 00091 /**@}*/ 00092 00093 00094 /******** Structures defining the FPGA routing architecture ********/ 00095 00096 int num_rr_nodes = 0; 00097 t_rr_node *rr_node = NULL; /**< [0..(num_rr_nodes-1)] */ 00098 t_ivec ***rr_node_indices = NULL; 00099 00100 int num_rr_indexed_data = 0; 00101 t_rr_indexed_data *rr_indexed_data = NULL; /**< [0..(num_rr_indexed_data-1)] */ 00102 00103 /** Gives the rr_node indices of net terminals. */ 00104 int **net_rr_terminals = NULL; /**< [0..num_nets-1][0..num_pins-1] */ 00105 00106 /** Gives information about all the switch types 00107 * (part of routing architecture, but loaded in read_arch.c 00108 */ 00109 struct s_switch_inf *switch_inf = NULL; /**< [0..(det_routing_arch.num_switch-1)] */ 00110 00111 /** Stores the SOURCE and SINK nodes of all CLBs (not valid for pads). */ 00112 int **rr_blk_source = NULL; /**< [0..(num_blocks-1)][0..(num_class-1)] */ 00113 00114 /** primary inputs removed from circuit */ 00115 struct s_linked_vptr *circuit_p_io_removed = NULL; 00116 00117 00118 /********** Structures representing timing graph information */ 00119 t_tnode *tnode = NULL; /**< [0..num_tnodes - 1] */ 00120 int num_tnodes = 0; /**< Number of nodes (pins) in the timing graph */ 00121 float pb_max_internal_delay = UNDEFINED; /**< biggest internal delay of physical block */ 00122 const t_pb_type *pbtype_max_internal_delay = NULL; /**< physical block type with highest internal delay */ 00123 00124 00125 /********************** Subroutines local to this module ********************/ 00126 00127 static void PrintUsage(); 00128 static void PrintTitle(); 00129 static void freeArch(t_arch* Arch); 00130 static void freeOptions(t_options *options); 00131 static void InitArch(INP t_arch Arch); 00132 static void free_pb_type(t_pb_type *pb_type); 00133 static void free_complex_block_types(); 00134 00135 00136 00137 /************************* Subroutine definitions ***************************/ 00138 00139 /** 00140 * VPR program 00141 * Generate FPGA architecture given architecture description 00142 * Pack, place, and route circuit into FPGA architecture 00143 * Electrical timing analysis on results 00144 * 00145 * Overall steps 00146 * - 1. Initialization 00147 * - 2. Pack 00148 * - 3. Place-and-route and timing analysis 00149 */ 00150 int 00151 main(int argc, 00152 char **argv) 00153 { 00154 t_options Options; 00155 t_arch Arch; 00156 t_model *user_models, *library_models; 00157 00158 enum e_operation Operation; 00159 struct s_file_name_opts FileNameOpts; 00160 struct s_packer_opts PackerOpts; 00161 struct s_placer_opts PlacerOpts; 00162 struct s_annealing_sched AnnealSched; 00163 struct s_router_opts RouterOpts; 00164 struct s_det_routing_arch RoutingArch; 00165 t_segment_inf *Segments; 00166 t_timing_inf Timing; 00167 boolean ShowGraphics; 00168 boolean TimingEnabled; 00169 int GraphPause; 00170 clock_t begin, end; 00171 00172 /* Print title message */ 00173 PrintTitle(); 00174 00175 /* Print usage message if no args */ 00176 if(argc < 2) 00177 { 00178 PrintUsage(); 00179 exit(1); 00180 } 00181 00182 /* Read in available inputs */ 00183 ReadOptions(argc, argv, &Options); 00184 00185 /* Determine whether timing is on or off */ 00186 TimingEnabled = IsTimingEnabled(Options); 00187 00188 /* Use inputs to configure VPR */ 00189 memset(&Arch, 0, sizeof(t_arch)); 00190 SetupVPR(Options, TimingEnabled, &FileNameOpts, &Arch, &Operation, &user_models, 00191 &library_models, &PackerOpts, &PlacerOpts, 00192 &AnnealSched, &RouterOpts, &RoutingArch, &Segments, 00193 &Timing, &ShowGraphics, &GraphPause); 00194 00195 /* Check inputs are reasonable */ 00196 CheckOptions(Options, TimingEnabled); 00197 CheckArch(Arch, TimingEnabled); 00198 00199 /* Verify settings don't conflict or otherwise not make sense */ 00200 CheckSetup(Operation, PlacerOpts, AnnealSched, RouterOpts, 00201 RoutingArch, Segments, Timing, Arch.Chans); 00202 fflush(stdout); 00203 00204 /* Packing stage */ 00205 if(PackerOpts.doPacking) { 00206 begin = clock(); 00207 try_pack(&PackerOpts, &Arch, user_models, library_models); 00208 end = clock(); 00209 #ifdef CLOCKS_PER_SEC 00210 printf("Packing took %g seconds\n", (float)(end - begin) / CLOCKS_PER_SEC); 00211 #else 00212 printf("Packing took %g seconds\n", (float)(end - begin) / CLK_PER_SEC); 00213 #endif 00214 00215 /* Free logical blocks and nets */ 00216 if(logical_block != NULL) { 00217 free_logical_blocks(); 00218 free_logical_nets(); 00219 } 00220 if(!PlacerOpts.doPlacement && !RouterOpts.doRouting) { 00221 return 0; 00222 } 00223 } 00224 /* Packing stage complete */ 00225 fflush(stdout); 00226 00227 /* Read in netlist file for placement and routing */ 00228 if(FileNameOpts.NetFile) 00229 { 00230 read_netlist(FileNameOpts.NetFile, &Arch, &num_blocks, &block, &num_nets, &clb_net); 00231 /* This is done so that all blocks have subblocks and can be treated the same */ 00232 check_netlist(); 00233 } 00234 00235 /* Output the current settings to console. */ 00236 ShowSetup(Options, Arch, TimingEnabled, Operation, FileNameOpts, PlacerOpts, 00237 AnnealSched, RouterOpts, RoutingArch, Segments, Timing); 00238 00239 00240 if(Operation == TIMING_ANALYSIS_ONLY) { 00241 do_constant_net_delay_timing_analysis( 00242 Timing, Options.constant_net_delay); 00243 return 0; 00244 } 00245 00246 InitArch(Arch); 00247 fflush(stdout); 00248 00249 00250 /* Startup X graphics */ 00251 set_graphics_state(ShowGraphics, GraphPause, RouterOpts.route_type); 00252 if(ShowGraphics) 00253 { 00254 init_graphics("VPR: Versatile Place and Route for FPGAs"); 00255 alloc_draw_structs(); 00256 } 00257 00258 /* Do placement and routing */ 00259 place_and_route(Operation, PlacerOpts, FileNameOpts.PlaceFile, 00260 FileNameOpts.NetFile, FileNameOpts.ArchFile, FileNameOpts.RouteFile, 00261 AnnealSched, RouterOpts, RoutingArch, 00262 Segments, Timing, Arch.Chans, Arch.models); 00263 00264 fflush(stdout); 00265 00266 /* Close down X Display */ 00267 if(ShowGraphics) 00268 close_graphics(); 00269 00270 /* free data structures */ 00271 freeOptions(&Options); 00272 00273 /* Free logical blocks and nets */ 00274 if(logical_block != NULL) { 00275 free_logical_blocks(); 00276 free_logical_nets(); 00277 } 00278 00279 00280 freeArch(&Arch); 00281 free_complex_block_types(); 00282 00283 /* Return 0 to single success to scripts */ 00284 return 0; 00285 } 00286 00287 00288 00289 /** Outputs usage message */ 00290 static void 00291 PrintUsage() 00292 { 00293 puts("Usage: vpr fpga_architecture.xml circuit_name [Options ...]"); 00294 puts(""); 00295 puts("General Options: [--nodisp] [--auto <int>] [--pack]"); 00296 puts("\t[--place] [--route] [--timing_analyze_only_with_net_delay <float>]"); 00297 puts("\t[--fast] [--full_stats] [--timing_analysis on | off] [--outfile_prefix <string>]"); 00298 puts("\t[--blif_file <string>][--net_file <string>][--place_file <string>][--route_file <string>]"); 00299 puts(""); 00300 puts("Packer Options:"); 00301 /* puts("\t[-global_clocks on|off]"); 00302 puts("\t[-hill_climbing on|off]"); 00303 puts("\t[-sweep_hanging_nets_and_inputs on|off]"); */ 00304 puts("\t[--timing_driven_clustering on|off]"); 00305 puts("\t[--cluster_seed_type timing|max_inputs] [--alpha_clustering <float>] [--beta_clustering <float>]"); 00306 /* puts("\t[-recompute_timing_after <int>] [-cluster_block_delay <float>]"); */ 00307 puts("\t[--allow_unrelated_clustering on|off]"); 00308 /* puts("\t[-allow_early_exit on|off]"); 00309 puts("\t[-intra_cluster_net_delay <float>] "); 00310 puts("\t[-inter_cluster_net_delay <float>] "); */ 00311 puts("\t[--connection_driven_clustering on|off] "); 00312 /* puts("\t[-packer_algorithm greedy|brute_force]"); 00313 puts("\t[-hack_no_legal_frac_lut]"); 00314 puts("\t[-hack_safe_latch]"); */ 00315 puts(""); 00316 puts("Placer Options:"); 00317 puts("\t[--place_algorithm bounding_box | net_timing_driven | path_timing_driven]"); 00318 puts("\t[--init_t <float>] [--exit_t <float>]"); 00319 puts("\t[--alpha_t <float>] [--inner_num <float>] [--seed <int>]"); 00320 puts("\t[--place_cost_exp <float>] [--place_cost_type linear | nonlinear]"); 00321 puts("\t[--place_chan_width <int>] [--num_regions <int>] "); 00322 puts("\t[--fix_pins random | <file.pads>]"); 00323 puts("\t[--enable_timing_computations on | off]"); 00324 puts("\t[--block_dist <int>]"); 00325 puts(""); 00326 puts("Placement Options Valid Only for Timing-Driven Placement:"); 00327 puts("\t[--timing_tradeoff <float>]"); 00328 puts("\t[--recompute_crit_iter <int>]"); 00329 puts("\t[--inner_loop_recompute_divider <int>]"); 00330 puts("\t[--td_place_exp_first <float>]"); 00331 puts("\t[--td_place_exp_last <float>]"); 00332 puts(""); 00333 puts("Router Options: [-max_router_iterations <int>] [-bb_factor <int>]"); 00334 puts("\t[--initial_pres_fac <float>] [--pres_fac_mult <float>]"); 00335 puts("\t[--acc_fac <float>] [--first_iter_pres_fac <float>]"); 00336 puts("\t[--bend_cost <float>] [--route_type global | detailed]"); 00337 puts("\t[--verify_binary_search] [--route_chan_width <int>]"); 00338 puts("\t[--router_algorithm breadth_first | timing_driven | directed_search]"); 00339 puts("\t[--base_cost_type intrinsic_delay | delay_normalized | demand_only]"); 00340 puts(""); 00341 puts("Routing options valid only for timing-driven routing:"); 00342 puts("\t[--astar_fac <float>] [--max_criticality <float>]"); 00343 puts("\t[--criticality_exp <float>]"); 00344 puts(""); 00345 } 00346 00347 00348 00349 static void 00350 PrintTitle() 00351 { 00352 puts(""); 00353 puts("VPR FPGA Placement and Routing."); 00354 puts("Version: Version " VPR_VERSION); 00355 puts("Compiled: " __DATE__ "."); 00356 puts("Original VPR by V. Betz."); 00357 puts("Timing-driven placement enhancements by A. Marquardt."); 00358 puts("Single-drivers enhancements by Andy Ye with additions by."); 00359 puts("Mark Fang, Jason Luu, Ted Campbell"); 00360 puts("Heterogeneous stucture support by Jason Luu and Ted Campbell."); 00361 puts("T-VPack clustering integration by Jason Luu."); 00362 puts("Area-driven AAPack added by Jason Luu."); 00363 puts("This code is licensed only for non-commercial use."); 00364 puts(""); 00365 } 00366 00367 static void freeArch(t_arch* Arch) 00368 { 00369 int i; 00370 t_model *model, *prev; 00371 t_model_ports *port, *prev_port; 00372 struct s_linked_vptr *vptr, *vptr_prev; 00373 for(i = 0; i < Arch->num_switches; i++) { 00374 if(Arch->Switches->name != NULL) { 00375 free(Arch->Switches[i].name); 00376 } 00377 } 00378 free(Arch->Switches); 00379 for(i = 0; i < Arch->num_segments; i++) { 00380 if(Arch->Segments->cb != NULL) { 00381 free(Arch->Segments[i].cb); 00382 } 00383 if(Arch->Segments->sb != NULL) { 00384 free(Arch->Segments[i].sb); 00385 } 00386 } 00387 free(Arch->Segments); 00388 model = Arch->models; 00389 while(model) { 00390 port = model->inputs; 00391 while(port) { 00392 prev_port = port; 00393 port = port->next; 00394 free(prev_port->name); 00395 free(prev_port); 00396 } 00397 port = model->outputs; 00398 while(port) { 00399 prev_port = port; 00400 port = port->next; 00401 free(prev_port->name); 00402 free(prev_port); 00403 } 00404 vptr = model->pb_types; 00405 while(vptr) { 00406 vptr_prev = vptr; 00407 vptr = vptr->next; 00408 free(vptr_prev); 00409 } 00410 prev = model; 00411 00412 model = model->next; 00413 if(prev->instances) 00414 free(prev->instances); 00415 free(prev->name); 00416 free(prev); 00417 } 00418 00419 for(i = 0; i < 4; i++) { 00420 vptr = Arch->model_library[i].pb_types; 00421 while(vptr) { 00422 vptr_prev = vptr; 00423 vptr = vptr->next; 00424 free(vptr_prev); 00425 } 00426 } 00427 00428 free(Arch->model_library[0].name); 00429 free(Arch->model_library[0].outputs->name); 00430 free(Arch->model_library[0].outputs); 00431 free(Arch->model_library[1].inputs->name); 00432 free(Arch->model_library[1].inputs); 00433 free(Arch->model_library[1].name); 00434 free(Arch->model_library[2].name); 00435 free(Arch->model_library[2].inputs[0].name); 00436 free(Arch->model_library[2].inputs[1].name); 00437 free(Arch->model_library[2].inputs); 00438 free(Arch->model_library[2].outputs->name); 00439 free(Arch->model_library[2].outputs); 00440 free(Arch->model_library[3].name); 00441 free(Arch->model_library[3].inputs->name); 00442 free(Arch->model_library[3].inputs); 00443 free(Arch->model_library[3].outputs->name); 00444 free(Arch->model_library[3].outputs); 00445 free(Arch->model_library); 00446 } 00447 00448 static void free_complex_block_types() { 00449 int i, j, k, m; 00450 00451 free_all_pb_graph_nodes(); 00452 00453 for(i = 0; i < num_types; i++) { 00454 if(&type_descriptors[i] == EMPTY_TYPE) { 00455 continue; 00456 } 00457 free(type_descriptors[i].name); 00458 for(j = 0; j < type_descriptors[i].height; j++) { 00459 for(k = 0; k < 4; k ++) { 00460 for(m = 0; m < type_descriptors[i].num_pin_loc_assignments[j][k]; m++) { 00461 if(type_descriptors[i].pin_loc_assignments[j][k][m]) 00462 free(type_descriptors[i].pin_loc_assignments[j][k][m]); 00463 } 00464 free(type_descriptors[i].pinloc[j][k]); 00465 free(type_descriptors[i].pin_loc_assignments[j][k]); 00466 } 00467 free(type_descriptors[i].pinloc[j]); 00468 free(type_descriptors[i].pin_loc_assignments[j]); 00469 free(type_descriptors[i].num_pin_loc_assignments[j]); 00470 } 00471 free(type_descriptors[i].pinloc); 00472 free(type_descriptors[i].pin_loc_assignments); 00473 free(type_descriptors[i].num_pin_loc_assignments); 00474 free(type_descriptors[i].pin_height); 00475 00476 free_pb_type(type_descriptors[i].pb_type); 00477 free(type_descriptors[i].pb_type); 00478 } 00479 } 00480 00481 static void free_pb_type(t_pb_type *pb_type) { 00482 00483 int i, j, k, m; 00484 struct s_linked_vptr *vptr, *prev; 00485 00486 free(pb_type->name); 00487 if(pb_type->blif_model) 00488 free(pb_type->blif_model); 00489 00490 for(i = 0; i < pb_type->num_modes; i++) { 00491 for(j = 0; j < pb_type->modes[i].num_pb_type_children; j++) { 00492 free_pb_type(&pb_type->modes[i].pb_type_children[j]); 00493 } 00494 free(pb_type->modes[i].pb_type_children); 00495 free(pb_type->modes[i].name); 00496 for(j = 0; j < pb_type->modes[i].num_interconnect; j++) { 00497 free(pb_type->modes[i].interconnect[j].input_string); 00498 free(pb_type->modes[i].interconnect[j].output_string); 00499 free(pb_type->modes[i].interconnect[j].name); 00500 00501 for(k = 0; k < pb_type->modes[i].interconnect[j].num_annotations; k++) { 00502 if(pb_type->modes[i].interconnect[j].annotations[k].clock) 00503 free(pb_type->modes[i].interconnect[j].annotations[k].clock); 00504 if(pb_type->modes[i].interconnect[j].annotations[k].input_pins) { 00505 free(pb_type->modes[i].interconnect[j].annotations[k].input_pins); 00506 } 00507 if(pb_type->modes[i].interconnect[j].annotations[k].output_pins) { 00508 free(pb_type->modes[i].interconnect[j].annotations[k].output_pins); 00509 } 00510 for(m = 0; m < pb_type->modes[i].interconnect[j].annotations[k].num_value_prop_pairs; m++) { 00511 free(pb_type->modes[i].interconnect[j].annotations[k].value[m]); 00512 } 00513 free(pb_type->modes[i].interconnect[j].annotations[k].prop); 00514 free(pb_type->modes[i].interconnect[j].annotations[k].value); 00515 } 00516 free(pb_type->modes[i].interconnect[j].annotations); 00517 } 00518 if(pb_type->modes[i].interconnect) 00519 free(pb_type->modes[i].interconnect); 00520 } 00521 if(pb_type->modes) 00522 free(pb_type->modes); 00523 00524 for(i = 0; i < pb_type->num_annotations; i++) { 00525 for(j = 0; j < pb_type->annotations[i].num_value_prop_pairs; j++) { 00526 free(pb_type->annotations[i].value[j]); 00527 } 00528 free(pb_type->annotations[i].value); 00529 free(pb_type->annotations[i].prop); 00530 if(pb_type->annotations[i].input_pins) { 00531 free(pb_type->annotations[i].input_pins); 00532 } 00533 if(pb_type->annotations[i].output_pins) { 00534 free(pb_type->annotations[i].output_pins); 00535 } 00536 if(pb_type->annotations[i].clock) { 00537 free(pb_type->annotations[i].clock); 00538 } 00539 } 00540 if(pb_type->num_annotations > 0) { 00541 free(pb_type->annotations); 00542 } 00543 00544 vptr = pb_type->models_contained; 00545 while(vptr) { 00546 prev = vptr; 00547 vptr = vptr->next; 00548 free(prev); 00549 } 00550 00551 for(i = 0; i < pb_type->num_ports; i++) { 00552 free(pb_type->ports[i].name); 00553 if(pb_type->ports[i].port_class) { 00554 free(pb_type->ports[i].port_class); 00555 } 00556 } 00557 free(pb_type->ports); 00558 } 00559 00560 00561 /** This is a modification of the init_arch function to use Arch as param. 00562 * - Sets globals: nx, ny 00563 * - Allocs globals: chan_width_x, chan_width_y, grid 00564 * - Depends on num_clbs, pins_per_clb 00565 */ 00566 static void 00567 InitArch(INP t_arch Arch) 00568 { 00569 int *num_instances_type, *num_blocks_type; 00570 int i; 00571 int current, high, low; 00572 boolean fit; 00573 00574 current = nint(sqrt(num_blocks)); /* current is the value of the smaller side of the FPGA */ 00575 low = 1; 00576 high = -1; 00577 00578 num_instances_type = my_calloc(num_types, sizeof(int)); 00579 num_blocks_type = my_calloc(num_types, sizeof(int)); 00580 00581 for(i = 0; i < num_blocks; i++) 00582 { 00583 num_blocks_type[block[i].type->index]++; 00584 } 00585 00586 if(Arch.clb_grid.IsAuto) 00587 { 00588 /* Auto-size FPGA, perform a binary search */ 00589 while(high == -1 || low < high) 00590 { 00591 /* Generate grid */ 00592 if(Arch.clb_grid.Aspect >= 1.0) 00593 { 00594 ny = current; 00595 nx = nint(current * Arch.clb_grid.Aspect); 00596 } 00597 else 00598 { 00599 nx = current; 00600 ny = nint(current / Arch.clb_grid.Aspect); 00601 } 00602 #if DEBUG 00603 printf("Auto-sizing FPGA, try x = %d y = %d\n", nx, ny); 00604 #endif 00605 alloc_and_load_grid(num_instances_type); 00606 freeGrid(); 00607 00608 /* Test if netlist fits in grid */ 00609 fit = TRUE; 00610 for(i = 0; i < num_types; i++) 00611 { 00612 if(num_blocks_type[i] > num_instances_type[i]) 00613 { 00614 fit = FALSE; 00615 break; 00616 } 00617 } 00618 00619 /* get next value */ 00620 if(!fit) 00621 { 00622 /* increase size of max */ 00623 if(high == -1) 00624 { 00625 current = current * 2; 00626 if(current > MAX_SHORT) 00627 { 00628 printf(ERRTAG 00629 "FPGA required is too large for current architecture settings\n"); 00630 exit(1); 00631 } 00632 } 00633 else 00634 { 00635 if(low == current) 00636 current++; 00637 low = current; 00638 current = low + ((high - low) / 2); 00639 } 00640 } 00641 else 00642 { 00643 high = current; 00644 current = low + ((high - low) / 2); 00645 } 00646 } 00647 /* Generate grid */ 00648 if(Arch.clb_grid.Aspect >= 1.0) 00649 { 00650 ny = current; 00651 nx = nint(current * Arch.clb_grid.Aspect); 00652 } 00653 else 00654 { 00655 nx = current; 00656 ny = nint(current / Arch.clb_grid.Aspect); 00657 } 00658 alloc_and_load_grid(num_instances_type); 00659 printf("FPGA auto-sized to, x = %d y = %d\n", nx, ny); 00660 } 00661 else 00662 { 00663 nx = Arch.clb_grid.W; 00664 ny = Arch.clb_grid.H; 00665 alloc_and_load_grid(num_instances_type); 00666 } 00667 00668 printf("The circuit will be mapped into a %d x %d array of clbs.\n", 00669 nx, ny); 00670 00671 /* Test if netlist fits in grid */ 00672 fit = TRUE; 00673 for(i = 0; i < num_types; i++) 00674 { 00675 if(num_blocks_type[i] > num_instances_type[i]) 00676 { 00677 fit = FALSE; 00678 break; 00679 } 00680 } 00681 if(!fit) 00682 { 00683 printf(ERRTAG "Not enough physical locations for type %s, " 00684 "number of blocks is %d but number of locations is %d\n", 00685 type_descriptors[i].name, num_blocks_type[i], num_instances_type[i]); 00686 exit(1); 00687 } 00688 00689 printf("\nResource Usage:\n"); 00690 for(i = 0; i < num_types; i++) 00691 { 00692 printf("Netlist %d\tblocks of type %s\n", 00693 num_blocks_type[i], type_descriptors[i].name); 00694 printf("Architecture %d\tblocks of type %s\n", 00695 num_instances_type[i], type_descriptors[i].name); 00696 } 00697 printf("\n"); 00698 chan_width_x = (int *)my_malloc((ny + 1) * sizeof(int)); 00699 chan_width_y = (int *)my_malloc((nx + 1) * sizeof(int)); 00700 00701 free(num_blocks_type); 00702 free(num_instances_type); 00703 } 00704 00705 00706 00707 static void freeOptions(t_options *options) { 00708 free(options->ArchFile); 00709 free(options->CircuitName); 00710 if(options->BlifFile) 00711 free(options->BlifFile); 00712 if(options->NetFile) 00713 free(options->NetFile); 00714 if(options->PlaceFile) 00715 free(options->PlaceFile); 00716 if(options->RouteFile) 00717 free(options->RouteFile); 00718 if(options->OutFilePrefix) 00719 free(options->OutFilePrefix); 00720 if(options->PinFile) 00721 free(options->PinFile); 00722 } 00723 00724