⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 用c++写的用于FPGA设计中布图布线的工具源码
💻 C
📖 第 1 页 / 共 3 页
字号:
       if (router_opts->fixed_channel_width >= MAX_CHANNEL_WIDTH) {	printf ("Error:  -router_chan_width value must be less than %d."		"\n", MAX_CHANNEL_WIDTH);	exit (1);      }       i += 2;      continue;    }      if (strcmp(argv[i],"-route_only") == 0) {      if (*operation == PLACE_ONLY) {	printf("Error:  Both -route_only and -place_only specified.\n");	exit (1);      }      *operation = ROUTE_ONLY;      placer_opts->place_freq = PLACE_NEVER;      i++;      continue;    }    if (strcmp(argv[i],"-place_only") == 0) {      if (*operation == ROUTE_ONLY) {	printf("Error:  Both -route_only and -place_only specified.\n");	exit (1);      }      *operation = PLACE_ONLY;      i++;      continue;    }    if (strcmp(argv[i],"-verify_binary_search") == 0) {      *verify_binary_search = TRUE;      i++;      continue;    }    printf("Error:  Unrecognized flag: %s.  Aborting.\n",argv[i]);    exit(1);  }   /* End of giant while loop. */  /* Check for illegal options combinations. */  if (placer_opts->place_cost_type == NONLINEAR_CONG && *operation !=      PLACE_AND_ROUTE && do_one_nonlinear_place == FALSE) {    printf("Error:  Replacing using the nonlinear congestion option\n");    printf("        for each channel width makes sense only for full "	   "place and route.\n");    exit (1);  }  if (placer_opts->place_cost_type == NONLINEAR_CONG &&       (placer_opts->place_algorithm == NET_TIMING_DRIVEN_PLACE ||       placer_opts->place_algorithm == PATH_TIMING_DRIVEN_PLACE)) {    /*note that this may work together, but I have not tested it */    printf("Error: Cannot use nonlinear placement with \n"	   "      timing driven placement\n");    exit(1);  }  if (router_opts->route_type == GLOBAL &&      (placer_opts->place_algorithm == NET_TIMING_DRIVEN_PLACE ||       placer_opts->place_algorithm == PATH_TIMING_DRIVEN_PLACE)) {    /* Works, but very weird.  Can't optimize timing well, since you're     * not doing proper architecture delay modelling.     */    printf("Warning: Using global routing with timing-driven placement.\n");    printf("\tThis is allowed, but strange, and circuit speed will suffer.\n");  }    if ( *timing_analysis_enabled == FALSE  &&     (placer_opts->place_algorithm == NET_TIMING_DRIVEN_PLACE ||      placer_opts->place_algorithm == PATH_TIMING_DRIVEN_PLACE)) {       /*may work, not tested*/      printf("Error: timing analysis must be enabled for timing-driven placement\n");      exit (1);  }  if (*operation == ROUTE_ONLY && placer_opts->pad_loc_type == USER) {    printf ("Error:  You cannot specify both a full placement file and \n");    printf ("        a pad location file.\n");    exit (1);  }  if (router_opts->fixed_channel_width != NO_FIXED_CHANNEL_WIDTH &&      *verify_binary_search) {    printf ("Error:  Routing on a fixed channel width (%d tracks) "	    "specified.\n", router_opts->fixed_channel_width);    printf ("        There is no binary search to verify, so you \n"	    "        cannot specify -verify_binary_search option.\n");    exit (1);  }  if (*operation == ROUTE_ONLY || *operation == PLACE_AND_ROUTE) {    if (router_opts->router_algorithm == TIMING_DRIVEN && 	*timing_analysis_enabled == FALSE) {      printf ("Error:  Cannot perform timing-driven routing when timing "	      "analysis is disabled.\n");      exit (1);    }    if (*timing_analysis_enabled == FALSE && router_opts->base_cost_type 	!= DEMAND_ONLY) {      printf ("Error:  base_cost_type must be demand_only when timing "	      "analysis is disabled.\n");      exit (1);    }  }  if (*operation == TIMING_ANALYSIS_ONLY && *timing_analysis_enabled ==       FALSE) {    printf ("Error:  -timing_analyze_only_with_net_delay option requires\n"	    "\tthat timing analysis not be disabled.\n");    exit (1);  }  /* Now echo back the options the user has selected. */  printf("\nGeneral Options:\n");  if (*aspect_ratio != 1.) {    printf("\tFPGA will have a width/length ratio of %g.\n", 	   *aspect_ratio);  }  if (*user_sized == TRUE) {    printf("\tThe FPGA size has been specified by the user.\n");    /* If one of nx or ny was unspecified, compute it from the other and  *     * the aspect ratio.  If both are unspecified, wait till the netlist  *     * is read and compute the smallest possible nx and ny in read_arch.  */    if (ny == 0) {         ny = (float) nx / (float) *aspect_ratio;    }    else if (nx == 0) {      nx = ny *  *aspect_ratio;    }    else if (*aspect_ratio != 1 && *aspect_ratio != nx / ny) {      printf("\nError:  User-specified size and aspect ratio do\n");      printf("not match.  Note that aspect ratio does not have to\n");      printf("be specified if both nx and ny are specified.\n");      exit (1);    }  }  if (*full_stats == TRUE) {    printf("\tA full statistical report will be printed.\n");  }  if (*operation == ROUTE_ONLY) {    printf ("\tRouting will be performed on an existing placement.\n");  } else if (*operation == PLACE_ONLY) {    printf ("\tThe circuit will be placed but not routed.\n");  } else if (*operation == PLACE_AND_ROUTE) {    printf ("\tThe circuit will be placed and routed.\n");  } else if (*operation == TIMING_ANALYSIS_ONLY) {    printf ("\tOnly timing analysis (assuming a constant net delay) will "	    "be performed.\n");  }  if (*operation == PLACE_ONLY || *operation == PLACE_AND_ROUTE) {    printf("\nPlacer Options:\n");    if (placer_opts->place_algorithm == NET_TIMING_DRIVEN_PLACE)      printf("\tPlacement algorithm is net_timing_driven\n");    if (placer_opts->place_algorithm == PATH_TIMING_DRIVEN_PLACE)      printf("\tPlacement algorithm is path_timing_driven\n");    if (placer_opts->place_algorithm == NET_TIMING_DRIVEN_PLACE ||	placer_opts->place_algorithm == PATH_TIMING_DRIVEN_PLACE) {      printf("\tTradeoff between bounding box and critical path: %g\n",placer_opts->timing_tradeoff);      printf("\tLower bound assumes block distance: %d\n",placer_opts->block_dist);      printf("\tRecomputing criticalities every %d temperature changes\n",	     placer_opts->recompute_crit_iter);      printf("\tInner loop computes criticalities every move_lim/%d moves\n",	     placer_opts->inner_loop_recompute_divider);            printf("\tExponent starting value used in timing-driven cost function is %g\n",	     placer_opts->td_place_exp_first);      printf("\tExponent final value used in timing-driven cost function is %g\n",	     placer_opts->td_place_exp_last);    }    else if (placer_opts->place_algorithm == BOUNDING_BOX_PLACE) {      printf("\tPlacement algorithm is bounding_box\n");      if (placer_opts->enable_timing_computations) {         printf("\tPlacement algorithm will generate timing estimates\n"	    "\t(estimates do not affect the placement in bounding_box mode)\n");      }    }    if (annealing_sched->type == AUTO_SCHED) {      printf("\tAutomatic annealing schedule selected.\n");      printf("\tNumber of moves in the inner loop is (num_blocks)^4/3 "	     "* %g\n", annealing_sched->inner_num);    }    else {      printf("\tUser annealing schedule selected with:\n");      printf("\tInitial Temperature: %g\n",annealing_sched->init_t);      printf("\tExit (Final) Temperature: %g\n",annealing_sched->exit_t);      printf("\tTemperature Reduction factor (alpha_t): %g\n",	     annealing_sched->alpha_t);      printf("\tNumber of moves in the inner loop is (num_blocks)^4/3 * "	     "%g\n", annealing_sched->inner_num);    }          if (placer_opts->place_cost_type == NONLINEAR_CONG) {      printf("\tPlacement cost type is nonlinear congestion.\n");      printf("\tCongestion will be determined on a %d x %d array.\n",	     placer_opts->num_regions, placer_opts->num_regions);      if (do_one_nonlinear_place == TRUE) {	placer_opts->place_freq = PLACE_ONCE;	printf("\tPlacement will be performed once.\n");	printf("\tPlacement channel width factor = %d.\n",	       placer_opts->place_chan_width);      }      else {	placer_opts->place_freq = PLACE_ALWAYS;	printf("\tCircuit will be replaced for each channel width "	       "attempted.\n");      }    }    else if (placer_opts->place_cost_type == LINEAR_CONG) {      placer_opts->place_freq = PLACE_ONCE;      printf("\tPlacement cost type is linear congestion.\n");      printf("\tPlacement will be performed once.\n");      printf("\tPlacement channel width factor = %d.\n",	     placer_opts->place_chan_width);      printf("\tExponent used in placement cost: %g\n",	     placer_opts->place_cost_exp);    }       if (placer_opts->pad_loc_type == RANDOM) {      printf("\tPlacer will fix the IO pins in a random configuration.\n");    }    else if (placer_opts->pad_loc_type == USER) {      printf ("\tPlacer will fix the IO pins as specified by file %s.\n",	      placer_opts->pad_loc_file);    }    /* The default bend_cost for DETAILED routing is 0, while the default for *     * GLOBAL routing is 1.                                                   */    if (bend_cost_set == FALSE && router_opts->route_type == DETAILED)       router_opts->bend_cost = 0.; /*needed when computing  placement lookup matricies*/    /* Default base_cost_type is DELAY_NORMALIZED for timing_driven routing */    if (!base_cost_type_set && router_opts->router_algorithm == TIMING_DRIVEN)      router_opts->base_cost_type = DELAY_NORMALIZED; /*needed when computing  placement lookup matricies*/    printf("\tInitial random seed: %d\n", seed);    my_srandom(seed);  }   /* End of echo placement options. */  if (*operation == ROUTE_ONLY || *operation == PLACE_AND_ROUTE) {    printf("\nRouting Options:\n");    if (router_opts->route_type == GLOBAL)       printf("\tOnly GLOBAL routing will be performed.\n");    else       printf("\tCombined GLOBAL + DETAILED routing will be performed.\n");    if (router_opts->router_algorithm == BREADTH_FIRST)       printf ("\tRouter algorithm:  breadth first.\n");    else      printf ("\tRouter algorithm:  timing driven.\n");    printf("\tThe router will try at most %d iterations.\n",	   router_opts->max_router_iterations);    printf("\tRoutings can go at most %d channels outside their "	   "bounding box.\n", router_opts->bb_factor);    /* The default bend_cost for DETAILED routing is 0, while the default for *     * GLOBAL routing is 1.                                                   */    if (bend_cost_set == FALSE && router_opts->route_type == DETAILED)       router_opts->bend_cost = 0.;    printf("\tCost of a bend (bend_cost) is %g.\n", router_opts->bend_cost);    printf("\tFirst iteration sharing penalty factor (first_iter_pres_fac):"	   " %g\n", router_opts->first_iter_pres_fac);    printf("\tInitial (2nd iter.) sharing penalty factor (initial_pres_fac):"	   " %g\n", router_opts->initial_pres_fac);    printf("\tSharing penalty growth factor (pres_fac_mult): %g\n",	   router_opts->pres_fac_mult);    printf("\tAccumulated sharing penalty factor (acc_fac): %g\n", 	   router_opts->acc_fac);    /* Default base_cost_type is DELAY_NORMALIZED for timing_driven routing */    if (!base_cost_type_set && router_opts->router_algorithm == TIMING_DRIVEN)      router_opts->base_cost_type = DELAY_NORMALIZED;    printf ("\tBase_cost_type:  ");    if (router_opts->base_cost_type == INTRINSIC_DELAY)       printf ("intrinsic delay.\n");    else if (router_opts->base_cost_type == DELAY_NORMALIZED)       printf ("delay normalized.\n");    else if (router_opts->base_cost_type == DEMAND_ONLY)       printf ("demand only.\n");          if (router_opts->router_algorithm == TIMING_DRIVEN) {      printf ("\tSearch aggressiveness factor (astar_fac): %g\n", 	      router_opts->astar_fac);      printf ("\tMaximum sink criticality (max_criticality): %g\n",	      router_opts->max_criticality);      printf ("\tExponent for criticality computation (criticality_exp): "	      "%g\n", router_opts->criticality_exp);    }           if (router_opts->fixed_channel_width == NO_FIXED_CHANNEL_WIDTH) {      printf ("\tRouter will find the minimum number of tracks "	      "required to route.\n");    }      else {      printf ("\tRouter will attempt routing only with a channel width"	      " factor of %d.\n", router_opts->fixed_channel_width);    }      if (*verify_binary_search) {      /* Router will ensure routings with 1, 2, and 3 tracks fewer than the *       * best found by the binary search will not succeed.  Normally only   *       * verify that best - 1 tracks does not succeed.                      */      printf("\tRouter will verify that binary search yields min. "	     "channel width.\n");    }  }  /* End of echo router options. */     if (*operation == TIMING_ANALYSIS_ONLY) {    printf ("\tNet delay value for timing analysis: %g (s)\n", 	    *constant_net_delay);  }  printf("\n");}static void get_input (char *net_file, char *arch_file, int place_cost_type,		       int num_regions, float aspect_ratio, boolean user_sized,		       enum e_route_type route_type, struct s_det_routing_arch 		       *det_routing_arch, t_segment_inf **segment_inf_ptr,		       t_timing_inf *timing_inf_ptr, t_subblock_data *subblock_data_ptr,		       t_chan_width_dist *chan_width_dist_ptr) {  /* This subroutine reads in the netlist and architecture files, initializes * * some data structures and does any error checks that require knowledge of * * both the algorithms to be used and the FPGA architecture.                */  printf("Reading the FPGA architectural description from %s.\n", 	 arch_file);   read_arch (arch_file, route_type, det_routing_arch, segment_inf_ptr,	     timing_inf_ptr, subblock_data_ptr, chan_width_dist_ptr);  printf("Successfully read %s.\n",arch_file);  printf("Pins per clb: %d.  Pads per row/column: %d.\n", pins_per_clb, io_rat);  printf("Subblocks per clb: %d.  Subblock LUT size: %d.\n", 	 subblock_data_ptr->max_subblocks_per_block, 	 subblock_data_ptr->subblock_lut_size);  if (route_type == DETAILED) {    if (det_routing_arch->Fc_type == ABSOLUTE)       printf("Fc value is absolute number of tracks.\n");     else       printf("Fc value is fraction of tracks in a channel.\n");         printf("Fc_output: %g.  Fc_input: %g.  Fc_pad: %g.\n",            det_routing_arch->Fc_output, det_routing_arch->Fc_input,           det_routing_arch->Fc_pad);    if (det_routing_arch->switch_block_type == SUBSET)      printf("Switch block type: Subset.\n");    else if (det_routing_arch->switch_block_type == WILTON)       printf("Switch_block_type: WILTON.\n");    else       printf ("Switch_block_type: UNIVERSAL.\n");     printf ("Distinct types of segments: %d.\n",             det_routing_arch->num_segment);    printf ("Distinct types of user-specified switches: %d.\n",             det_routing_arch->num_switch - 2);  }  printf ("\n");  printf("Reading the circuit netlist from %s.\n",net_file);  read_net (net_file, subblock_data_ptr);  printf("Successfully read %s.\n", net_file);  printf("%d blocks, %d nets, %d global nets.\n", num_blocks, num_nets, 	 num_globals);  printf("%d clbs, %d inputs, %d outputs.\n", num_clbs, num_p_inputs,	 num_p_outputs);  /* Set up some physical FPGA data structures that need to   * *  know num_blocks.                                        */  init_arch(aspect_ratio, user_sized);  printf("The circuit will be mapped into a %d x %d array of clbs.\n\n",	 nx, ny);  if (place_cost_type == NONLINEAR_CONG && (num_regions > nx ||					    num_regions > ny)) {    printf("Error:  Cannot use more regions than clbs in placement cost "	   "function.\n");    exit(1);  } }static int read_int_option (int argc, char *argv[], int iarg) {  /* This routine returns the value in argv[iarg+1].  This value must exist *   * and be an integer, or an error message is printed and the program      *   * exits.                                                                 */  int value, num_read;  num_read = 0;  /* Does value exist for this option? */  if (argc > iarg+1)               num_read = sscanf(argv[iarg+1],"%d",&value);  /* Value exists and was a proper int? */  if (num_read != 1) {           printf("Error:  %s option requires an integer parameter.\n\n", argv[iarg]);    exit(1);  }  return (value);}static float read_float_option (int argc, char *argv[], int iarg) {   /* This routine returns the value in argv[iarg+1].  This value must exist *    * and be a float, or an error message is printed and the program exits.  */    int num_read;   float value;   num_read = 0;      /* Does value exist for this option? */   if (argc > iarg+1)               num_read = sscanf(argv[iarg+1],"%f",&value);   /* Value exists and was a proper float? */   if (num_read != 1) {           printf("Error:  %s option requires a float parameter.\n\n", argv[iarg]);    exit(1);  }   return (value); } 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -