diff options
| author | Clifford Wolf <clifford@clifford.at> | 2018-08-02 14:47:07 +0200 | 
|---|---|---|
| committer | Clifford Wolf <clifford@clifford.at> | 2018-08-02 14:47:07 +0200 | 
| commit | 3185abe2649ad57ec6eb06ccf99ed0d767daadb9 (patch) | |
| tree | 4686e9c1c42b536e7fa2f28fc214a95281a8ed5f | |
| parent | 6ccf8629b5c9f143eafa48c0427b066593f12403 (diff) | |
| download | nextpnr-3185abe2649ad57ec6eb06ccf99ed0d767daadb9.tar.gz nextpnr-3185abe2649ad57ec6eb06ccf99ed0d767daadb9.tar.bz2 nextpnr-3185abe2649ad57ec6eb06ccf99ed0d767daadb9.zip  | |
Fix router1 cleanupReroute() for "drive-by nets"
Signed-off-by: Clifford Wolf <clifford@clifford.at>
| -rw-r--r-- | common/router1.cc | 57 | 
1 files changed, 32 insertions, 25 deletions
diff --git a/common/router1.cc b/common/router1.cc index b8ab2db2..06da114e 100644 --- a/common/router1.cc +++ b/common/router1.cc @@ -586,8 +586,38 @@ void cleanupReroute(Context *ctx, const Router1Cfg &cfg,          if (ctx->verbose)              allNetinfos.push_back(net_info); +        std::unordered_map<WireId, int> useCounters; +        std::vector<int> candidateArcs; +          for (int user_idx = 0; user_idx < int(net_info->users.size()); user_idx++) {              auto dst_wire = ctx->getNetinfoSinkWire(net_info, net_info->users[user_idx]); + +            if (dst_wire == src_wire) +                continue; + +            auto cursor = dst_wire; +            useCounters[cursor]++; + +            while (cursor != src_wire) { +                auto it = net_info->wires.find(cursor); +                if (it == net_info->wires.end()) +                    break; +                cursor = ctx->getPipSrcWire(it->second.pip); +                useCounters[cursor]++; +            } + +            if (cursor != src_wire) +                continue; + +            candidateArcs.push_back(user_idx); +        } + +        for (int user_idx : candidateArcs) { +            auto dst_wire = ctx->getNetinfoSinkWire(net_info, net_info->users[user_idx]); + +            if (useCounters.at(dst_wire) != 1) +                continue; +              RouteJob job;              job.net = net_name;              job.user_idx = user_idx; @@ -618,25 +648,8 @@ void cleanupReroute(Context *ctx, const Router1Cfg &cfg,          auto user_idx = job.user_idx;          NetInfo *net_info = ctx->nets.at(net_name).get(); -        auto src_wire = ctx->getNetinfoSourceWire(net_info);          auto dst_wire = ctx->getNetinfoSinkWire(net_info, net_info->users[user_idx]); -        auto cursor = dst_wire; -        while (cursor != src_wire) { -            auto it = net_info->wires.find(cursor); -            if (it == net_info->wires.end()) { -                cleanupQueue.insert(net_name); -                goto skipThisJob; -            } -            cursor = ctx->getPipSrcWire(it->second.pip); -        } - -        if (0) -    skipThisJob: -            continue; - -        int oldWireCount = net_info->wires.size(); -          ctx->unbindWire(dst_wire);          Router router(ctx, cfg, scores, net_name, user_idx, false, false); @@ -644,12 +657,6 @@ void cleanupReroute(Context *ctx, const Router1Cfg &cfg,          if (!router.routedOkay)              log_error("Failed to re-route arc %d of net %s.\n", user_idx, net_name.c_str(ctx)); -        int newWireCount = net_info->wires.size(); - -        if (ctx->debug && oldWireCount != newWireCount) -            log_info("  rerouting arc %d of net %s changed wire count: %d -> %d (%+d)\n", -                     user_idx, net_name.c_str(ctx), oldWireCount, newWireCount, newWireCount - oldWireCount); -          visitCnt += router.visitCnt;          revisitCnt += router.revisitCnt;          overtimeRevisitCnt += router.overtimeRevisitCnt; @@ -659,7 +666,7 @@ void cleanupReroute(Context *ctx, const Router1Cfg &cfg,          for (auto it : allNetinfos)              totalWireCountDelta += it->wires.size(); -        log_info("  visited %d PIPs (%.2f%% revisits, %.2f%% overtime revisits), %+d bound wires.\n", +        log_info("  visited %d PIPs (%.2f%% revisits, %.2f%% overtime), %+d wires.\n",                   visitCnt, (100.0 * revisitCnt) / visitCnt, (100.0 * overtimeRevisitCnt) / visitCnt,                   totalWireCountDelta);      } @@ -861,7 +868,7 @@ bool router1(Context *ctx, const Router1Cfg &cfg)              if (iterCnt == 8 || iterCnt == 16 || iterCnt == 32 || iterCnt == 64 || iterCnt == 128)                  ripup_penalty += ctx->getRipupDelayPenalty(); -            if (jobQueue.empty() || (iterCnt % 5) == 4 || (cfg.fullCleanupReroute && iterCnt == 1)) +            if (jobQueue.empty() || (iterCnt % 5) == 0 || (cfg.fullCleanupReroute && iterCnt == 1))                  cleanupReroute(ctx, cfg, scores, cleanupQueue, jobQueue, totalVisitCnt, totalRevisitCnt, totalOvertimeRevisitCnt);              ctx->yield();  | 
