VPR-6.0

vpr/SRC/pack/pack.c

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <assert.h>
00003 #include <string.h>
00004 #include "util.h"
00005 #include "vpr_types.h"
00006 #include "globals.h"
00007 #include "pack.h"
00008 #include "read_blif.h"
00009 #include "ff_pack.h"
00010 #include "cluster.h"
00011 #include "output_clustering.h"
00012 #include "read_xml_arch_file.h"
00013 
00014 /* #define DUMP_PB_GRAPH 1 */
00015 /* #define DUMP_BLIF_INPUT 1 */
00016 
00017 static void unclustered_stats (int max_lut_size);
00018 
00019 void try_pack(INP struct s_packer_opts *packer_opts, INP const t_arch * arch, INP t_model *user_models, INP t_model *library_models) {
00020         boolean *is_clock;
00021         int num_models;
00022         t_model *cur_model;
00023 
00024         printf("Begin packing of %s \n", packer_opts->blif_file_name);
00025 
00026         /* determine number of models in the architecture */
00027         num_models = 0;
00028         cur_model = user_models;
00029         while(cur_model) {
00030                 num_models++;
00031                 cur_model = cur_model->next;
00032         }
00033         cur_model = library_models;
00034         while(cur_model) {
00035                 num_models++;
00036                 cur_model = cur_model->next;
00037         }
00038 
00039         /* begin parsing blif input file */
00040         read_blif (packer_opts->blif_file_name, 
00041                                 packer_opts->sweep_hanging_nets_and_inputs,
00042                                 user_models,
00043                                 library_models);
00044 /* TODO: Do check blif here 
00045 eg. 
00046  for(i = 0; i < num_logical_blocks; i++) {
00047          if(logical_block[i].model->num_inputs > max_subblock_inputs) {
00048                  printf(ERRTAG "logical_block %s of model %s has %d inputs but architecture only supports subblocks up to %d inputs\n",
00049                          logical_block[i].name, logical_block[i].model->name, logical_block[i].model->num_inputs, max_subblock_inputs);
00050                  exit(1);
00051          }
00052  }
00053 
00054 
00055 */
00056 #ifdef DUMP_BLIF_INPUT
00057         echo_input (packer_opts->blif_file_name, "blif_input.echo", library_models);
00058 #endif
00059 
00060         absorb_buffer_luts ();
00061         compress_netlist (); /* remove unused inputs */
00062         /* NB:  It's important to mark clocks and such *after* compressing the   *
00063         * netlist because the vpack_net numbers, etc. may be changed by removing      *
00064         * unused inputs .                                      */
00065 
00066         is_clock = alloc_and_load_is_clock (packer_opts->global_clocks);
00067 
00068         printf("\nAfter removing unused inputs:\n");
00069         printf("Total Blocks: %d.  Total Nets: %d.  Total inputs %d ouptuts %d\n", num_logical_blocks, num_logical_nets, 
00070            num_p_inputs, num_p_outputs);
00071 
00072 
00073         /* Uncomment line below if you want a dump of compressed netlist. */
00074         /* echo_input (packer_opts->blif_file_name, packer_opts->lut_size, "packed.echo"); */
00075 
00076         if (packer_opts->skip_clustering == FALSE) {
00077                 do_clustering (arch,
00078                                         num_models,
00079                                         packer_opts->global_clocks, 
00080                                         is_clock, 
00081                                         packer_opts->hill_climbing_flag,
00082                                         packer_opts->output_file, 
00083                                         packer_opts->timing_driven, 
00084                                         packer_opts->cluster_seed_type, 
00085                                         packer_opts->alpha, 
00086                                         packer_opts->beta,
00087                                         packer_opts->recompute_timing_after, 
00088                                         packer_opts->block_delay, 
00089                                         packer_opts->intra_cluster_net_delay, 
00090                                         packer_opts->inter_cluster_net_delay, 
00091                                         packer_opts->aspect,
00092                                         packer_opts->allow_unrelated_clustering, 
00093                                         packer_opts->allow_early_exit, 
00094                                         packer_opts->connection_driven,
00095                                         packer_opts->packer_algorithm,
00096                                         packer_opts->hack_no_legal_frac_lut,
00097                                         packer_opts->hack_safe_latch);
00098         }
00099         else {
00100                 printf("Skip clustering not supported\n");
00101                 exit(1);
00102         }
00103 
00104         free (is_clock);
00105 
00106         saved_logical_blocks = logical_block;
00107         logical_block = NULL;
00108         num_saved_logical_blocks = num_logical_blocks;
00109         saved_logical_nets = vpack_net;
00110         vpack_net = NULL;
00111         num_saved_logical_nets = num_logical_nets; /* Todo: Use this for error checking */
00112         
00113         printf("\nNetlist conversion complete.\n\n");
00114 }
00115 
00116 /** Dumps out statistics on an unclustered netlist -- i.e. it is just 
00117  * packed into VPACK_LUT + FF logic blocks, but not local routing from     
00118  * output to input etc. is assumed.                                  
00119  */
00120 void unclustered_stats (int max_lut_size) {
00121 
00122         assert(0);
00123 #if 0
00124  int iblk, num_logic_blocks, num_subckts;
00125  int min_inputs_used, min_clocks_used;
00126  int max_inputs_used, max_clocks_used;
00127  int summ_inputs_used, summ_clocks_used;
00128  int inputs_used, clocks_used;
00129 
00130  printf("\nUnclustered Netlist Statistics:\n\n");
00131  num_logic_blocks = num_logical_blocks - num_p_inputs - num_p_outputs;
00132  printf("%d Logic Blocks.\n", num_logic_blocks);
00133 
00134  min_inputs_used = max_lut_size+1;
00135  min_clocks_used = 2;
00136  max_inputs_used = -1;
00137  max_clocks_used = -1;
00138  summ_inputs_used = 0;
00139  summ_clocks_used = 0;
00140  num_subckts = 0;
00141 
00142  for (iblk=0;iblk<num_logical_blocks;iblk++) {
00143          if (strcmp(logical_block[iblk].model->name, MODEL_LOGIC) == 0 || 
00144                  strcmp(logical_block[iblk].model->name, MODEL_LATCH) == 0) {
00145            assert(logical_block[iblk].type == VPACK_COMB || logical_block[iblk].type != VPACK_LATCH);
00146        inputs_used = logical_block[iblk].num_input_nets;
00147            if (logical_block[iblk].clock_net != OPEN)
00148           clocks_used = 1;
00149        else 
00150           clocks_used = 0;
00151 
00152        min_inputs_used = min (min_inputs_used, inputs_used);
00153        max_inputs_used = max (max_inputs_used, inputs_used);
00154        summ_inputs_used += inputs_used;
00155 
00156        min_clocks_used = min (min_clocks_used, clocks_used);
00157        max_clocks_used = max (max_clocks_used, clocks_used);
00158        summ_clocks_used += clocks_used;
00159     }
00160          else if (strcmp(logical_block[iblk].model->name, MODEL_INPUT) != 0 &&
00161                           strcmp(logical_block[iblk].model->name, MODEL_OUTPUT) != 0 ) {
00162                 assert(logical_block[iblk].type == VPACK_COMB);
00163                 num_subckts++;
00164         }
00165  }
00166 
00167  printf("\n\t\t\tAverage\t\tMin\tMax\n");
00168  printf("Logic Blocks / Cluster\t%f\t%d\t%d\n", 1., 1, 1);
00169  printf("Used Inputs / Cluster\t%f\t%d\t%d\n", (float) summ_inputs_used /
00170         (float) num_logic_blocks, min_inputs_used, max_inputs_used);
00171  printf("Used Clocks / Cluster\t%f\t%d\t%d\n", (float) summ_clocks_used /
00172         (float) num_logic_blocks, min_clocks_used, max_clocks_used);
00173  printf("Subcircuits in design \t%d\n", num_subckts);
00174  printf("\n");
00175 #endif
00176 }
00177