Improve router ripup handling
Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
parent
a1681560a3
commit
a40d9dc514
@ -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);
|
||||
|
13
ice40/arch.h
13
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();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user