VPR-6.0

vpr/SRC/main.c

Go to the documentation of this file.
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