aboutsummaryrefslogtreecommitdiffstats
path: root/common/router2.cc
diff options
context:
space:
mode:
Diffstat (limited to 'common/router2.cc')
-rw-r--r--common/router2.cc139
1 files changed, 71 insertions, 68 deletions
diff --git a/common/router2.cc b/common/router2.cc
index c76e1f61..e943e493 100644
--- a/common/router2.cc
+++ b/common/router2.cc
@@ -117,7 +117,7 @@ struct Router2
NetInfo *ni = net.second.get();
ni->udata = i;
nets_by_udata.at(i) = ni;
- nets.at(i).arcs.resize(ni->users.size());
+ nets.at(i).arcs.resize(ni->users.capacity());
// Start net bounding box at overall min/max
nets.at(i).bb.x0 = std::numeric_limits<int>::max();
@@ -133,10 +133,9 @@ struct Router2
nets.at(i).cy += drv_loc.y;
}
- for (size_t j = 0; j < ni->users.size(); j++) {
- auto &usr = ni->users.at(j);
+ for (auto usr : ni->users.enumerate()) {
WireId src_wire = ctx->getNetinfoSourceWire(ni);
- for (auto &dst_wire : ctx->getNetinfoSinkWires(ni, usr)) {
+ for (auto &dst_wire : ctx->getNetinfoSinkWires(ni, usr.value)) {
nets.at(i).src_wire = src_wire;
if (ni->driver.cell == nullptr)
src_wire = dst_wire;
@@ -146,10 +145,10 @@ struct Router2
log_error("No wire found for port %s on source cell %s.\n", ctx->nameOf(ni->driver.port),
ctx->nameOf(ni->driver.cell));
if (dst_wire == WireId())
- log_error("No wire found for port %s on destination cell %s.\n", ctx->nameOf(usr.port),
- ctx->nameOf(usr.cell));
- nets.at(i).arcs.at(j).emplace_back();
- auto &ad = nets.at(i).arcs.at(j).back();
+ log_error("No wire found for port %s on destination cell %s.\n", ctx->nameOf(usr.value.port),
+ ctx->nameOf(usr.value.cell));
+ nets.at(i).arcs.at(usr.index.idx()).emplace_back();
+ auto &ad = nets.at(i).arcs.at(usr.index.idx()).back();
ad.sink_wire = dst_wire;
// Set bounding box for this arc
ad.bb = ctx->getRouteBoundingBox(src_wire, dst_wire);
@@ -160,14 +159,14 @@ struct Router2
nets.at(i).bb.y1 = std::max(nets.at(i).bb.y1, ad.bb.y1);
}
// Add location to centroid sum
- Loc usr_loc = ctx->getBelLocation(usr.cell->bel);
+ Loc usr_loc = ctx->getBelLocation(usr.value.cell->bel);
nets.at(i).cx += usr_loc.x;
nets.at(i).cy += usr_loc.y;
}
nets.at(i).hpwl = std::max(
std::abs(nets.at(i).bb.y1 - nets.at(i).bb.y0) + std::abs(nets.at(i).bb.x1 - nets.at(i).bb.x0), 1);
- nets.at(i).cx /= int(ni->users.size() + 1);
- nets.at(i).cy /= int(ni->users.size() + 1);
+ nets.at(i).cx /= int(ni->users.entries() + 1);
+ nets.at(i).cy /= int(ni->users.entries() + 1);
if (ctx->debug)
log_info("%s: bb=(%d, %d)->(%d, %d) c=(%d, %d) hpwl=%d\n", ctx->nameOf(ni), nets.at(i).bb.x0,
nets.at(i).bb.y0, nets.at(i).bb.x1, nets.at(i).bb.y1, nets.at(i).cx, nets.at(i).cy,
@@ -218,11 +217,11 @@ struct Router2
for (auto &net_pair : ctx->nets) {
auto *net = net_pair.second.get();
auto &nd = nets.at(net->udata);
- for (size_t usr = 0; usr < net->users.size(); usr++) {
- auto &ad = nd.arcs.at(usr);
+ for (auto usr : net->users.enumerate()) {
+ auto &ad = nd.arcs.at(usr.index.idx());
for (size_t phys_pin = 0; phys_pin < ad.size(); phys_pin++) {
- if (check_arc_routing(net, usr, phys_pin)) {
- record_prerouted_net(net, usr, phys_pin);
+ if (check_arc_routing(net, usr.index, phys_pin)) {
+ record_prerouted_net(net, usr.index, phys_pin);
}
}
}
@@ -261,7 +260,7 @@ struct Router2
// Nets that failed routing
std::vector<NetInfo *> failed_nets;
- std::vector<std::pair<size_t, size_t>> route_arcs;
+ std::vector<std::pair<store_index<PortRef>, size_t>> route_arcs;
std::priority_queue<QueuedWire, std::vector<QueuedWire>, QueuedWire::Greater> fwd_queue, bwd_queue;
// Special case where one net has multiple logical arcs to the same physical sink
@@ -305,7 +304,7 @@ struct Router2
log(__VA_ARGS__); \
} while (0)
- void bind_pip_internal(PerNetData &net, size_t user, int wire, PipId pip)
+ void bind_pip_internal(PerNetData &net, store_index<PortRef> user, int wire, PipId pip)
{
auto &wd = flat_wires.at(wire);
auto found = net.wires.find(wd.w);
@@ -323,7 +322,7 @@ struct Router2
}
}
- void unbind_pip_internal(PerNetData &net, size_t user, WireId wire)
+ void unbind_pip_internal(PerNetData &net, store_index<PortRef> user, WireId wire)
{
auto &wd = wire_data(wire);
auto &b = net.wires.at(wd.w);
@@ -335,10 +334,10 @@ struct Router2
}
}
- void ripup_arc(NetInfo *net, size_t user, size_t phys_pin)
+ void ripup_arc(NetInfo *net, store_index<PortRef> user, size_t phys_pin)
{
auto &nd = nets.at(net->udata);
- auto &ad = nd.arcs.at(user).at(phys_pin);
+ auto &ad = nd.arcs.at(user.idx()).at(phys_pin);
if (!ad.routed)
return;
WireId src = nets.at(net->udata).src_wire;
@@ -351,7 +350,8 @@ struct Router2
ad.routed = false;
}
- float score_wire_for_arc(NetInfo *net, size_t user, size_t phys_pin, WireId wire, PipId pip, float crit_weight)
+ float score_wire_for_arc(NetInfo *net, store_index<PortRef> user, size_t phys_pin, WireId wire, PipId pip,
+ float crit_weight)
{
auto &wd = wire_data(wire);
auto &nd = nets.at(net->udata);
@@ -367,13 +367,14 @@ struct Router2
float present_cost = 1.0f + overuse * curr_cong_weight * crit_weight;
if (pip != PipId()) {
Loc pl = ctx->getPipLocation(pip);
- bias_cost = cfg.bias_cost_factor * (base_cost / int(net->users.size())) *
+ bias_cost = cfg.bias_cost_factor * (base_cost / int(net->users.entries())) *
((std::abs(pl.x - nd.cx) + std::abs(pl.y - nd.cy)) / float(nd.hpwl));
}
return base_cost * hist_cost * present_cost / (1 + (source_uses * crit_weight)) + bias_cost;
}
- float get_togo_cost(NetInfo *net, size_t user, int wire, WireId src_sink, float crit_weight, bool bwd = false)
+ float get_togo_cost(NetInfo *net, store_index<PortRef> user, int wire, WireId src_sink, float crit_weight,
+ bool bwd = false)
{
auto &nd = nets.at(net->udata);
auto &wd = flat_wires[wire];
@@ -386,10 +387,10 @@ struct Router2
return (ctx->getDelayNS(est_delay) / (1 + source_uses * crit_weight)) + cfg.ipin_cost_adder;
}
- bool check_arc_routing(NetInfo *net, size_t usr, size_t phys_pin)
+ bool check_arc_routing(NetInfo *net, store_index<PortRef> usr, size_t phys_pin)
{
auto &nd = nets.at(net->udata);
- auto &ad = nd.arcs.at(usr).at(phys_pin);
+ auto &ad = nd.arcs.at(usr.idx()).at(phys_pin);
WireId src_wire = nets.at(net->udata).src_wire;
WireId cursor = ad.sink_wire;
while (nd.wires.count(cursor)) {
@@ -404,10 +405,10 @@ struct Router2
return (cursor == src_wire);
}
- void record_prerouted_net(NetInfo *net, size_t usr, size_t phys_pin)
+ void record_prerouted_net(NetInfo *net, store_index<PortRef> usr, size_t phys_pin)
{
auto &nd = nets.at(net->udata);
- auto &ad = nd.arcs.at(usr).at(phys_pin);
+ auto &ad = nd.arcs.at(usr.idx()).at(phys_pin);
ad.routed = true;
WireId src = nets.at(net->udata).src_wire;
@@ -449,7 +450,7 @@ struct Router2
}
// Find all the wires that must be used to route a given arc
- bool reserve_wires_for_arc(NetInfo *net, size_t i)
+ bool reserve_wires_for_arc(NetInfo *net, store_index<PortRef> i)
{
bool did_something = false;
WireId src = ctx->getNetinfoSourceWire(net);
@@ -459,7 +460,7 @@ struct Router2
WireId cursor = sink;
bool done = false;
if (ctx->debug)
- log("reserving wires for arc %d (%s.%s) of net %s\n", int(i), ctx->nameOf(usr.cell),
+ log("reserving wires for arc %d (%s.%s) of net %s\n", i.idx(), ctx->nameOf(usr.cell),
ctx->nameOf(usr.port), ctx->nameOf(net));
while (!done) {
auto &wd = wire_data(cursor);
@@ -501,8 +502,8 @@ struct Router2
WireId src = ctx->getNetinfoSourceWire(net);
if (src == WireId())
continue;
- for (size_t i = 0; i < net->users.size(); i++)
- did_something |= reserve_wires_for_arc(net, i);
+ for (auto usr : net->users.enumerate())
+ did_something |= reserve_wires_for_arc(net, usr.index);
}
} while (did_something);
}
@@ -529,12 +530,12 @@ struct Router2
return false;
}
- void update_wire_by_loc(ThreadContext &t, NetInfo *net, size_t i, size_t phys_pin, bool is_mt)
+ void update_wire_by_loc(ThreadContext &t, NetInfo *net, store_index<PortRef> i, size_t phys_pin, bool is_mt)
{
if (is_pseudo_const_net(net))
return;
auto &nd = nets.at(net->udata);
- auto &ad = nd.arcs.at(i).at(phys_pin);
+ auto &ad = nd.arcs.at(i.idx()).at(phys_pin);
WireId cursor = ad.sink_wire;
if (!nd.wires.count(cursor))
return;
@@ -571,28 +572,29 @@ struct Router2
bool was_visited_fwd(int wire) { return flat_wires.at(wire).visited_fwd; }
bool was_visited_bwd(int wire) { return flat_wires.at(wire).visited_bwd; }
- float get_arc_crit(NetInfo *net, size_t i)
+ float get_arc_crit(NetInfo *net, store_index<PortRef> i)
{
if (!timing_driven)
return 0;
return tmg.get_criticality(CellPortKey(net->users.at(i)));
}
- bool arc_failed_slack(NetInfo *net, size_t usr_idx)
+ bool arc_failed_slack(NetInfo *net, store_index<PortRef> usr_idx)
{
return timing_driven_ripup &&
(tmg.get_setup_slack(CellPortKey(net->users.at(usr_idx))) < (2 * ctx->getDelayEpsilon()));
}
- ArcRouteResult route_arc(ThreadContext &t, NetInfo *net, size_t i, size_t phys_pin, bool is_mt, bool is_bb = true)
+ ArcRouteResult route_arc(ThreadContext &t, NetInfo *net, store_index<PortRef> i, size_t phys_pin, bool is_mt,
+ bool is_bb = true)
{
// Do some initial lookups and checks
auto arc_start = std::chrono::high_resolution_clock::now();
auto &nd = nets[net->udata];
- auto &ad = nd.arcs.at(i).at(phys_pin);
+ auto &ad = nd.arcs.at(i.idx()).at(phys_pin);
auto &usr = net->users.at(i);
- ROUTE_LOG_DBG("Routing arc %d of net '%s' (%d, %d) -> (%d, %d)\n", int(i), ctx->nameOf(net), ad.bb.x0, ad.bb.y0,
- ad.bb.x1, ad.bb.y1);
+ ROUTE_LOG_DBG("Routing arc %d of net '%s' (%d, %d) -> (%d, %d)\n", i.idx(), ctx->nameOf(net), ad.bb.x0,
+ ad.bb.y0, ad.bb.x1, ad.bb.y1);
WireId src_wire = ctx->getNetinfoSourceWire(net), dst_wire = ctx->getNetinfoSinkWire(net, usr, phys_pin);
if (src_wire == WireId())
ARC_LOG_ERR("No wire found for port %s on source cell %s.\n", ctx->nameOf(net->driver.port),
@@ -614,7 +616,7 @@ struct Router2
// 0. starting within a small range of existing routing
// 1. expanding from all routing
int mode = 0;
- if (net->users.size() < 4 || nd.wires.empty() || (crit > 0.95))
+ if (net->users.entries() < 4 || nd.wires.empty() || (crit > 0.95))
mode = 1;
// This records the point where forwards and backwards routing met
@@ -844,11 +846,11 @@ struct Router2
t.processed_sinks.insert(dst_wire);
ad.routed = true;
auto arc_end = std::chrono::high_resolution_clock::now();
- ROUTE_LOG_DBG("Routing arc %d of net '%s' (is_bb = %d) took %02fs\n", int(i), ctx->nameOf(net), is_bb,
+ ROUTE_LOG_DBG("Routing arc %d of net '%s' (is_bb = %d) took %02fs\n", i.idx(), ctx->nameOf(net), is_bb,
std::chrono::duration<float>(arc_end - arc_start).count());
} else {
auto arc_end = std::chrono::high_resolution_clock::now();
- ROUTE_LOG_DBG("Failed routing arc %d of net '%s' (is_bb = %d) took %02fs\n", int(i), ctx->nameOf(net),
+ ROUTE_LOG_DBG("Failed routing arc %d of net '%s' (is_bb = %d) took %02fs\n", i.idx(), ctx->nameOf(net),
is_bb, std::chrono::duration<float>(arc_end - arc_start).count());
result = ARC_RETRY_WITHOUT_BB;
}
@@ -880,26 +882,26 @@ struct Router2
t.in_wire_by_loc.clear();
auto &nd = nets.at(net->udata);
bool failed_slack = false;
- for (size_t i = 0; i < net->users.size(); i++)
- failed_slack |= arc_failed_slack(net, i);
- for (size_t i = 0; i < net->users.size(); i++) {
- auto &ad = nd.arcs.at(i);
+ for (auto usr : net->users.enumerate())
+ failed_slack |= arc_failed_slack(net, usr.index);
+ for (auto usr : net->users.enumerate()) {
+ auto &ad = nd.arcs.at(usr.index.idx());
for (size_t j = 0; j < ad.size(); j++) {
// Ripup failed arcs to start with
// Check if arc is already legally routed
- if (!failed_slack && check_arc_routing(net, i, j)) {
- update_wire_by_loc(t, net, i, j, true);
+ if (!failed_slack && check_arc_routing(net, usr.index, j)) {
+ update_wire_by_loc(t, net, usr.index, j, true);
continue;
}
// Ripup arc to start with
- ripup_arc(net, i, j);
- t.route_arcs.emplace_back(i, j);
+ ripup_arc(net, usr.index, j);
+ t.route_arcs.emplace_back(usr.index, j);
}
}
// Route most critical arc first
std::stable_sort(t.route_arcs.begin(), t.route_arcs.end(),
- [&](std::pair<size_t, size_t> a, std::pair<size_t, size_t> b) {
+ [&](std::pair<store_index<PortRef>, size_t> a, std::pair<store_index<PortRef>, size_t> b) {
return get_arc_crit(net, a.first) > get_arc_crit(net, b.first);
});
for (auto a : t.route_arcs) {
@@ -913,7 +915,7 @@ struct Router2
} else {
// Attempt a re-route without the bounding box constraint
ROUTE_LOG_DBG("Rerouting arc %d.%d of net '%s' without bounding box, possible tricky routing...\n",
- int(a.first), int(a.second), ctx->nameOf(net));
+ a.first.idx(), int(a.second), ctx->nameOf(net));
auto res2 = route_arc(t, net, a.first, a.second, is_mt, false);
// If this also fails, no choice but to give up
if (res2 != ARC_SUCCESS) {
@@ -926,7 +928,7 @@ struct Router2
log("\n");
}
}
- log_error("Failed to route arc %d.%d of net '%s', from %s to %s.\n", int(a.first),
+ log_error("Failed to route arc %d.%d of net '%s', from %s to %s.\n", a.first.idx(),
int(a.second), ctx->nameOf(net), ctx->nameOfWire(ctx->getNetinfoSourceWire(net)),
ctx->nameOfWire(ctx->getNetinfoSinkWire(net, net->users.at(a.first), a.second)));
}
@@ -991,7 +993,7 @@ struct Router2
}
}
- bool bind_and_check(NetInfo *net, int usr_idx, int phys_pin)
+ bool bind_and_check(NetInfo *net, store_index<PortRef> usr_idx, int phys_pin)
{
#ifdef ARCH_ECP5
if (net->is_global)
@@ -999,7 +1001,7 @@ struct Router2
#endif
bool success = true;
auto &nd = nets.at(net->udata);
- auto &ad = nd.arcs.at(usr_idx).at(phys_pin);
+ auto &ad = nd.arcs.at(usr_idx.idx()).at(phys_pin);
auto &usr = net->users.at(usr_idx);
WireId src = ctx->getNetinfoSourceWire(net);
// Skip routes with no source
@@ -1043,7 +1045,8 @@ struct Router2
if (!nd.wires.count(cursor)) {
log("Failure details:\n");
log(" Cursor: %s\n", ctx->nameOfWire(cursor));
- log_error("Internal error; incomplete route tree for arc %d of net %s.\n", usr_idx, ctx->nameOf(net));
+ log_error("Internal error; incomplete route tree for arc %d of net %s.\n", usr_idx.idx(),
+ ctx->nameOf(net));
}
PipId p = nd.wires.at(cursor).first;
if (ctx->checkPipAvailForNet(p, net)) {
@@ -1104,9 +1107,9 @@ struct Router2
}
// Bind the arcs using the routes we have discovered
- for (size_t i = 0; i < net->users.size(); i++) {
- for (size_t phys_pin = 0; phys_pin < nets.at(net->udata).arcs.at(i).size(); phys_pin++) {
- if (!bind_and_check(net, i, phys_pin)) {
+ for (auto usr : net->users.enumerate()) {
+ for (size_t phys_pin = 0; phys_pin < nets.at(net->udata).arcs.at(usr.index.idx()).size(); phys_pin++) {
+ if (!bind_and_check(net, usr.index, phys_pin)) {
++arch_fail;
success = false;
}
@@ -1313,10 +1316,10 @@ struct Router2
route_net(tcs.at(N), fail, false);
}
- delay_t get_route_delay(int net, int usr_idx, int phys_idx)
+ delay_t get_route_delay(int net, store_index<PortRef> usr_idx, int phys_idx)
{
auto &nd = nets.at(net);
- auto &ad = nd.arcs.at(usr_idx).at(phys_idx);
+ auto &ad = nd.arcs.at(usr_idx.idx()).at(phys_idx);
WireId cursor = ad.sink_wire;
if (cursor == WireId() || nd.src_wire == WireId())
return 0;
@@ -1344,11 +1347,11 @@ struct Router2
continue;
#endif
auto &nd = nets.at(net);
- for (int i = 0; i < int(nd.arcs.size()); i++) {
+ for (auto usr : ni->users.enumerate()) {
delay_t arc_delay = 0;
- for (int j = 0; j < int(nd.arcs.at(i).size()); j++)
- arc_delay = std::max(arc_delay, get_route_delay(net, i, j));
- tmg.set_route_delay(CellPortKey(ni->users.at(i)), DelayPair(arc_delay));
+ for (int j = 0; j < int(nd.arcs.at(usr.index.idx()).size()); j++)
+ arc_delay = std::max(arc_delay, get_route_delay(net, usr.index, j));
+ tmg.set_route_delay(CellPortKey(usr.value), DelayPair(arc_delay));
}
}
}
@@ -1416,8 +1419,8 @@ struct Router2
if (timing_driven_ripup && iter < 500) {
for (size_t i = 0; i < nets_by_udata.size(); i++) {
NetInfo *ni = nets_by_udata.at(i);
- for (size_t j = 0; j < ni->users.size(); j++) {
- if (arc_failed_slack(ni, j)) {
+ for (auto usr : ni->users.enumerate()) {
+ if (arc_failed_slack(ni, usr.index)) {
failed_nets.insert(i);
++tmgfail;
}
@@ -1451,7 +1454,7 @@ struct Router2
log_info("1000 slowest nets by runtime:\n");
for (int i = 0; i < std::min(int(nets_by_runtime.size()), 1000); i++) {
log(" %80s %6d %.1fms\n", nets_by_runtime.at(i).second.c_str(ctx),
- int(ctx->nets.at(nets_by_runtime.at(i).second)->users.size()),
+ int(ctx->nets.at(nets_by_runtime.at(i).second)->users.entries()),
nets_by_runtime.at(i).first / 1000.0);
}
}