diff options
-rw-r--r-- | common/route.cc | 60 | ||||
-rw-r--r-- | ice40/arch.h | 13 |
2 files changed, 55 insertions, 18 deletions
diff --git a/common/route.cc b/common/route.cc index b3e773dd..a7f8f53f 100644 --- a/common/route.cc +++ b/common/route.cc @@ -67,8 +67,10 @@ struct QueuedWire struct RipupScoreboard { - std::unordered_map<std::pair<IdString, WireId>, int, hash_id_wire> wireScores; - std::unordered_map<std::pair<IdString, PipId>, int, hash_id_pip> pipScores; + std::unordered_map<WireId, int> wireScores; + std::unordered_map<PipId, int> pipScores; + std::unordered_map<std::pair<IdString, WireId>, int, hash_id_wire> netWireScores; + std::unordered_map<std::pair<IdString, PipId>, int, hash_id_pip> netPipScores; }; void ripup_net(Context *ctx, IdString net_name) @@ -152,9 +154,15 @@ struct Router IdString ripupWireNet = ctx->getConflictingWireNet(next_wire); if (ripupWireNet == net_name || ripupWireNet == IdString()) continue; - auto it = scores.wireScores.find(std::make_pair(ripupWireNet, next_wire)); - if (it != scores.wireScores.end()) - next_delay += it->second * ripup_penalty; + + 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; } @@ -164,9 +172,15 @@ struct Router IdString ripupPipNet = ctx->getConflictingPipNet(pip); if (ripupPipNet == net_name || ripupPipNet == IdString()) continue; - auto it = scores.pipScores.find(std::make_pair(ripupPipNet, pip)); - if (it != scores.pipScores.end()) - next_delay += it->second * ripup_penalty; + + 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; } @@ -271,6 +285,8 @@ struct Router std::unordered_map<WireId, delay_t> src_wires; src_wires[src_wire] = 0; + + ripup_net(ctx, net_name); ctx->bindWire(src_wire, net_name, STRENGTH_WEAK); std::vector<PortRef> users_array = net_info->users; @@ -340,26 +356,36 @@ struct Router break; IdString conflicting_wire_net = ctx->getConflictingWireNet(cursor); - IdString conflicting_pip_net = ctx->getConflictingPipNet(visited[cursor].pip); if (conflicting_wire_net != IdString()) { assert(ripup); assert(conflicting_wire_net != net_name); - ripup_net(ctx, conflicting_wire_net); + + ctx->unbindWire(cursor); + if (!ctx->checkWireAvail(cursor)) + ripup_net(ctx, conflicting_wire_net); + rippedNets.insert(conflicting_wire_net); - scores.wireScores[std::make_pair(net_name, cursor)]++; - scores.wireScores[std::make_pair(conflicting_wire_net, cursor)]++; + 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()) { assert(ripup); assert(conflicting_pip_net != net_name); - if (conflicting_wire_net != conflicting_pip_net) { + + ctx->unbindPip(pip); + if (!ctx->checkPipAvail(pip)) ripup_net(ctx, conflicting_pip_net); - rippedNets.insert(conflicting_pip_net); - } - scores.pipScores[std::make_pair(net_name, visited[cursor].pip)]++; - scores.pipScores[std::make_pair(conflicting_pip_net, visited[cursor].pip)]++; + + 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); diff --git a/ice40/arch.h b/ice40/arch.h index f13e3f72..ad69363e 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -617,7 +617,18 @@ struct Arch : BaseCtx { assert(wire != WireId()); assert(wire_to_net[wire.index] != IdString()); - nets[wire_to_net[wire.index]]->wires.erase(wire); + + auto &net_wires = nets[wire_to_net[wire.index]]->wires; + auto it = net_wires.find(wire); + assert(it != net_wires.end()); + + auto pip = it->second.pip; + if (pip != PipId()) { + pip_to_net[pip.index] = IdString(); + switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString(); + } + + net_wires.erase(it); wire_to_net[wire.index] = IdString(); } |