router1: Support for multiple bel pins per cell pin

Signed-off-by: gatecat <gatecat@ds0.me>
This commit is contained in:
gatecat 2021-02-10 14:31:16 +00:00
parent 535723f414
commit 7dafc64f78

View File

@ -32,12 +32,20 @@ USING_NEXTPNR_NAMESPACE
struct arc_key struct arc_key
{ {
NetInfo *net_info; NetInfo *net_info;
// logical user cell port index
int user_idx; int user_idx;
// physical index into cell->bel pin mapping (usually 0)
unsigned phys_idx;
bool operator==(const arc_key &other) const { return (net_info == other.net_info) && (user_idx == other.user_idx); } bool operator==(const arc_key &other) const
{
return (net_info == other.net_info) && (user_idx == other.user_idx) && (phys_idx == other.phys_idx);
}
bool operator<(const arc_key &other) const bool operator<(const arc_key &other) const
{ {
return net_info == other.net_info ? user_idx < other.user_idx : net_info->name < other.net_info->name; return net_info == other.net_info
? (user_idx == other.user_idx ? phys_idx < other.phys_idx : user_idx < other.user_idx)
: net_info->name < other.net_info->name;
} }
struct Hash struct Hash
@ -46,6 +54,7 @@ struct arc_key
{ {
std::size_t seed = std::hash<NetInfo *>()(arg.net_info); std::size_t seed = std::hash<NetInfo *>()(arg.net_info);
seed ^= std::hash<int>()(arg.user_idx) + 0x9e3779b9 + (seed << 6) + (seed >> 2); seed ^= std::hash<int>()(arg.user_idx) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
seed ^= std::hash<int>()(arg.phys_idx) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
return seed; return seed;
} }
}; };
@ -142,9 +151,10 @@ struct Router1
NetInfo *net_info = arc.net_info; NetInfo *net_info = arc.net_info;
int user_idx = arc.user_idx; int user_idx = arc.user_idx;
unsigned phys_idx = arc.phys_idx;
auto src_wire = ctx->getNetinfoSourceWire(net_info); auto src_wire = ctx->getNetinfoSourceWire(net_info);
auto dst_wire = ctx->getNetinfoSinkWire(net_info, net_info->users[user_idx], 0); auto dst_wire = ctx->getNetinfoSinkWire(net_info, net_info->users[user_idx], phys_idx);
arc_queue_insert(arc, src_wire, dst_wire); arc_queue_insert(arc, src_wire, dst_wire);
} }
@ -302,13 +312,14 @@ struct Router1
log_assert(src_wire != WireId()); log_assert(src_wire != WireId());
for (int user_idx = 0; user_idx < int(net_info->users.size()); user_idx++) { 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], 0); unsigned phys_idx = 0;
for (auto dst_wire : ctx->getNetinfoSinkWires(net_info, net_info->users[user_idx])) {
log_assert(dst_wire != WireId()); log_assert(dst_wire != WireId());
arc_key arc; arc_key arc;
arc.net_info = net_info; arc.net_info = net_info;
arc.user_idx = user_idx; arc.user_idx = user_idx;
arc.phys_idx = phys_idx++;
valid_arcs.insert(arc); valid_arcs.insert(arc);
#if 0 #if 0
if (ctx->debug) if (ctx->debug)
@ -325,6 +336,7 @@ struct Router1
log_assert(net_info->wires.count(wire)); log_assert(net_info->wires.count(wire));
} }
} }
}
for (auto &it : net_info->wires) { for (auto &it : net_info->wires) {
WireId w = it.first; WireId w = it.first;
@ -375,28 +387,25 @@ struct Router1
ctx->nameOf(dst_to_arc.at(src_wire).net_info), dst_to_arc.at(src_wire).user_idx); ctx->nameOf(dst_to_arc.at(src_wire).net_info), dst_to_arc.at(src_wire).user_idx);
for (int user_idx = 0; user_idx < int(net_info->users.size()); user_idx++) { 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], 0); unsigned phys_idx = 0;
for (auto dst_wire : ctx->getNetinfoSinkWires(net_info, net_info->users[user_idx])) {
if (dst_wire == WireId()) arc_key arc;
log_error("No wire found for port %s on destination cell %s.\n", arc.net_info = net_info;
ctx->nameOf(net_info->users[user_idx].port), ctx->nameOf(net_info->users[user_idx].cell)); arc.user_idx = user_idx;
arc.phys_idx = phys_idx++;
if (dst_to_arc.count(dst_wire)) { if (dst_to_arc.count(dst_wire)) {
if (dst_to_arc.at(dst_wire).net_info == net_info) if (dst_to_arc.at(dst_wire).net_info == net_info)
continue; continue;
log_error("Found two arcs with same sink wire %s: %s (%d) vs %s (%d)\n", ctx->nameOfWire(dst_wire), log_error("Found two arcs with same sink wire %s: %s (%d) vs %s (%d)\n",
ctx->nameOf(net_info), user_idx, ctx->nameOf(dst_to_arc.at(dst_wire).net_info), ctx->nameOfWire(dst_wire), ctx->nameOf(net_info), user_idx,
dst_to_arc.at(dst_wire).user_idx); ctx->nameOf(dst_to_arc.at(dst_wire).net_info), dst_to_arc.at(dst_wire).user_idx);
} }
if (src_to_net.count(dst_wire)) if (src_to_net.count(dst_wire))
log_error("Wire %s is used as source and sink in different nets: %s vs %s (%d)\n", log_error("Wire %s is used as source and sink in different nets: %s vs %s (%d)\n",
ctx->nameOfWire(dst_wire), ctx->nameOf(src_to_net.at(dst_wire)), ctx->nameOf(net_info), ctx->nameOfWire(dst_wire), ctx->nameOf(src_to_net.at(dst_wire)),
user_idx); ctx->nameOf(net_info), user_idx);
arc_key arc;
arc.net_info = net_info;
arc.user_idx = user_idx;
dst_to_arc[dst_wire] = arc; dst_to_arc[dst_wire] = arc;
@ -422,6 +431,12 @@ struct Router1
arc_to_wires[arc].insert(cursor); arc_to_wires[arc].insert(cursor);
} }
} }
// TODO: this matches the situation before supporting multiple cell->bel pins, but do we want to keep
// this invariant?
if (phys_idx == 0)
log_error("No wires found for port %s on destination cell %s.\n",
ctx->nameOf(net_info->users[user_idx].port), ctx->nameOf(net_info->users[user_idx].cell));
}
src_to_net[src_wire] = net_info; src_to_net[src_wire] = net_info;
@ -443,7 +458,7 @@ struct Router1
int user_idx = arc.user_idx; int user_idx = arc.user_idx;
auto src_wire = ctx->getNetinfoSourceWire(net_info); auto src_wire = ctx->getNetinfoSourceWire(net_info);
auto dst_wire = ctx->getNetinfoSinkWire(net_info, net_info->users[user_idx], 0); auto dst_wire = ctx->getNetinfoSinkWire(net_info, net_info->users[user_idx], arc.phys_idx);
ripup_flag = false; ripup_flag = false;
if (ctx->debug) { if (ctx->debug) {
@ -934,7 +949,7 @@ bool Context::checkRoutedDesign() const
std::unordered_map<WireId, int> dest_wires; std::unordered_map<WireId, int> dest_wires;
for (int user_idx = 0; user_idx < int(net_info->users.size()); user_idx++) { 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], 0); for (auto dst_wire : ctx->getNetinfoSinkWires(net_info, net_info->users[user_idx])) {
log_assert(dst_wire != WireId()); log_assert(dst_wire != WireId());
dest_wires[dst_wire] = user_idx; dest_wires[dst_wire] = user_idx;
@ -944,6 +959,7 @@ bool Context::checkRoutedDesign() const
found_unrouted = true; found_unrouted = true;
} }
} }
}
std::function<void(WireId, int)> setOrderNum; std::function<void(WireId, int)> setOrderNum;
std::unordered_set<WireId> logged_wires; std::unordered_set<WireId> logged_wires;