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) {