aboutsummaryrefslogtreecommitdiffstats
path: root/ecp5
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2019-02-25 10:54:24 +0000
committerDavid Shah <dave@ds0.me>2019-02-25 11:49:25 +0000
commit4ec2bd1e5deebf738e35ecf594a958cb0166f4af (patch)
tree6f15c7c60c9f3815c66cb78c58fb95437b13e1ff /ecp5
parent55b0b60d9d58961bfefea66fcc197b399424d9d6 (diff)
downloadnextpnr-4ec2bd1e5deebf738e35ecf594a958cb0166f4af.tar.gz
nextpnr-4ec2bd1e5deebf738e35ecf594a958cb0166f4af.tar.bz2
nextpnr-4ec2bd1e5deebf738e35ecf594a958cb0166f4af.zip
ecp5: Fix global clock routing with multiclock DPRAM
Signed-off-by: David Shah <dave@ds0.me>
Diffstat (limited to 'ecp5')
-rw-r--r--ecp5/arch.cc9
-rw-r--r--ecp5/globals.cc19
2 files changed, 18 insertions, 10 deletions
diff --git a/ecp5/arch.cc b/ecp5/arch.cc
index 2bce0b01..bec9278d 100644
--- a/ecp5/arch.cc
+++ b/ecp5/arch.cc
@@ -459,7 +459,8 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const
auto src_loc = est_location(src), dst_loc = est_location(dst);
int dx = abs(src_loc.first - dst_loc.first), dy = abs(src_loc.second - dst_loc.second);
- return (130 - 13 * args.speed) * (4 + std::max(dx - 5, 0) + std::max(dy - 5, 0) + 2 * (std::min(dx, 5) + std::min(dy, 5)));
+ return (130 - 13 * args.speed) *
+ (4 + std::max(dx - 5, 0) + std::max(dy - 5, 0) + 2 * (std::min(dx, 5) + std::min(dy, 5)));
}
delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const
@@ -471,10 +472,12 @@ delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const
auto sink_loc = getBelLocation(sink.cell->bel);
int dx = abs(driver_loc.x - sink_loc.x), dy = abs(driver_loc.y - sink_loc.y);
- return (130 - 13 * args.speed) * (4 + std::max(dx - 5, 0) + std::max(dy - 5, 0) + 2 * (std::min(dx, 5) + std::min(dy, 5)));
+ return (130 - 13 * args.speed) *
+ (4 + std::max(dx - 5, 0) + std::max(dy - 5, 0) + 2 * (std::min(dx, 5) + std::min(dy, 5)));
}
-bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const {
+bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const
+{
if (net_info->driver.port == id_FCO && sink.port == id_FCI) {
budget = 0;
return true;
diff --git a/ecp5/globals.cc b/ecp5/globals.cc
index 49947b20..fae2c683 100644
--- a/ecp5/globals.cc
+++ b/ecp5/globals.cc
@@ -448,6 +448,8 @@ class Ecp5GlobalRouter
if (i < 8)
fab_globals.insert(i);
}
+ std::vector<std::pair<PortRef *, int>> toroute;
+ std::unordered_map<int, NetInfo *> clocks;
for (auto cell : sorted(ctx->cells)) {
CellInfo *ci = cell.second;
if (ci->type == id_DCCA) {
@@ -472,15 +474,18 @@ class Ecp5GlobalRouter
NPNR_ASSERT(routed);
// WCK must have routing priority
- auto sorted_users = clock->users;
- std::sort(sorted_users.begin(), sorted_users.end(), [this](const PortRef &a, const PortRef &b) {
- return global_route_priority(a) < global_route_priority(b);
- });
- for (const auto &user : sorted_users) {
- route_logic_tile_global(clock, glbid, user);
- }
+ for (auto &user : clock->users)
+ toroute.emplace_back(&user, glbid);
+ clocks[glbid] = clock;
}
}
+ std::sort(toroute.begin(), toroute.end(),
+ [this](const std::pair<PortRef *, int> &a, const std::pair<PortRef *, int> &b) {
+ return global_route_priority(*a.first) < global_route_priority(*b.first);
+ });
+ for (const auto &user : toroute) {
+ route_logic_tile_global(clocks.at(user.second), user.second, *user.first);
+ }
}
};
void promote_ecp5_globals(Context *ctx) { Ecp5GlobalRouter(ctx).promote_globals(); }