aboutsummaryrefslogtreecommitdiffstats
path: root/ecp5
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2020-02-04 16:08:08 +0000
committerGitHub <noreply@github.com>2020-02-04 16:08:08 +0000
commit1ceffbe0bcba4f31a40c58c436df9370899fa4a2 (patch)
treef3cff1e5f8a067159a4e0fecd870a7acacba57a0 /ecp5
parentb4d029a55cd67bafcc9c364d609208a818227204 (diff)
parenta1c902dadc3165fe9abab7c96a75b5f4808836cd (diff)
downloadnextpnr-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.cc68
-rw-r--r--ecp5/arch.h3
-rw-r--r--ecp5/arch_place.cc21
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;
+ }
}
}
}