blob: 978fff41b85928c818c98b5b27e7523218b73b79 [file] [log] [blame]
#include "vtr_log.h"
#include "vpr_types.h"
#include "vpr_error.h"
#include "globals.h"
#include "echo_files.h"
#include "read_xml_arch_file.h"
#include "CheckSetup.h"
void CheckSetup(const t_packer_opts& PackerOpts,
const t_placer_opts& PlacerOpts,
const t_router_opts& RouterOpts,
const t_det_routing_arch& RoutingArch,
const std::vector<t_segment_inf>& Segments,
const t_timing_inf Timing,
const t_chan_width_dist Chans) {
int i;
int Tmp;
if (!Timing.timing_analysis_enabled && PackerOpts.timing_driven) {
VPR_FATAL_ERROR(VPR_ERROR_OTHER,
"Packing cannot be timing driven without timing analysis enabled\n");
}
if ((GLOBAL == RouterOpts.route_type)
&& (BOUNDING_BOX_PLACE != PlacerOpts.place_algorithm)) {
/* Works, but very weird. Can't optimize timing well, since you're
* not doing proper architecture delay modelling. */
VTR_LOG_WARN(
"Using global routing with timing-driven placement. "
"This is allowed, but strange, and circuit speed will suffer.\n");
}
if ((false == Timing.timing_analysis_enabled)
&& (PlacerOpts.place_algorithm == PATH_TIMING_DRIVEN_PLACE)) {
/* May work, not tested */
VPR_FATAL_ERROR(VPR_ERROR_OTHER,
"Timing analysis must be enabled for timing-driven placement.\n");
}
if (!PlacerOpts.doPlacement && (USER == PlacerOpts.pad_loc_type)) {
VPR_FATAL_ERROR(VPR_ERROR_OTHER,
"A pad location file requires that placement is enabled.\n");
}
if (RouterOpts.doRouting) {
if (!Timing.timing_analysis_enabled
&& (DEMAND_ONLY != RouterOpts.base_cost_type && DEMAND_ONLY_NORMALIZED_LENGTH != RouterOpts.base_cost_type)) {
VPR_FATAL_ERROR(VPR_ERROR_OTHER,
"base_cost_type must be demand_only or demand_only_normailzed_length when timing analysis is disabled.\n");
}
}
if (DETAILED == RouterOpts.route_type) {
if ((Chans.chan_x_dist.type != UNIFORM)
|| (Chans.chan_y_dist.type != UNIFORM)
|| (Chans.chan_x_dist.peak != Chans.chan_y_dist.peak)) {
VPR_FATAL_ERROR(VPR_ERROR_OTHER,
"Detailed routing currently only supported on FPGAs with all channels of equal width.\n");
}
}
for (i = 0; i < (int)Segments.size(); ++i) {
Tmp = Segments[i].arch_opin_switch;
auto& device_ctx = g_vpr_ctx.device();
if (false == device_ctx.arch_switch_inf[Tmp].buffered()) {
VPR_FATAL_ERROR(VPR_ERROR_OTHER,
"arch_opin_switch (#%d) of segment type #%d is not buffered.\n", Tmp, i);
}
}
if ((PlacerOpts.place_chan_width != NO_FIXED_CHANNEL_WIDTH) && PlacerOpts.place_chan_width < 0) {
VPR_FATAL_ERROR(VPR_ERROR_OTHER,
"Place channel width must be positive.\n");
}
if ((RouterOpts.fixed_channel_width != NO_FIXED_CHANNEL_WIDTH) && RouterOpts.fixed_channel_width < 0) {
VPR_FATAL_ERROR(VPR_ERROR_OTHER,
"Routing channel width must be positive.\n");
}
if (UNI_DIRECTIONAL == RoutingArch.directionality) {
if ((RouterOpts.fixed_channel_width != NO_FIXED_CHANNEL_WIDTH)
&& (RouterOpts.fixed_channel_width % 2 > 0)) {
VPR_FATAL_ERROR(VPR_ERROR_OTHER,
"Routing channel width must be even for unidirectional.\n");
}
if ((PlacerOpts.place_chan_width != NO_FIXED_CHANNEL_WIDTH)
&& (PlacerOpts.place_chan_width % 2 > 0)) {
VPR_FATAL_ERROR(VPR_ERROR_OTHER,
"Place channel width must be even for unidirectional.\n");
}
}
}