From 7df67c91b38433e8a1002f8e9f53926aafaa4d1b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 11 Jul 2018 18:04:09 +0200 Subject: Add ctx->route() API Signed-off-by: Clifford Wolf --- common/router1.cc | 655 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 655 insertions(+) create mode 100644 common/router1.cc (limited to 'common/router1.cc') diff --git a/common/router1.cc b/common/router1.cc new file mode 100644 index 00000000..94c7070e --- /dev/null +++ b/common/router1.cc @@ -0,0 +1,655 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include +#include + +#include "log.h" +#include "router1.h" + +namespace { + +USING_NEXTPNR_NAMESPACE + +struct hash_id_wire +{ + std::size_t operator()(const std::pair &arg) const noexcept + { + std::size_t seed = std::hash()(arg.first); + seed ^= std::hash()(arg.second) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + return seed; + } +}; + +struct hash_id_pip +{ + std::size_t operator()(const std::pair &arg) const noexcept + { + std::size_t seed = std::hash()(arg.first); + seed ^= std::hash()(arg.second) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + return seed; + } +}; + +struct QueuedWire +{ + WireId wire; + PipId pip; + + delay_t delay = 0, togo = 0; + int randtag = 0; + + struct Greater + { + bool operator()(const QueuedWire &lhs, const QueuedWire &rhs) const noexcept + { + delay_t l = lhs.delay + lhs.togo, r = rhs.delay + rhs.togo; + return l == r ? lhs.randtag > rhs.randtag : l > r; + } + }; +}; + +struct RipupScoreboard +{ + std::unordered_map wireScores; + std::unordered_map pipScores; + std::unordered_map, int, hash_id_wire> netWireScores; + std::unordered_map, int, hash_id_pip> netPipScores; +}; + +void ripup_net(Context *ctx, IdString net_name) +{ + auto net_info = ctx->nets.at(net_name).get(); + std::vector pips; + std::vector wires; + + pips.reserve(net_info->wires.size()); + wires.reserve(net_info->wires.size()); + + for (auto &it : net_info->wires) { + if (it.second.pip != PipId()) + pips.push_back(it.second.pip); + else + wires.push_back(it.first); + } + + for (auto pip : pips) + ctx->unbindPip(pip); + + for (auto wire : wires) + ctx->unbindWire(wire); + + NPNR_ASSERT(net_info->wires.empty()); +} + +struct Router +{ + Context *ctx; + RipupScoreboard scores; + IdString net_name; + + bool ripup; + delay_t ripup_penalty; + + std::unordered_set rippedNets; + std::unordered_map visited; + int visitCnt = 0, revisitCnt = 0, overtimeRevisitCnt = 0; + bool routedOkay = false; + delay_t maxDelay = 0.0; + WireId failedDest; + + void route(const std::unordered_map &src_wires, WireId dst_wire) + { + std::priority_queue, QueuedWire::Greater> queue; + + visited.clear(); + + for (auto &it : src_wires) { + QueuedWire qw; + qw.wire = it.first; + qw.pip = PipId(); + qw.delay = it.second; + qw.togo = ctx->estimateDelay(qw.wire, dst_wire); + qw.randtag = ctx->rng(); + + queue.push(qw); + visited[qw.wire] = qw; + } + + int thisVisitCnt = 0; + int thisVisitCntLimit = 0; + + while (!queue.empty() && (thisVisitCntLimit == 0 || thisVisitCnt < thisVisitCntLimit)) { + QueuedWire qw = queue.top(); + queue.pop(); + + if (thisVisitCntLimit == 0 && visited.count(dst_wire)) + thisVisitCntLimit = (thisVisitCnt * 3) / 2; + + for (auto pip : ctx->getPipsDownhill(qw.wire)) { + delay_t next_delay = qw.delay + ctx->getPipDelay(pip).avgDelay(); + WireId next_wire = ctx->getPipDstWire(pip); + bool foundRipupNet = false; + thisVisitCnt++; + + if (!ctx->checkWireAvail(next_wire)) { + if (!ripup) + continue; + IdString ripupWireNet = ctx->getConflictingWireNet(next_wire); + if (ripupWireNet == net_name || ripupWireNet == IdString()) + continue; + + auto it1 = scores.wireScores.find(next_wire); + if (it1 != scores.wireScores.end()) + next_delay += (it1->second * ripup_penalty) / 8; + + auto it2 = scores.netWireScores.find(std::make_pair(ripupWireNet, next_wire)); + if (it2 != scores.netWireScores.end()) + next_delay += it2->second * ripup_penalty; + + foundRipupNet = true; + } + + if (!ctx->checkPipAvail(pip)) { + if (!ripup) + continue; + IdString ripupPipNet = ctx->getConflictingPipNet(pip); + if (ripupPipNet == net_name || ripupPipNet == IdString()) + continue; + + auto it1 = scores.pipScores.find(pip); + if (it1 != scores.pipScores.end()) + next_delay += (it1->second * ripup_penalty) / 8; + + auto it2 = scores.netPipScores.find(std::make_pair(ripupPipNet, pip)); + if (it2 != scores.netPipScores.end()) + next_delay += it2->second * ripup_penalty; + + foundRipupNet = true; + } + + if (foundRipupNet) + next_delay += ripup_penalty; + + NPNR_ASSERT(next_delay >= 0); + + if (visited.count(next_wire)) { + if (visited.at(next_wire).delay <= next_delay + ctx->getDelayEpsilon()) + continue; +#if 0 // FIXME + if (ctx->debug) + log("Found better route to %s. Old vs new delay " + "estimate: %.3f %.3f\n", + ctx->getWireName(next_wire).c_str(), + ctx->getDelayNS(visited.at(next_wire).delay), + ctx->getDelayNS(next_delay)); +#endif + if (thisVisitCntLimit == 0) + revisitCnt++; + else + overtimeRevisitCnt++; + } + + QueuedWire next_qw; + next_qw.wire = next_wire; + next_qw.pip = pip; + next_qw.delay = next_delay; + next_qw.togo = ctx->estimateDelay(next_wire, dst_wire); + qw.randtag = ctx->rng(); + + visited[next_qw.wire] = next_qw; + queue.push(next_qw); + } + } + + visitCnt += thisVisitCnt; + } + + Router(Context *ctx, RipupScoreboard &scores, WireId src_wire, WireId dst_wire, bool ripup = false, + delay_t ripup_penalty = 0) + : ctx(ctx), scores(scores), ripup(ripup), ripup_penalty(ripup_penalty) + { + std::unordered_map src_wires; + src_wires[src_wire] = 0; + route(src_wires, dst_wire); + routedOkay = visited.count(dst_wire); + + if (ctx->debug) { + log("Route (from destination to source):\n"); + + WireId cursor = dst_wire; + + while (1) { + log(" %8.3f %s\n", ctx->getDelayNS(visited[cursor].delay), ctx->getWireName(cursor).c_str(ctx)); + + if (cursor == src_wire) + break; + + cursor = ctx->getPipSrcWire(visited[cursor].pip); + } + } + } + + Router(Context *ctx, RipupScoreboard &scores, IdString net_name, bool ripup = false, delay_t ripup_penalty = 0) + : ctx(ctx), scores(scores), net_name(net_name), ripup(ripup), ripup_penalty(ripup_penalty) + { + auto net_info = ctx->nets.at(net_name).get(); + + if (ctx->debug) + log("Routing net %s.\n", net_name.c_str(ctx)); + + if (ctx->debug) + log(" Source: %s.%s.\n", net_info->driver.cell->name.c_str(ctx), net_info->driver.port.c_str(ctx)); + + auto src_bel = net_info->driver.cell->bel; + + if (src_bel == BelId()) + log_error("Source cell %s (%s) is not mapped to a bel.\n", net_info->driver.cell->name.c_str(ctx), + net_info->driver.cell->type.c_str(ctx)); + + if (ctx->debug) + log(" Source bel: %s\n", ctx->getBelName(src_bel).c_str(ctx)); + + IdString driver_port = net_info->driver.port; + + auto driver_port_it = net_info->driver.cell->pins.find(driver_port); + if (driver_port_it != net_info->driver.cell->pins.end()) + driver_port = driver_port_it->second; + + auto src_wire = ctx->getWireBelPin(src_bel, ctx->portPinFromId(driver_port)); + + if (src_wire == WireId()) + log_error("No wire found for port %s (pin %s) on source cell %s " + "(bel %s).\n", + net_info->driver.port.c_str(ctx), driver_port.c_str(ctx), net_info->driver.cell->name.c_str(ctx), + ctx->getBelName(src_bel).c_str(ctx)); + + if (ctx->debug) + log(" Source wire: %s\n", ctx->getWireName(src_wire).c_str(ctx)); + + std::unordered_map src_wires; + src_wires[src_wire] = 0; + + ripup_net(ctx, net_name); + ctx->bindWire(src_wire, net_name, STRENGTH_WEAK); + + std::vector users_array = net_info->users; + ctx->shuffle(users_array); + + for (auto &user_it : users_array) { + if (ctx->debug) + log(" Route to: %s.%s.\n", user_it.cell->name.c_str(ctx), user_it.port.c_str(ctx)); + + auto dst_bel = user_it.cell->bel; + + if (dst_bel == BelId()) + log_error("Destination cell %s (%s) is not mapped to a bel.\n", user_it.cell->name.c_str(ctx), + user_it.cell->type.c_str(ctx)); + + if (ctx->debug) + log(" Destination bel: %s\n", ctx->getBelName(dst_bel).c_str(ctx)); + + IdString user_port = user_it.port; + + auto user_port_it = user_it.cell->pins.find(user_port); + + if (user_port_it != user_it.cell->pins.end()) + user_port = user_port_it->second; + + auto dst_wire = ctx->getWireBelPin(dst_bel, ctx->portPinFromId(user_port)); + + if (dst_wire == WireId()) + log_error("No wire found for port %s (pin %s) on destination " + "cell %s (bel %s).\n", + user_it.port.c_str(ctx), user_port.c_str(ctx), user_it.cell->name.c_str(ctx), + ctx->getBelName(dst_bel).c_str(ctx)); + + if (ctx->debug) { + log(" Destination wire: %s\n", ctx->getWireName(dst_wire).c_str(ctx)); + log(" Path delay estimate: %.2f\n", float(ctx->estimateDelay(src_wire, dst_wire))); + } + + route(src_wires, dst_wire); + + if (visited.count(dst_wire) == 0) { + if (ctx->debug) + log("Failed to route %s -> %s.\n", ctx->getWireName(src_wire).c_str(ctx), + ctx->getWireName(dst_wire).c_str(ctx)); + else if (ripup) + log_info("Failed to route %s -> %s.\n", ctx->getWireName(src_wire).c_str(ctx), + ctx->getWireName(dst_wire).c_str(ctx)); + ripup_net(ctx, net_name); + failedDest = dst_wire; + return; + } + + if (ctx->debug) + log(" Final path delay: %.3f\n", ctx->getDelayNS(visited[dst_wire].delay)); + maxDelay = fmaxf(maxDelay, visited[dst_wire].delay); + + if (ctx->debug) + log(" Route (from destination to source):\n"); + + WireId cursor = dst_wire; + + while (1) { + if (ctx->debug) + log(" %8.3f %s\n", ctx->getDelayNS(visited[cursor].delay), ctx->getWireName(cursor).c_str(ctx)); + + if (src_wires.count(cursor)) + break; + + IdString conflicting_wire_net = ctx->getConflictingWireNet(cursor); + + if (conflicting_wire_net != IdString()) { + NPNR_ASSERT(ripup); + NPNR_ASSERT(conflicting_wire_net != net_name); + + ctx->unbindWire(cursor); + if (!ctx->checkWireAvail(cursor)) + ripup_net(ctx, conflicting_wire_net); + + rippedNets.insert(conflicting_wire_net); + scores.wireScores[cursor]++; + scores.netWireScores[std::make_pair(net_name, cursor)]++; + scores.netWireScores[std::make_pair(conflicting_wire_net, cursor)]++; + } + + PipId pip = visited[cursor].pip; + IdString conflicting_pip_net = ctx->getConflictingPipNet(pip); + + if (conflicting_pip_net != IdString()) { + NPNR_ASSERT(ripup); + NPNR_ASSERT(conflicting_pip_net != net_name); + + ctx->unbindPip(pip); + if (!ctx->checkPipAvail(pip)) + ripup_net(ctx, conflicting_pip_net); + + rippedNets.insert(conflicting_pip_net); + scores.pipScores[visited[cursor].pip]++; + scores.netPipScores[std::make_pair(net_name, visited[cursor].pip)]++; + scores.netPipScores[std::make_pair(conflicting_pip_net, visited[cursor].pip)]++; + } + + ctx->bindPip(visited[cursor].pip, net_name, STRENGTH_WEAK); + src_wires[cursor] = visited[cursor].delay; + cursor = ctx->getPipSrcWire(visited[cursor].pip); + } + } + + routedOkay = true; + } +}; + +} // namespace + +NEXTPNR_NAMESPACE_BEGIN + +bool router1(Context *ctx) +{ + try { + int totalVisitCnt = 0, totalRevisitCnt = 0, totalOvertimeRevisitCnt = 0; + delay_t ripup_penalty = ctx->getRipupDelayPenalty(); + RipupScoreboard scores; + + log_break(); + log_info("Routing..\n"); + + std::unordered_set netsQueue; + + for (auto &net_it : ctx->nets) { + auto net_name = net_it.first; + auto net_info = net_it.second.get(); + + if (net_info->driver.cell == nullptr) + continue; + + if (!net_info->wires.empty()) + continue; + + netsQueue.insert(net_name); + } + + if (netsQueue.empty()) { + log_info("found no unrouted nets. no routing necessary.\n"); + return true; + } + + log_info("found %d unrouted nets. starting routing procedure.\n", int(netsQueue.size())); + + delay_t estimatedTotalDelay = 0.0; + int estimatedTotalDelayCnt = 0; + + for (auto net_name : netsQueue) { + auto net_info = ctx->nets.at(net_name).get(); + + auto src_bel = net_info->driver.cell->bel; + + if (src_bel == BelId()) + continue; + + IdString driver_port = net_info->driver.port; + + auto driver_port_it = net_info->driver.cell->pins.find(driver_port); + if (driver_port_it != net_info->driver.cell->pins.end()) + driver_port = driver_port_it->second; + + auto src_wire = ctx->getWireBelPin(src_bel, ctx->portPinFromId(driver_port)); + + if (src_wire == WireId()) + continue; + + for (auto &user_it : net_info->users) { + auto dst_bel = user_it.cell->bel; + + if (dst_bel == BelId()) + continue; + + IdString user_port = user_it.port; + + auto user_port_it = user_it.cell->pins.find(user_port); + + if (user_port_it != user_it.cell->pins.end()) + user_port = user_port_it->second; + + auto dst_wire = ctx->getWireBelPin(dst_bel, ctx->portPinFromId(user_port)); + + if (dst_wire == WireId()) + continue; + + estimatedTotalDelay += ctx->estimateDelay(src_wire, dst_wire); + estimatedTotalDelayCnt++; + } + } + + log_info("estimated total wire delay: %.2f (avg %.2f)\n", float(estimatedTotalDelay), + float(estimatedTotalDelay) / estimatedTotalDelayCnt); + + int iterCnt = 0; + + while (!netsQueue.empty()) { + if (iterCnt == 200) { + log_warning("giving up after %d iterations.\n", iterCnt); + log_info("Checksum: 0x%08x\n", ctx->checksum()); +#ifndef NDEBUG + ctx->check(); +#endif + return false; + } + + iterCnt++; + if (ctx->verbose) + log_info("-- %d --\n", iterCnt); + + int visitCnt = 0, revisitCnt = 0, overtimeRevisitCnt = 0, netCnt = 0; + + std::unordered_set ripupQueue; + + if (ctx->verbose || iterCnt == 1) + log_info("routing queue contains %d nets.\n", int(netsQueue.size())); + + bool printNets = ctx->verbose && (netsQueue.size() < 10); + + std::vector netsArray(netsQueue.begin(), netsQueue.end()); + ctx->sorted_shuffle(netsArray); + netsQueue.clear(); + + for (auto net_name : netsArray) { + if (printNets) + log_info(" routing net %s. (%d users)\n", net_name.c_str(ctx), + int(ctx->nets.at(net_name)->users.size())); + + Router router(ctx, scores, net_name, false); + + netCnt++; + visitCnt += router.visitCnt; + revisitCnt += router.revisitCnt; + overtimeRevisitCnt += router.overtimeRevisitCnt; + + if (!router.routedOkay) { + if (printNets) + log_info(" failed to route to %s.\n", ctx->getWireName(router.failedDest).c_str(ctx)); + ripupQueue.insert(net_name); + } + + if ((ctx->verbose || iterCnt == 1) && !printNets && (netCnt % 100 == 0)) + log_info(" processed %d nets. (%d routed, %d failed)\n", netCnt, netCnt - int(ripupQueue.size()), + int(ripupQueue.size())); + } + + int normalRouteCnt = netCnt - int(ripupQueue.size()); + + if ((ctx->verbose || iterCnt == 1) && (netCnt % 100 != 0)) + log_info(" processed %d nets. (%d routed, %d failed)\n", netCnt, normalRouteCnt, + int(ripupQueue.size())); + + if (ctx->verbose) + log_info(" visited %d PIPs (%.2f%% revisits, %.2f%% overtime " + "revisits).\n", + visitCnt, (100.0 * revisitCnt) / visitCnt, (100.0 * overtimeRevisitCnt) / visitCnt); + + if (!ripupQueue.empty()) { + if (ctx->verbose || iterCnt == 1) + log_info("failed to route %d nets. re-routing in ripup " + "mode.\n", + int(ripupQueue.size())); + + printNets = ctx->verbose && (ripupQueue.size() < 10); + + visitCnt = 0; + revisitCnt = 0; + overtimeRevisitCnt = 0; + netCnt = 0; + int ripCnt = 0; + + std::vector ripupArray(ripupQueue.begin(), ripupQueue.end()); + ctx->sorted_shuffle(ripupArray); + + for (auto net_name : ripupArray) { + if (printNets) + log_info(" routing net %s. (%d users)\n", net_name.c_str(ctx), + int(ctx->nets.at(net_name)->users.size())); + + Router router(ctx, scores, net_name, true, ripup_penalty); + + netCnt++; + visitCnt += router.visitCnt; + revisitCnt += router.revisitCnt; + overtimeRevisitCnt += router.overtimeRevisitCnt; + + if (!router.routedOkay) + log_error("Net %s is impossible to route.\n", net_name.c_str(ctx)); + + for (auto it : router.rippedNets) + netsQueue.insert(it); + + if (printNets) { + if (router.rippedNets.size() < 10) { + log_info(" ripped up %d other nets:\n", int(router.rippedNets.size())); + for (auto n : router.rippedNets) + log_info(" %s (%d users)\n", n.c_str(ctx), int(ctx->nets.at(n)->users.size())); + } else { + log_info(" ripped up %d other nets.\n", int(router.rippedNets.size())); + } + } + + ripCnt += router.rippedNets.size(); + + if ((ctx->verbose || iterCnt == 1) && !printNets && (netCnt % 100 == 0)) + log_info(" routed %d nets, ripped %d nets.\n", netCnt, ripCnt); + } + + if ((ctx->verbose || iterCnt == 1) && (netCnt % 100 != 0)) + log_info(" routed %d nets, ripped %d nets.\n", netCnt, ripCnt); + + if (ctx->verbose) + log_info(" visited %d PIPs (%.2f%% revisits, %.2f%% " + "overtime revisits).\n", + visitCnt, (100.0 * revisitCnt) / visitCnt, (100.0 * overtimeRevisitCnt) / visitCnt); + + if (ctx->verbose && !netsQueue.empty()) + log_info(" ripped up %d previously routed nets. continue " + "routing.\n", + int(netsQueue.size())); + } + + if (!ctx->verbose) + log_info("iteration %d: routed %d nets without ripup, routed %d " + "nets with ripup.\n", + iterCnt, normalRouteCnt, int(ripupQueue.size())); + + totalVisitCnt += visitCnt; + totalRevisitCnt += revisitCnt; + totalOvertimeRevisitCnt += overtimeRevisitCnt; + + if (iterCnt == 8 || iterCnt == 16 || iterCnt == 32 || iterCnt == 64 || iterCnt == 128) + ripup_penalty += ctx->getRipupDelayPenalty(); + } + + log_info("routing complete after %d iterations.\n", iterCnt); + + log_info("visited %d PIPs (%.2f%% revisits, %.2f%% " + "overtime revisits).\n", + totalVisitCnt, (100.0 * totalRevisitCnt) / totalVisitCnt, + (100.0 * totalOvertimeRevisitCnt) / totalVisitCnt); + + log_info("Checksum: 0x%08x\n", ctx->checksum()); +#ifndef NDEBUG + ctx->check(); +#endif + return true; + } catch (log_execution_error_exception) { +#ifndef NDEBUG + ctx->check(); +#endif + return false; + } +} + +bool Context::getActualRouteDelay(WireId src_wire, WireId dst_wire, delay_t &delay) +{ + RipupScoreboard scores; + Router router(this, scores, src_wire, dst_wire); + if (router.routedOkay) + delay = router.visited.at(dst_wire).delay; + return router.routedOkay; +} + +NEXTPNR_NAMESPACE_END -- cgit v1.2.3 From 9e4f97290a50fc5d9dc0cbe6ead945840b9811b1 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Fri, 13 Jul 2018 14:50:58 +0100 Subject: Make PnR use Unlocked methods --- common/router1.cc | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'common/router1.cc') diff --git a/common/router1.cc b/common/router1.cc index 94c7070e..cbaf773d 100644 --- a/common/router1.cc +++ b/common/router1.cc @@ -90,10 +90,10 @@ void ripup_net(Context *ctx, IdString net_name) } for (auto pip : pips) - ctx->unbindPip(pip); + ctx->unbindPipUnlocked(pip); for (auto wire : wires) - ctx->unbindWire(wire); + ctx->unbindWireUnlocked(wire); NPNR_ASSERT(net_info->wires.empty()); } @@ -148,10 +148,10 @@ struct Router bool foundRipupNet = false; thisVisitCnt++; - if (!ctx->checkWireAvail(next_wire)) { + if (!ctx->checkWireAvailUnlocked(next_wire)) { if (!ripup) continue; - IdString ripupWireNet = ctx->getConflictingWireNet(next_wire); + IdString ripupWireNet = ctx->getConflictingWireNetUnlocked(next_wire); if (ripupWireNet == net_name || ripupWireNet == IdString()) continue; @@ -166,10 +166,10 @@ struct Router foundRipupNet = true; } - if (!ctx->checkPipAvail(pip)) { + if (!ctx->checkPipAvailUnlocked(pip)) { if (!ripup) continue; - IdString ripupPipNet = ctx->getConflictingPipNet(pip); + IdString ripupPipNet = ctx->getConflictingPipNetUnlocked(pip); if (ripupPipNet == net_name || ripupPipNet == IdString()) continue; @@ -272,7 +272,7 @@ struct Router if (driver_port_it != net_info->driver.cell->pins.end()) driver_port = driver_port_it->second; - auto src_wire = ctx->getWireBelPin(src_bel, ctx->portPinFromId(driver_port)); + auto src_wire = ctx->getWireBelPinUnlocked(src_bel, ctx->portPinFromId(driver_port)); if (src_wire == WireId()) log_error("No wire found for port %s (pin %s) on source cell %s " @@ -287,7 +287,7 @@ struct Router src_wires[src_wire] = 0; ripup_net(ctx, net_name); - ctx->bindWire(src_wire, net_name, STRENGTH_WEAK); + ctx->bindWireUnlocked(src_wire, net_name, STRENGTH_WEAK); std::vector users_array = net_info->users; ctx->shuffle(users_array); @@ -312,7 +312,7 @@ struct Router if (user_port_it != user_it.cell->pins.end()) user_port = user_port_it->second; - auto dst_wire = ctx->getWireBelPin(dst_bel, ctx->portPinFromId(user_port)); + auto dst_wire = ctx->getWireBelPinUnlocked(dst_bel, ctx->portPinFromId(user_port)); if (dst_wire == WireId()) log_error("No wire found for port %s (pin %s) on destination " @@ -355,14 +355,14 @@ struct Router if (src_wires.count(cursor)) break; - IdString conflicting_wire_net = ctx->getConflictingWireNet(cursor); + IdString conflicting_wire_net = ctx->getConflictingWireNetUnlocked(cursor); if (conflicting_wire_net != IdString()) { NPNR_ASSERT(ripup); NPNR_ASSERT(conflicting_wire_net != net_name); - ctx->unbindWire(cursor); - if (!ctx->checkWireAvail(cursor)) + ctx->unbindWireUnlocked(cursor); + if (!ctx->checkWireAvailUnlocked(cursor)) ripup_net(ctx, conflicting_wire_net); rippedNets.insert(conflicting_wire_net); @@ -372,14 +372,14 @@ struct Router } PipId pip = visited[cursor].pip; - IdString conflicting_pip_net = ctx->getConflictingPipNet(pip); + IdString conflicting_pip_net = ctx->getConflictingPipNetUnlocked(pip); if (conflicting_pip_net != IdString()) { NPNR_ASSERT(ripup); NPNR_ASSERT(conflicting_pip_net != net_name); - ctx->unbindPip(pip); - if (!ctx->checkPipAvail(pip)) + ctx->unbindPipUnlocked(pip); + if (!ctx->checkPipAvailUnlocked(pip)) ripup_net(ctx, conflicting_pip_net); rippedNets.insert(conflicting_pip_net); @@ -388,7 +388,7 @@ struct Router scores.netPipScores[std::make_pair(conflicting_pip_net, visited[cursor].pip)]++; } - ctx->bindPip(visited[cursor].pip, net_name, STRENGTH_WEAK); + ctx->bindPipUnlocked(visited[cursor].pip, net_name, STRENGTH_WEAK); src_wires[cursor] = visited[cursor].delay; cursor = ctx->getPipSrcWire(visited[cursor].pip); } @@ -451,7 +451,7 @@ bool router1(Context *ctx) if (driver_port_it != net_info->driver.cell->pins.end()) driver_port = driver_port_it->second; - auto src_wire = ctx->getWireBelPin(src_bel, ctx->portPinFromId(driver_port)); + auto src_wire = ctx->getWireBelPinUnlocked(src_bel, ctx->portPinFromId(driver_port)); if (src_wire == WireId()) continue; @@ -469,7 +469,7 @@ bool router1(Context *ctx) if (user_port_it != user_it.cell->pins.end()) user_port = user_port_it->second; - auto dst_wire = ctx->getWireBelPin(dst_bel, ctx->portPinFromId(user_port)); + auto dst_wire = ctx->getWireBelPinUnlocked(dst_bel, ctx->portPinFromId(user_port)); if (dst_wire == WireId()) continue; -- cgit v1.2.3 From 89809a8b810dd57f50f365d70a0ce547705f8dbb Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Fri, 13 Jul 2018 18:57:55 +0100 Subject: Introduce proxies for locked access to ctx --- common/router1.cc | 108 +++++++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 49 deletions(-) (limited to 'common/router1.cc') diff --git a/common/router1.cc b/common/router1.cc index cbaf773d..0d26a36d 100644 --- a/common/router1.cc +++ b/common/router1.cc @@ -2,6 +2,7 @@ * nextpnr -- Next Generation Place and Route * * Copyright (C) 2018 Clifford Wolf + * Copyright (C) 2018 Serge Bazanski * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -73,7 +74,7 @@ struct RipupScoreboard std::unordered_map, int, hash_id_pip> netPipScores; }; -void ripup_net(Context *ctx, IdString net_name) +void ripup_net(ArchRWProxy &proxy, Context *ctx, IdString net_name) { auto net_info = ctx->nets.at(net_name).get(); std::vector pips; @@ -90,10 +91,10 @@ void ripup_net(Context *ctx, IdString net_name) } for (auto pip : pips) - ctx->unbindPipUnlocked(pip); + proxy.unbindPip(pip); for (auto wire : wires) - ctx->unbindWireUnlocked(wire); + proxy.unbindWire(wire); NPNR_ASSERT(net_info->wires.empty()); } @@ -114,7 +115,7 @@ struct Router delay_t maxDelay = 0.0; WireId failedDest; - void route(const std::unordered_map &src_wires, WireId dst_wire) + void route(ArchRWProxy &proxy, const std::unordered_map &src_wires, WireId dst_wire) { std::priority_queue, QueuedWire::Greater> queue; @@ -135,6 +136,7 @@ struct Router int thisVisitCnt = 0; int thisVisitCntLimit = 0; + while (!queue.empty() && (thisVisitCntLimit == 0 || thisVisitCnt < thisVisitCntLimit)) { QueuedWire qw = queue.top(); queue.pop(); @@ -148,10 +150,10 @@ struct Router bool foundRipupNet = false; thisVisitCnt++; - if (!ctx->checkWireAvailUnlocked(next_wire)) { + if (!proxy.checkWireAvail(next_wire)) { if (!ripup) continue; - IdString ripupWireNet = ctx->getConflictingWireNetUnlocked(next_wire); + IdString ripupWireNet = proxy.getConflictingWireNet(next_wire); if (ripupWireNet == net_name || ripupWireNet == IdString()) continue; @@ -166,10 +168,10 @@ struct Router foundRipupNet = true; } - if (!ctx->checkPipAvailUnlocked(pip)) { + if (!proxy.checkPipAvail(pip)) { if (!ripup) continue; - IdString ripupPipNet = ctx->getConflictingPipNetUnlocked(pip); + IdString ripupPipNet = proxy.getConflictingPipNet(pip); if (ripupPipNet == net_name || ripupPipNet == IdString()) continue; @@ -227,7 +229,10 @@ struct Router { std::unordered_map src_wires; src_wires[src_wire] = 0; - route(src_wires, dst_wire); + { + auto &&proxy = ctx->rwproxy(); + route(proxy, src_wires, dst_wire); + } routedOkay = visited.count(dst_wire); if (ctx->debug) { @@ -272,7 +277,7 @@ struct Router if (driver_port_it != net_info->driver.cell->pins.end()) driver_port = driver_port_it->second; - auto src_wire = ctx->getWireBelPinUnlocked(src_bel, ctx->portPinFromId(driver_port)); + auto src_wire = ctx->rproxy().getWireBelPin(src_bel, ctx->portPinFromId(driver_port)); if (src_wire == WireId()) log_error("No wire found for port %s (pin %s) on source cell %s " @@ -286,8 +291,10 @@ struct Router std::unordered_map src_wires; src_wires[src_wire] = 0; - ripup_net(ctx, net_name); - ctx->bindWireUnlocked(src_wire, net_name, STRENGTH_WEAK); + auto &&proxy = ctx->rwproxy(); + + ripup_net(proxy, ctx, net_name); + proxy.bindWire(src_wire, net_name, STRENGTH_WEAK); std::vector users_array = net_info->users; ctx->shuffle(users_array); @@ -312,7 +319,7 @@ struct Router if (user_port_it != user_it.cell->pins.end()) user_port = user_port_it->second; - auto dst_wire = ctx->getWireBelPinUnlocked(dst_bel, ctx->portPinFromId(user_port)); + auto dst_wire = proxy.getWireBelPin(dst_bel, ctx->portPinFromId(user_port)); if (dst_wire == WireId()) log_error("No wire found for port %s (pin %s) on destination " @@ -325,7 +332,7 @@ struct Router log(" Path delay estimate: %.2f\n", float(ctx->estimateDelay(src_wire, dst_wire))); } - route(src_wires, dst_wire); + route(proxy, src_wires, dst_wire); if (visited.count(dst_wire) == 0) { if (ctx->debug) @@ -334,7 +341,7 @@ struct Router else if (ripup) log_info("Failed to route %s -> %s.\n", ctx->getWireName(src_wire).c_str(ctx), ctx->getWireName(dst_wire).c_str(ctx)); - ripup_net(ctx, net_name); + ripup_net(proxy, ctx, net_name); failedDest = dst_wire; return; } @@ -355,15 +362,15 @@ struct Router if (src_wires.count(cursor)) break; - IdString conflicting_wire_net = ctx->getConflictingWireNetUnlocked(cursor); + IdString conflicting_wire_net = proxy.getConflictingWireNet(cursor); if (conflicting_wire_net != IdString()) { NPNR_ASSERT(ripup); NPNR_ASSERT(conflicting_wire_net != net_name); - ctx->unbindWireUnlocked(cursor); - if (!ctx->checkWireAvailUnlocked(cursor)) - ripup_net(ctx, conflicting_wire_net); + proxy.unbindWire(cursor); + if (!proxy.checkWireAvail(cursor)) + ripup_net(proxy, ctx, conflicting_wire_net); rippedNets.insert(conflicting_wire_net); scores.wireScores[cursor]++; @@ -372,15 +379,15 @@ struct Router } PipId pip = visited[cursor].pip; - IdString conflicting_pip_net = ctx->getConflictingPipNetUnlocked(pip); + IdString conflicting_pip_net = proxy.getConflictingPipNet(pip); if (conflicting_pip_net != IdString()) { NPNR_ASSERT(ripup); NPNR_ASSERT(conflicting_pip_net != net_name); - ctx->unbindPipUnlocked(pip); - if (!ctx->checkPipAvailUnlocked(pip)) - ripup_net(ctx, conflicting_pip_net); + proxy.unbindPip(pip); + if (!proxy.checkPipAvail(pip)) + ripup_net(proxy, ctx, conflicting_pip_net); rippedNets.insert(conflicting_pip_net); scores.pipScores[visited[cursor].pip]++; @@ -388,7 +395,7 @@ struct Router scores.netPipScores[std::make_pair(conflicting_pip_net, visited[cursor].pip)]++; } - ctx->bindPipUnlocked(visited[cursor].pip, net_name, STRENGTH_WEAK); + proxy.bindPip(visited[cursor].pip, net_name, STRENGTH_WEAK); src_wires[cursor] = visited[cursor].delay; cursor = ctx->getPipSrcWire(visited[cursor].pip); } @@ -437,45 +444,48 @@ bool router1(Context *ctx) delay_t estimatedTotalDelay = 0.0; int estimatedTotalDelayCnt = 0; - for (auto net_name : netsQueue) { - auto net_info = ctx->nets.at(net_name).get(); + { + auto &&proxy = ctx->rproxy(); + for (auto net_name : netsQueue) { + auto net_info = ctx->nets.at(net_name).get(); - auto src_bel = net_info->driver.cell->bel; + auto src_bel = net_info->driver.cell->bel; - if (src_bel == BelId()) - continue; + if (src_bel == BelId()) + continue; - IdString driver_port = net_info->driver.port; + IdString driver_port = net_info->driver.port; - auto driver_port_it = net_info->driver.cell->pins.find(driver_port); - if (driver_port_it != net_info->driver.cell->pins.end()) - driver_port = driver_port_it->second; + auto driver_port_it = net_info->driver.cell->pins.find(driver_port); + if (driver_port_it != net_info->driver.cell->pins.end()) + driver_port = driver_port_it->second; - auto src_wire = ctx->getWireBelPinUnlocked(src_bel, ctx->portPinFromId(driver_port)); + auto src_wire = proxy.getWireBelPin(src_bel, ctx->portPinFromId(driver_port)); - if (src_wire == WireId()) - continue; + if (src_wire == WireId()) + continue; - for (auto &user_it : net_info->users) { - auto dst_bel = user_it.cell->bel; + for (auto &user_it : net_info->users) { + auto dst_bel = user_it.cell->bel; - if (dst_bel == BelId()) - continue; + if (dst_bel == BelId()) + continue; - IdString user_port = user_it.port; + IdString user_port = user_it.port; - auto user_port_it = user_it.cell->pins.find(user_port); + auto user_port_it = user_it.cell->pins.find(user_port); - if (user_port_it != user_it.cell->pins.end()) - user_port = user_port_it->second; + if (user_port_it != user_it.cell->pins.end()) + user_port = user_port_it->second; - auto dst_wire = ctx->getWireBelPinUnlocked(dst_bel, ctx->portPinFromId(user_port)); + auto dst_wire = proxy.getWireBelPin(dst_bel, ctx->portPinFromId(user_port)); - if (dst_wire == WireId()) - continue; + if (dst_wire == WireId()) + continue; - estimatedTotalDelay += ctx->estimateDelay(src_wire, dst_wire); - estimatedTotalDelayCnt++; + estimatedTotalDelay += ctx->estimateDelay(src_wire, dst_wire); + estimatedTotalDelayCnt++; + } } } -- cgit v1.2.3 From 9b17fe385cf7e8d3025747b5f7c7822ac2d99920 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 11:10:31 +0100 Subject: Refactor proxies to nextpnr. --- common/router1.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'common/router1.cc') diff --git a/common/router1.cc b/common/router1.cc index 0d26a36d..f7a7e8a2 100644 --- a/common/router1.cc +++ b/common/router1.cc @@ -74,7 +74,7 @@ struct RipupScoreboard std::unordered_map, int, hash_id_pip> netPipScores; }; -void ripup_net(ArchRWProxy &proxy, Context *ctx, IdString net_name) +void ripup_net(MutateContext &proxy, Context *ctx, IdString net_name) { auto net_info = ctx->nets.at(net_name).get(); std::vector pips; @@ -115,7 +115,7 @@ struct Router delay_t maxDelay = 0.0; WireId failedDest; - void route(ArchRWProxy &proxy, const std::unordered_map &src_wires, WireId dst_wire) + void route(MutateContext &proxy, const std::unordered_map &src_wires, WireId dst_wire) { std::priority_queue, QueuedWire::Greater> queue; -- cgit v1.2.3 From 8ca7a6da2525463be5be4ee9f62cfae0acc06b01 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 11:10:59 +0100 Subject: clang-format --- common/router1.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'common/router1.cc') diff --git a/common/router1.cc b/common/router1.cc index f7a7e8a2..dc75a153 100644 --- a/common/router1.cc +++ b/common/router1.cc @@ -136,7 +136,6 @@ struct Router int thisVisitCnt = 0; int thisVisitCntLimit = 0; - while (!queue.empty() && (thisVisitCntLimit == 0 || thisVisitCnt < thisVisitCntLimit)) { QueuedWire qw = queue.top(); queue.pop(); -- cgit v1.2.3 From d9c3c117a38c8bc42cfb96255b4762965bc1611b Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 18:50:34 +0100 Subject: Revert "clang-format" This reverts commit 8ca7a6da2525463be5be4ee9f62cfae0acc06b01. --- common/router1.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'common/router1.cc') diff --git a/common/router1.cc b/common/router1.cc index dc75a153..f7a7e8a2 100644 --- a/common/router1.cc +++ b/common/router1.cc @@ -136,6 +136,7 @@ struct Router int thisVisitCnt = 0; int thisVisitCntLimit = 0; + while (!queue.empty() && (thisVisitCntLimit == 0 || thisVisitCnt < thisVisitCntLimit)) { QueuedWire qw = queue.top(); queue.pop(); -- cgit v1.2.3 From b0c05c7f751cf68165849a8f28d389541456f956 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 18:50:37 +0100 Subject: Revert "Refactor proxies to nextpnr." This reverts commit 9b17fe385cf7e8d3025747b5f7c7822ac2d99920. --- common/router1.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'common/router1.cc') diff --git a/common/router1.cc b/common/router1.cc index f7a7e8a2..0d26a36d 100644 --- a/common/router1.cc +++ b/common/router1.cc @@ -74,7 +74,7 @@ struct RipupScoreboard std::unordered_map, int, hash_id_pip> netPipScores; }; -void ripup_net(MutateContext &proxy, Context *ctx, IdString net_name) +void ripup_net(ArchRWProxy &proxy, Context *ctx, IdString net_name) { auto net_info = ctx->nets.at(net_name).get(); std::vector pips; @@ -115,7 +115,7 @@ struct Router delay_t maxDelay = 0.0; WireId failedDest; - void route(MutateContext &proxy, const std::unordered_map &src_wires, WireId dst_wire) + void route(ArchRWProxy &proxy, const std::unordered_map &src_wires, WireId dst_wire) { std::priority_queue, QueuedWire::Greater> queue; -- cgit v1.2.3 From 447ed83638ef35967adae801430f24e92acb6010 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 18:52:56 +0100 Subject: Revert "Introduce proxies for locked access to ctx" This reverts commit 89809a8b810dd57f50f365d70a0ce547705f8dbb. --- common/router1.cc | 108 +++++++++++++++++++++++++----------------------------- 1 file changed, 49 insertions(+), 59 deletions(-) (limited to 'common/router1.cc') diff --git a/common/router1.cc b/common/router1.cc index 0d26a36d..cbaf773d 100644 --- a/common/router1.cc +++ b/common/router1.cc @@ -2,7 +2,6 @@ * nextpnr -- Next Generation Place and Route * * Copyright (C) 2018 Clifford Wolf - * Copyright (C) 2018 Serge Bazanski * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -74,7 +73,7 @@ struct RipupScoreboard std::unordered_map, int, hash_id_pip> netPipScores; }; -void ripup_net(ArchRWProxy &proxy, Context *ctx, IdString net_name) +void ripup_net(Context *ctx, IdString net_name) { auto net_info = ctx->nets.at(net_name).get(); std::vector pips; @@ -91,10 +90,10 @@ void ripup_net(ArchRWProxy &proxy, Context *ctx, IdString net_name) } for (auto pip : pips) - proxy.unbindPip(pip); + ctx->unbindPipUnlocked(pip); for (auto wire : wires) - proxy.unbindWire(wire); + ctx->unbindWireUnlocked(wire); NPNR_ASSERT(net_info->wires.empty()); } @@ -115,7 +114,7 @@ struct Router delay_t maxDelay = 0.0; WireId failedDest; - void route(ArchRWProxy &proxy, const std::unordered_map &src_wires, WireId dst_wire) + void route(const std::unordered_map &src_wires, WireId dst_wire) { std::priority_queue, QueuedWire::Greater> queue; @@ -136,7 +135,6 @@ struct Router int thisVisitCnt = 0; int thisVisitCntLimit = 0; - while (!queue.empty() && (thisVisitCntLimit == 0 || thisVisitCnt < thisVisitCntLimit)) { QueuedWire qw = queue.top(); queue.pop(); @@ -150,10 +148,10 @@ struct Router bool foundRipupNet = false; thisVisitCnt++; - if (!proxy.checkWireAvail(next_wire)) { + if (!ctx->checkWireAvailUnlocked(next_wire)) { if (!ripup) continue; - IdString ripupWireNet = proxy.getConflictingWireNet(next_wire); + IdString ripupWireNet = ctx->getConflictingWireNetUnlocked(next_wire); if (ripupWireNet == net_name || ripupWireNet == IdString()) continue; @@ -168,10 +166,10 @@ struct Router foundRipupNet = true; } - if (!proxy.checkPipAvail(pip)) { + if (!ctx->checkPipAvailUnlocked(pip)) { if (!ripup) continue; - IdString ripupPipNet = proxy.getConflictingPipNet(pip); + IdString ripupPipNet = ctx->getConflictingPipNetUnlocked(pip); if (ripupPipNet == net_name || ripupPipNet == IdString()) continue; @@ -229,10 +227,7 @@ struct Router { std::unordered_map src_wires; src_wires[src_wire] = 0; - { - auto &&proxy = ctx->rwproxy(); - route(proxy, src_wires, dst_wire); - } + route(src_wires, dst_wire); routedOkay = visited.count(dst_wire); if (ctx->debug) { @@ -277,7 +272,7 @@ struct Router if (driver_port_it != net_info->driver.cell->pins.end()) driver_port = driver_port_it->second; - auto src_wire = ctx->rproxy().getWireBelPin(src_bel, ctx->portPinFromId(driver_port)); + auto src_wire = ctx->getWireBelPinUnlocked(src_bel, ctx->portPinFromId(driver_port)); if (src_wire == WireId()) log_error("No wire found for port %s (pin %s) on source cell %s " @@ -291,10 +286,8 @@ struct Router std::unordered_map src_wires; src_wires[src_wire] = 0; - auto &&proxy = ctx->rwproxy(); - - ripup_net(proxy, ctx, net_name); - proxy.bindWire(src_wire, net_name, STRENGTH_WEAK); + ripup_net(ctx, net_name); + ctx->bindWireUnlocked(src_wire, net_name, STRENGTH_WEAK); std::vector users_array = net_info->users; ctx->shuffle(users_array); @@ -319,7 +312,7 @@ struct Router if (user_port_it != user_it.cell->pins.end()) user_port = user_port_it->second; - auto dst_wire = proxy.getWireBelPin(dst_bel, ctx->portPinFromId(user_port)); + auto dst_wire = ctx->getWireBelPinUnlocked(dst_bel, ctx->portPinFromId(user_port)); if (dst_wire == WireId()) log_error("No wire found for port %s (pin %s) on destination " @@ -332,7 +325,7 @@ struct Router log(" Path delay estimate: %.2f\n", float(ctx->estimateDelay(src_wire, dst_wire))); } - route(proxy, src_wires, dst_wire); + route(src_wires, dst_wire); if (visited.count(dst_wire) == 0) { if (ctx->debug) @@ -341,7 +334,7 @@ struct Router else if (ripup) log_info("Failed to route %s -> %s.\n", ctx->getWireName(src_wire).c_str(ctx), ctx->getWireName(dst_wire).c_str(ctx)); - ripup_net(proxy, ctx, net_name); + ripup_net(ctx, net_name); failedDest = dst_wire; return; } @@ -362,15 +355,15 @@ struct Router if (src_wires.count(cursor)) break; - IdString conflicting_wire_net = proxy.getConflictingWireNet(cursor); + IdString conflicting_wire_net = ctx->getConflictingWireNetUnlocked(cursor); if (conflicting_wire_net != IdString()) { NPNR_ASSERT(ripup); NPNR_ASSERT(conflicting_wire_net != net_name); - proxy.unbindWire(cursor); - if (!proxy.checkWireAvail(cursor)) - ripup_net(proxy, ctx, conflicting_wire_net); + ctx->unbindWireUnlocked(cursor); + if (!ctx->checkWireAvailUnlocked(cursor)) + ripup_net(ctx, conflicting_wire_net); rippedNets.insert(conflicting_wire_net); scores.wireScores[cursor]++; @@ -379,15 +372,15 @@ struct Router } PipId pip = visited[cursor].pip; - IdString conflicting_pip_net = proxy.getConflictingPipNet(pip); + IdString conflicting_pip_net = ctx->getConflictingPipNetUnlocked(pip); if (conflicting_pip_net != IdString()) { NPNR_ASSERT(ripup); NPNR_ASSERT(conflicting_pip_net != net_name); - proxy.unbindPip(pip); - if (!proxy.checkPipAvail(pip)) - ripup_net(proxy, ctx, conflicting_pip_net); + ctx->unbindPipUnlocked(pip); + if (!ctx->checkPipAvailUnlocked(pip)) + ripup_net(ctx, conflicting_pip_net); rippedNets.insert(conflicting_pip_net); scores.pipScores[visited[cursor].pip]++; @@ -395,7 +388,7 @@ struct Router scores.netPipScores[std::make_pair(conflicting_pip_net, visited[cursor].pip)]++; } - proxy.bindPip(visited[cursor].pip, net_name, STRENGTH_WEAK); + ctx->bindPipUnlocked(visited[cursor].pip, net_name, STRENGTH_WEAK); src_wires[cursor] = visited[cursor].delay; cursor = ctx->getPipSrcWire(visited[cursor].pip); } @@ -444,48 +437,45 @@ bool router1(Context *ctx) delay_t estimatedTotalDelay = 0.0; int estimatedTotalDelayCnt = 0; - { - auto &&proxy = ctx->rproxy(); - for (auto net_name : netsQueue) { - auto net_info = ctx->nets.at(net_name).get(); + for (auto net_name : netsQueue) { + auto net_info = ctx->nets.at(net_name).get(); - auto src_bel = net_info->driver.cell->bel; + auto src_bel = net_info->driver.cell->bel; - if (src_bel == BelId()) - continue; + if (src_bel == BelId()) + continue; - IdString driver_port = net_info->driver.port; + IdString driver_port = net_info->driver.port; - auto driver_port_it = net_info->driver.cell->pins.find(driver_port); - if (driver_port_it != net_info->driver.cell->pins.end()) - driver_port = driver_port_it->second; + auto driver_port_it = net_info->driver.cell->pins.find(driver_port); + if (driver_port_it != net_info->driver.cell->pins.end()) + driver_port = driver_port_it->second; - auto src_wire = proxy.getWireBelPin(src_bel, ctx->portPinFromId(driver_port)); + auto src_wire = ctx->getWireBelPinUnlocked(src_bel, ctx->portPinFromId(driver_port)); - if (src_wire == WireId()) - continue; + if (src_wire == WireId()) + continue; - for (auto &user_it : net_info->users) { - auto dst_bel = user_it.cell->bel; + for (auto &user_it : net_info->users) { + auto dst_bel = user_it.cell->bel; - if (dst_bel == BelId()) - continue; + if (dst_bel == BelId()) + continue; - IdString user_port = user_it.port; + IdString user_port = user_it.port; - auto user_port_it = user_it.cell->pins.find(user_port); + auto user_port_it = user_it.cell->pins.find(user_port); - if (user_port_it != user_it.cell->pins.end()) - user_port = user_port_it->second; + if (user_port_it != user_it.cell->pins.end()) + user_port = user_port_it->second; - auto dst_wire = proxy.getWireBelPin(dst_bel, ctx->portPinFromId(user_port)); + auto dst_wire = ctx->getWireBelPinUnlocked(dst_bel, ctx->portPinFromId(user_port)); - if (dst_wire == WireId()) - continue; + if (dst_wire == WireId()) + continue; - estimatedTotalDelay += ctx->estimateDelay(src_wire, dst_wire); - estimatedTotalDelayCnt++; - } + estimatedTotalDelay += ctx->estimateDelay(src_wire, dst_wire); + estimatedTotalDelayCnt++; } } -- cgit v1.2.3 From 57f75385b0960d6e1e30112a395a89ee4df07056 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 18:53:08 +0100 Subject: Revert "Make PnR use Unlocked methods" This reverts commit 9e4f97290a50fc5d9dc0cbe6ead945840b9811b1. --- common/router1.cc | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'common/router1.cc') diff --git a/common/router1.cc b/common/router1.cc index cbaf773d..94c7070e 100644 --- a/common/router1.cc +++ b/common/router1.cc @@ -90,10 +90,10 @@ void ripup_net(Context *ctx, IdString net_name) } for (auto pip : pips) - ctx->unbindPipUnlocked(pip); + ctx->unbindPip(pip); for (auto wire : wires) - ctx->unbindWireUnlocked(wire); + ctx->unbindWire(wire); NPNR_ASSERT(net_info->wires.empty()); } @@ -148,10 +148,10 @@ struct Router bool foundRipupNet = false; thisVisitCnt++; - if (!ctx->checkWireAvailUnlocked(next_wire)) { + if (!ctx->checkWireAvail(next_wire)) { if (!ripup) continue; - IdString ripupWireNet = ctx->getConflictingWireNetUnlocked(next_wire); + IdString ripupWireNet = ctx->getConflictingWireNet(next_wire); if (ripupWireNet == net_name || ripupWireNet == IdString()) continue; @@ -166,10 +166,10 @@ struct Router foundRipupNet = true; } - if (!ctx->checkPipAvailUnlocked(pip)) { + if (!ctx->checkPipAvail(pip)) { if (!ripup) continue; - IdString ripupPipNet = ctx->getConflictingPipNetUnlocked(pip); + IdString ripupPipNet = ctx->getConflictingPipNet(pip); if (ripupPipNet == net_name || ripupPipNet == IdString()) continue; @@ -272,7 +272,7 @@ struct Router if (driver_port_it != net_info->driver.cell->pins.end()) driver_port = driver_port_it->second; - auto src_wire = ctx->getWireBelPinUnlocked(src_bel, ctx->portPinFromId(driver_port)); + auto src_wire = ctx->getWireBelPin(src_bel, ctx->portPinFromId(driver_port)); if (src_wire == WireId()) log_error("No wire found for port %s (pin %s) on source cell %s " @@ -287,7 +287,7 @@ struct Router src_wires[src_wire] = 0; ripup_net(ctx, net_name); - ctx->bindWireUnlocked(src_wire, net_name, STRENGTH_WEAK); + ctx->bindWire(src_wire, net_name, STRENGTH_WEAK); std::vector users_array = net_info->users; ctx->shuffle(users_array); @@ -312,7 +312,7 @@ struct Router if (user_port_it != user_it.cell->pins.end()) user_port = user_port_it->second; - auto dst_wire = ctx->getWireBelPinUnlocked(dst_bel, ctx->portPinFromId(user_port)); + auto dst_wire = ctx->getWireBelPin(dst_bel, ctx->portPinFromId(user_port)); if (dst_wire == WireId()) log_error("No wire found for port %s (pin %s) on destination " @@ -355,14 +355,14 @@ struct Router if (src_wires.count(cursor)) break; - IdString conflicting_wire_net = ctx->getConflictingWireNetUnlocked(cursor); + IdString conflicting_wire_net = ctx->getConflictingWireNet(cursor); if (conflicting_wire_net != IdString()) { NPNR_ASSERT(ripup); NPNR_ASSERT(conflicting_wire_net != net_name); - ctx->unbindWireUnlocked(cursor); - if (!ctx->checkWireAvailUnlocked(cursor)) + ctx->unbindWire(cursor); + if (!ctx->checkWireAvail(cursor)) ripup_net(ctx, conflicting_wire_net); rippedNets.insert(conflicting_wire_net); @@ -372,14 +372,14 @@ struct Router } PipId pip = visited[cursor].pip; - IdString conflicting_pip_net = ctx->getConflictingPipNetUnlocked(pip); + IdString conflicting_pip_net = ctx->getConflictingPipNet(pip); if (conflicting_pip_net != IdString()) { NPNR_ASSERT(ripup); NPNR_ASSERT(conflicting_pip_net != net_name); - ctx->unbindPipUnlocked(pip); - if (!ctx->checkPipAvailUnlocked(pip)) + ctx->unbindPip(pip); + if (!ctx->checkPipAvail(pip)) ripup_net(ctx, conflicting_pip_net); rippedNets.insert(conflicting_pip_net); @@ -388,7 +388,7 @@ struct Router scores.netPipScores[std::make_pair(conflicting_pip_net, visited[cursor].pip)]++; } - ctx->bindPipUnlocked(visited[cursor].pip, net_name, STRENGTH_WEAK); + ctx->bindPip(visited[cursor].pip, net_name, STRENGTH_WEAK); src_wires[cursor] = visited[cursor].delay; cursor = ctx->getPipSrcWire(visited[cursor].pip); } @@ -451,7 +451,7 @@ bool router1(Context *ctx) if (driver_port_it != net_info->driver.cell->pins.end()) driver_port = driver_port_it->second; - auto src_wire = ctx->getWireBelPinUnlocked(src_bel, ctx->portPinFromId(driver_port)); + auto src_wire = ctx->getWireBelPin(src_bel, ctx->portPinFromId(driver_port)); if (src_wire == WireId()) continue; @@ -469,7 +469,7 @@ bool router1(Context *ctx) if (user_port_it != user_it.cell->pins.end()) user_port = user_port_it->second; - auto dst_wire = ctx->getWireBelPinUnlocked(dst_bel, ctx->portPinFromId(user_port)); + auto dst_wire = ctx->getWireBelPin(dst_bel, ctx->portPinFromId(user_port)); if (dst_wire == WireId()) continue; -- cgit v1.2.3