aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2019-10-25 09:37:13 +0100
committerDavid Shah <dave@ds0.me>2019-10-25 09:37:13 +0100
commit36c07a0f45b13e4cf34e6db3b73ccf864af522f0 (patch)
tree45733cdbac1f0045cea5f57a44e4ed8229a8d7d7
parentb582ba810cc54282d4c574bee80a7339c8da17f9 (diff)
downloadnextpnr-36c07a0f45b13e4cf34e6db3b73ccf864af522f0.tar.gz
nextpnr-36c07a0f45b13e4cf34e6db3b73ccf864af522f0.tar.bz2
nextpnr-36c07a0f45b13e4cf34e6db3b73ccf864af522f0.zip
ecp5: Fix routing to shared DSP control inputs
Signed-off-by: David Shah <dave@ds0.me>
-rw-r--r--ecp5/arch.cc9
-rw-r--r--ecp5/arch.h5
-rw-r--r--ecp5/arch_place.cc24
3 files changed, 37 insertions, 1 deletions
diff --git a/ecp5/arch.cc b/ecp5/arch.cc
index 8ce0653c..5f62d5ae 100644
--- a/ecp5/arch.cc
+++ b/ecp5/arch.cc
@@ -477,7 +477,13 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const
}
};
- 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::place()
bool Arch::route()
{
+ setupWireLocations();
route_ecp5_globals(getCtx());
assignArchInfo();
assign_budget(getCtx(), true);
diff --git a/ecp5/arch.h b/ecp5/arch.h
index a479abb6..444dfa07 100644
--- a/ecp5/arch.h
+++ b/ecp5/arch.h
@@ -1048,6 +1048,11 @@ struct Arch : BaseCtx
// 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 d5c345af..6057605b 100644
--- a/ecp5/arch_place.cc
+++ b/ecp5/arch_place.cc
@@ -196,4 +196,28 @@ void Arch::permute_luts()
}
}
+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