diff options
author | David Shah <dave@ds0.me> | 2020-02-04 16:08:08 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-04 16:08:08 +0000 |
commit | 1ceffbe0bcba4f31a40c58c436df9370899fa4a2 (patch) | |
tree | f3cff1e5f8a067159a4e0fecd870a7acacba57a0 /ecp5 | |
parent | b4d029a55cd67bafcc9c364d609208a818227204 (diff) | |
parent | a1c902dadc3165fe9abab7c96a75b5f4808836cd (diff) | |
download | nextpnr-1ceffbe0bcba4f31a40c58c436df9370899fa4a2.tar.gz nextpnr-1ceffbe0bcba4f31a40c58c436df9370899fa4a2.tar.bz2 nextpnr-1ceffbe0bcba4f31a40c58c436df9370899fa4a2.zip |
Merge pull request #391 from YosysHQ/router2-upstream
Upstreaming router2
Diffstat (limited to 'ecp5')
-rw-r--r-- | ecp5/arch.cc | 68 | ||||
-rw-r--r-- | ecp5/arch.h | 3 | ||||
-rw-r--r-- | ecp5/arch_place.cc | 21 |
3 files changed, 85 insertions, 7 deletions
diff --git a/ecp5/arch.cc b/ecp5/arch.cc index 994e8660..0a44e020 100644 --- a/ecp5/arch.cc +++ b/ecp5/arch.cc @@ -30,6 +30,7 @@ #include "placer1.h" #include "placer_heap.h" #include "router1.h" +#include "router2.h" #include "timing.h" #include "util.h" @@ -492,6 +493,57 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const (6 + std::max(dx - 5, 0) + std::max(dy - 5, 0) + 2 * (std::min(dx, 5) + std::min(dy, 5))); } +ArcBounds Arch::getRouteBoundingBox(WireId src, WireId dst) const +{ + ArcBounds bb; + + bb.x0 = src.location.x; + bb.y0 = src.location.y; + bb.x1 = src.location.x; + bb.y1 = src.location.y; + + auto extend = [&](int x, int y) { + bb.x0 = std::min(bb.x0, x); + bb.x1 = std::max(bb.x1, x); + bb.y0 = std::min(bb.y0, y); + bb.y1 = std::max(bb.y1, y); + }; + + auto est_location = [&](WireId w) -> std::pair<int, int> { + const auto &wire = locInfo(w)->wire_data[w.index]; + if (w == gsrclk_wire) { + auto phys_wire = getPipSrcWire(*(getPipsUphill(w).begin())); + return std::make_pair(int(phys_wire.location.x), int(phys_wire.location.y)); + } else if (wire.num_bel_pins > 0) { + return std::make_pair(w.location.x + wire.bel_pins[0].rel_bel_loc.x, + w.location.y + wire.bel_pins[0].rel_bel_loc.y); + } else if (wire.num_downhill > 0) { + return std::make_pair(w.location.x + wire.pips_downhill[0].rel_loc.x, + w.location.y + wire.pips_downhill[0].rel_loc.y); + } else if (wire.num_uphill > 0) { + return std::make_pair(w.location.x + wire.pips_uphill[0].rel_loc.x, + w.location.y + wire.pips_uphill[0].rel_loc.y); + } else { + return std::make_pair(int(w.location.x), int(w.location.y)); + } + }; + + auto src_loc = est_location(src); + extend(src_loc.first, src_loc.second); + if (wire_loc_overrides.count(src)) { + extend(wire_loc_overrides.at(src).first, wire_loc_overrides.at(src).second); + } + std::pair<int, int> dst_loc; + extend(dst.location.x, dst.location.y); + if (wire_loc_overrides.count(dst)) { + dst_loc = wire_loc_overrides.at(dst); + } else { + dst_loc = est_location(dst); + } + extend(dst_loc.first, dst_loc.second); + return bb; +} + delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const { const auto &driver = net_info->driver; @@ -569,12 +621,23 @@ bool Arch::place() bool Arch::route() { + std::string router = str_or_default(settings, id("router"), defaultRouter); + setupWireLocations(); route_ecp5_globals(getCtx()); assignArchInfo(); assign_budget(getCtx(), true); - bool result = router1(getCtx(), Router1Cfg(getCtx())); + bool result; + if (router == "router1") { + result = router1(getCtx(), Router1Cfg(getCtx())); + } else if (router == "router2") { + router2(getCtx(), Router2Cfg(getCtx())); + result = true; + } else { + log_error("ECP5 architecture does not support router '%s'\n", router.c_str()); + } + #if 0 std::vector<std::pair<WireId, int>> fanout_vector; std::copy(wire_fanout.begin(), wire_fanout.end(), std::back_inserter(fanout_vector)); @@ -1121,6 +1184,9 @@ const std::vector<std::string> Arch::availablePlacers = {"sa", #endif }; +const std::string Arch::defaultRouter = "router1"; +const std::vector<std::string> Arch::availableRouters = {"router1", "router2"}; + // ----------------------------------------------------------------------- GroupId Arch::getGroupByName(IdString name) const diff --git a/ecp5/arch.h b/ecp5/arch.h index b3e36e52..55494b1f 100644 --- a/ecp5/arch.h +++ b/ecp5/arch.h @@ -948,6 +948,7 @@ struct Arch : BaseCtx // ------------------------------------------------- delay_t estimateDelay(WireId src, WireId dst) const; + ArcBounds getRouteBoundingBox(WireId src, WireId dst) const; delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const; delay_t getDelayEpsilon() const { return 20; } delay_t getRipupDelayPenalty() const; @@ -1065,6 +1066,8 @@ struct Arch : BaseCtx static const std::string defaultPlacer; static const std::vector<std::string> availablePlacers; + static const std::string defaultRouter; + static const std::vector<std::string> availableRouters; }; NEXTPNR_NAMESPACE_END diff --git a/ecp5/arch_place.cc b/ecp5/arch_place.cc index 6057605b..c5330694 100644 --- a/ecp5/arch_place.cc +++ b/ecp5/arch_place.cc @@ -203,17 +203,26 @@ void Arch::setupWireLocations() CellInfo *ci = cell.second; if (ci->bel == BelId()) continue; - if (ci->type == id_MULT18X18D || ci->type == id_DCUA) { + if (ci->type == id_MULT18X18D || ci->type == id_DCUA || ci->type == id_DDRDLL || ci->type == id_DQSBUFM || + ci->type == id_EHXPLLL) { for (auto &port : ci->ports) { - if (port.second.type != PORT_IN || port.second.net == nullptr) + if (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; + if (port.second.type == PORT_OUT) { + for (auto dh : getPipsDownhill(pw)) { + WireId pip_dst = getPipDstWire(dh); + wire_loc_overrides[pw] = std::make_pair(pip_dst.location.x, pip_dst.location.y); + break; + } + } else { + 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; + } } } } |