vpr: Add support for demand-based length scaled base costs
Previously specifying --timing_analysis off would switch the router to
use the basic DEMAND_ONLY base costs, and not the improved length-scaled
base costs. This lead to poor timing-driven router behaviour (higher WL,
longer runtime) when run with only a wirelength objective.
We now (by default) scale the base costs by length, regardless of whether
timing analysis is enabled or not.
diff --git a/vpr/src/base/CheckSetup.cpp b/vpr/src/base/CheckSetup.cpp
index bb42dc2..2dcfb6b 100644
--- a/vpr/src/base/CheckSetup.cpp
+++ b/vpr/src/base/CheckSetup.cpp
@@ -50,16 +50,10 @@
}
if (RouterOpts.doRouting) {
- if ((TIMING_DRIVEN == RouterOpts.router_algorithm)
- && (false == Timing.timing_analysis_enabled)) {
+ 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,
- "Cannot perform timing-driven routing when timing analysis is disabled.\n");
- }
-
- if ((false == Timing.timing_analysis_enabled)
- && (DEMAND_ONLY != RouterOpts.base_cost_type)) {
- VPR_FATAL_ERROR(VPR_ERROR_OTHER,
- "base_cost_type must be demand_only when timing analysis is disabled.\n");
+ "base_cost_type must be demand_only or demand_only_normailzed_length when timing analysis is disabled.\n");
}
}
diff --git a/vpr/src/base/ShowSetup.cpp b/vpr/src/base/ShowSetup.cpp
index f6ba4dd..3b6c374 100644
--- a/vpr/src/base/ShowSetup.cpp
+++ b/vpr/src/base/ShowSetup.cpp
@@ -185,9 +185,6 @@
case TIMING_DRIVEN:
VTR_LOG("TIMING_DRIVEN\n");
break;
- case NO_TIMING:
- VTR_LOG("NO_TIMING\n");
- break;
default:
VPR_FATAL_ERROR(VPR_ERROR_UNKNOWN, "<Unknown>\n");
}
@@ -209,6 +206,9 @@
case DEMAND_ONLY:
VTR_LOG("DEMAND_ONLY\n");
break;
+ case DEMAND_ONLY_NORMALIZED_LENGTH:
+ VTR_LOG("DEMAND_ONLY_NORMALIZED_LENGTH\n");
+ break;
default:
VPR_FATAL_ERROR(VPR_ERROR_UNKNOWN, "Unknown base_cost_type\n");
}
@@ -262,9 +262,6 @@
case TIMING_DRIVEN:
VTR_LOG("TIMING_DRIVEN\n");
break;
- case NO_TIMING:
- VTR_LOG("NO_TIMING\n");
- break;
default:
VTR_LOG_ERROR("Unknown router algorithm\n");
}
diff --git a/vpr/src/base/read_options.cpp b/vpr/src/base/read_options.cpp
index 6166ab1..1e60b57 100644
--- a/vpr/src/base/read_options.cpp
+++ b/vpr/src/base/read_options.cpp
@@ -241,6 +241,8 @@
conv_value.set_value(DELAY_NORMALIZED_FREQUENCY);
else if (str == "delay_normalized_length_frequency")
conv_value.set_value(DELAY_NORMALIZED_LENGTH_FREQUENCY);
+ else if (str == "demand_only_normalized_length")
+ conv_value.set_value(DEMAND_ONLY_NORMALIZED_LENGTH);
else if (str == "demand_only")
conv_value.set_value(DEMAND_ONLY);
else {
@@ -261,6 +263,8 @@
conv_value.set_value("delay_normalized_frequency");
else if (val == DELAY_NORMALIZED_LENGTH_FREQUENCY)
conv_value.set_value("delay_normalized_length_frequency");
+ else if (val == DEMAND_ONLY_NORMALIZED_LENGTH)
+ conv_value.set_value("demand_only_normalized_length");
else {
VTR_ASSERT(val == DEMAND_ONLY);
conv_value.set_value("demand_only");
@@ -269,7 +273,7 @@
}
std::vector<std::string> default_choices() {
- return {"demand_only", "delay_normalized", "delay_normalized_length", "delay_normalized_frequency", "delay_normalized_length_frequency"};
+ return {"demand_only", "demand_only_normalized_length", "delay_normalized", "delay_normalized_length", "delay_normalized_frequency", "delay_normalized_length_frequency"};
}
};
@@ -1432,6 +1436,8 @@
.help(
"Sets the basic cost of routing resource nodes:\n"
" * demand_only: based on expected demand of node type\n"
+ " * demand_only_normalized_length: based on expected \n"
+ " demand of node type normalized by length\n"
" * delay_normalized: like demand_only but normalized\n"
" to magnitude of typical routing resource delay\n"
" * delay_normalized_length: like delay_normalized but\n"
@@ -1812,22 +1818,17 @@
/*
* Routing
*/
- //Which routing algorithm to use?
- if (args.RouterAlgorithm.provenance() != Provenance::SPECIFIED) {
- if (args.timing_analysis && args.RouteType != GLOBAL) {
- args.RouterAlgorithm.set(TIMING_DRIVEN, Provenance::INFERRED);
- } else {
- args.RouterAlgorithm.set(NO_TIMING, Provenance::INFERRED);
- }
- }
-
//Base cost type
if (args.base_cost_type.provenance() != Provenance::SPECIFIED) {
- if (args.RouterAlgorithm == BREADTH_FIRST || args.RouterAlgorithm == NO_TIMING) {
+ if (args.RouterAlgorithm == BREADTH_FIRST) {
args.base_cost_type.set(DEMAND_ONLY, Provenance::INFERRED);
} else {
VTR_ASSERT(args.RouterAlgorithm == TIMING_DRIVEN);
- args.base_cost_type.set(DELAY_NORMALIZED_LENGTH, Provenance::INFERRED);
+ if (args.timing_analysis) {
+ args.base_cost_type.set(DELAY_NORMALIZED_LENGTH, Provenance::INFERRED);
+ } else {
+ args.base_cost_type.set(DEMAND_ONLY_NORMALIZED_LENGTH, Provenance::INFERRED);
+ }
}
}
diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h
index 1eb4ffb..bc2dfee 100644
--- a/vpr/src/base/vpr_types.h
+++ b/vpr/src/base/vpr_types.h
@@ -867,17 +867,19 @@
GLOBAL,
DETAILED
};
+
enum e_router_algorithm {
BREADTH_FIRST,
TIMING_DRIVEN,
- NO_TIMING
};
+
enum e_base_cost_type {
DELAY_NORMALIZED,
DELAY_NORMALIZED_LENGTH,
DELAY_NORMALIZED_FREQUENCY,
DELAY_NORMALIZED_LENGTH_FREQUENCY,
- DEMAND_ONLY
+ DEMAND_ONLY,
+ DEMAND_ONLY_NORMALIZED_LENGTH
};
enum e_routing_failure_predictor {
OFF,
diff --git a/vpr/src/route/route_common.cpp b/vpr/src/route/route_common.cpp
index a788735..778330c 100644
--- a/vpr/src/route/route_common.cpp
+++ b/vpr/src/route/route_common.cpp
@@ -1905,7 +1905,6 @@
bool router_needs_lookahead(enum e_router_algorithm router_algorithm) {
switch (router_algorithm) {
case BREADTH_FIRST:
- case NO_TIMING:
return false;
case TIMING_DRIVEN:
return true;
diff --git a/vpr/src/route/rr_graph_indexed_data.cpp b/vpr/src/route/rr_graph_indexed_data.cpp
index dc2218b..0d8fc85 100644
--- a/vpr/src/route/rr_graph_indexed_data.cpp
+++ b/vpr/src/route/rr_graph_indexed_data.cpp
@@ -153,7 +153,7 @@
auto& device_ctx = g_vpr_ctx.mutable_device();
- if (base_cost_type == DEMAND_ONLY) {
+ if (base_cost_type == DEMAND_ONLY || base_cost_type == DEMAND_ONLY_NORMALIZED_LENGTH) {
delay_normalization_fac = 1.;
} else {
delay_normalization_fac = get_delay_normalization_fac(nodes_per_chan, L_rr_node_indices);
@@ -177,7 +177,7 @@
if (base_cost_type == DELAY_NORMALIZED || base_cost_type == DEMAND_ONLY) {
device_ctx.rr_indexed_data[index].base_cost = delay_normalization_fac;
- } else if (base_cost_type == DELAY_NORMALIZED_LENGTH) {
+ } else if (base_cost_type == DELAY_NORMALIZED_LENGTH || base_cost_type == DEMAND_ONLY_NORMALIZED_LENGTH) {
device_ctx.rr_indexed_data[index].base_cost = delay_normalization_fac / device_ctx.rr_indexed_data[index].inv_length;
} else if (base_cost_type == DELAY_NORMALIZED_FREQUENCY) {