Merge branch 'master' of ssh.github.com:YosysHQ/nextpnr
diff --git a/ecp5/arch.cc b/ecp5/arch.cc
index 8ce0653..5f62d5a 100644
--- a/ecp5/arch.cc
+++ b/ecp5/arch.cc
@@ -477,7 +477,13 @@
         }
     };
 
-    auto src_loc = est_location(src), dst_loc = est_location(dst);
+    auto src_loc = est_location(src);
+    std::pair<int, int> dst_loc;
+    if (wire_loc_overrides.count(dst)) {
+        dst_loc = wire_loc_overrides.at(dst);
+    } else {
+        dst_loc = est_location(dst);
+    }
 
     int dx = abs(src_loc.first - dst_loc.first), dy = abs(src_loc.second - dst_loc.second);
 
@@ -562,6 +568,7 @@
 
 bool Arch::route()
 {
+    setupWireLocations();
     route_ecp5_globals(getCtx());
     assignArchInfo();
     assign_budget(getCtx(), true);
diff --git a/ecp5/arch.h b/ecp5/arch.h
index a479abb..444dfa0 100644
--- a/ecp5/arch.h
+++ b/ecp5/arch.h
@@ -1048,6 +1048,11 @@
     // Special case for delay estimates due to its physical location
     // being far from the logical location of its primitive
     WireId gsrclk_wire;
+    // Improves directivity of routing to DSP inputs, avoids issues
+    // with different routes to the same physical reset wire causing
+    // conflicts and slow routing
+    std::unordered_map<WireId, std::pair<int, int>> wire_loc_overrides;
+    void setupWireLocations();
 
     mutable std::unordered_map<DelayKey, std::pair<bool, DelayInfo>> celldelay_cache;
 
diff --git a/ecp5/arch_place.cc b/ecp5/arch_place.cc
index d5c345a..6057605 100644
--- a/ecp5/arch_place.cc
+++ b/ecp5/arch_place.cc
@@ -196,4 +196,28 @@
     }
 }
 
+void Arch::setupWireLocations()
+{
+    wire_loc_overrides.clear();
+    for (auto cell : sorted(cells)) {
+        CellInfo *ci = cell.second;
+        if (ci->bel == BelId())
+            continue;
+        if (ci->type == id_MULT18X18D || ci->type == id_DCUA) {
+            for (auto &port : ci->ports) {
+                if (port.second.type != PORT_IN || port.second.net == nullptr)
+                    continue;
+                WireId pw = getBelPinWire(ci->bel, port.first);
+                if (pw == WireId())
+                    continue;
+                for (auto uh : getPipsUphill(pw)) {
+                    WireId pip_src = getPipSrcWire(uh);
+                    wire_loc_overrides[pw] = std::make_pair(pip_src.location.x, pip_src.location.y);
+                    break;
+                }
+            }
+        }
+    }
+}
+
 NEXTPNR_NAMESPACE_END