VPR-6.0
|
00001 #include "util.h" 00002 #include "vpr_types.h" 00003 #include "globals.h" 00004 #include "OptionTokens.h" 00005 #include "ReadOptions.h" 00006 #include "read_xml_arch_file.h" 00007 #include "SetupVPR.h" 00008 00009 00010 void 00011 CheckSetup(INP enum e_operation Operation, 00012 INP struct s_placer_opts PlacerOpts, 00013 INP struct s_annealing_sched AnnealSched, 00014 INP struct s_router_opts RouterOpts, 00015 INP struct s_det_routing_arch RoutingArch, 00016 INP t_segment_inf * Segments, 00017 INP t_timing_inf Timing, 00018 INP t_chan_width_dist Chans) 00019 { 00020 int i; 00021 int Tmp; 00022 00023 if((NONLINEAR_CONG == PlacerOpts.place_cost_type) && 00024 (!PlacerOpts.doPlacement || !RouterOpts.doRouting) && 00025 (PLACE_ALWAYS == PlacerOpts.place_freq)) 00026 { 00027 printf(ERRTAG "Replacing using the nonlinear congestion option " 00028 "for each channel width makes sense only for full " 00029 "place and route.\n"); 00030 exit(1); 00031 } 00032 00033 if((NONLINEAR_CONG == PlacerOpts.place_cost_type) && 00034 (BOUNDING_BOX_PLACE != PlacerOpts.place_algorithm)) 00035 { 00036 00037 /* Note that this may work together, but I have not tested it */ 00038 printf(ERRTAG 00039 "Cannot use non-linear placement only supported with " 00040 "bounding box placement\n"); 00041 exit(1); 00042 } 00043 00044 if((GLOBAL == RouterOpts.route_type) && 00045 (TIMING_DRIVEN == RouterOpts.router_algorithm)) 00046 { 00047 00048 printf(ERRTAG "The global router does not support timing-drvien " 00049 "routing.\n"); 00050 exit(1); 00051 } 00052 00053 if((GLOBAL == RouterOpts.route_type) && 00054 (BOUNDING_BOX_PLACE != PlacerOpts.place_algorithm)) 00055 { 00056 00057 /* Works, but very weird. Can't optimize timing well, since you're 00058 * not doing proper architecture delay modelling. */ 00059 printf(WARNTAG 00060 "Using global routing with timing-driven placement. " 00061 "This is allowed, but strange, and circuit speed will suffer.\n"); 00062 } 00063 00064 if((FALSE == Timing.timing_analysis_enabled) && 00065 ((PlacerOpts.place_algorithm == NET_TIMING_DRIVEN_PLACE) || 00066 (PlacerOpts.place_algorithm == PATH_TIMING_DRIVEN_PLACE))) 00067 { 00068 00069 /* May work, not tested */ 00070 printf(ERRTAG 00071 "Timing analysis must be enabled for timing-driven placement\n"); 00072 exit(1); 00073 } 00074 00075 if(!PlacerOpts.doPlacement && (USER == PlacerOpts.pad_loc_type)) 00076 { 00077 printf(ERRTAG "A pad location file requires that placement is enabled.\n"); 00078 exit(1); 00079 } 00080 00081 if(RouterOpts.doRouting) 00082 { 00083 if((TIMING_DRIVEN == RouterOpts.router_algorithm) && 00084 (FALSE == Timing.timing_analysis_enabled)) 00085 { 00086 printf(ERRTAG 00087 "Cannot perform timing-driven routing when timing " 00088 "analysis is disabled.\n"); 00089 exit(1); 00090 } 00091 00092 if((FALSE == Timing.timing_analysis_enabled) && 00093 (DEMAND_ONLY != RouterOpts.base_cost_type)) 00094 { 00095 printf(ERRTAG 00096 "base_cost_type must be demand_only when timing " 00097 "analysis is disabled.\n"); 00098 exit(1); 00099 } 00100 } 00101 00102 if((TIMING_ANALYSIS_ONLY == Operation) && 00103 (FALSE == Timing.timing_analysis_enabled)) 00104 { 00105 printf(ERRTAG 00106 "-timing_analyze_only_with_net_delay option requires " 00107 "that timing analysis not be disabled.\n"); 00108 exit(1); 00109 } 00110 00111 if((NONLINEAR_CONG == PlacerOpts.place_cost_type) && 00112 ((PlacerOpts.num_regions > nx) || (PlacerOpts.num_regions > ny))) 00113 { 00114 printf(ERRTAG "Cannot use more regions than clbs in " 00115 "placement cost function.\n"); 00116 exit(1); 00117 } 00118 00119 if(DETAILED == RouterOpts.route_type) 00120 { 00121 if((Chans.chan_x_dist.type != UNIFORM) || 00122 (Chans.chan_y_dist.type != UNIFORM) || 00123 (Chans.chan_x_dist.peak != Chans.chan_y_dist.peak) || 00124 (Chans.chan_x_dist.peak != Chans.chan_width_io)) 00125 { 00126 printf(ERRTAG "Detailed routing currently only supported " 00127 "on FPGAs with all channels of equal width.\n"); 00128 exit(1); 00129 } 00130 } 00131 00132 for(i = 0; i < RoutingArch.num_segment; ++i) 00133 { 00134 Tmp = Segments[i].opin_switch; 00135 if(FALSE == switch_inf[Tmp].buffered) 00136 { 00137 printf(ERRTAG "opin_switch (#%d) of segment type #%d " 00138 "is not buffered.\n", Tmp, i); 00139 exit(1); 00140 } 00141 } 00142 00143 if(UNI_DIRECTIONAL == RoutingArch.directionality) 00144 { 00145 if((RouterOpts.fixed_channel_width != NO_FIXED_CHANNEL_WIDTH) && 00146 (RouterOpts.fixed_channel_width % 2 > 0)) 00147 { 00148 printf(ERRTAG 00149 "Routing channel width must be even for unidirectional\n"); 00150 exit(1); 00151 } 00152 if((PlacerOpts.place_chan_width != NO_FIXED_CHANNEL_WIDTH) && 00153 (PlacerOpts.place_chan_width % 2 > 0)) 00154 { 00155 printf(ERRTAG 00156 "Place channel width must be even for unidirectional\n"); 00157 exit(1); 00158 } 00159 } 00160 }