router2: Add some test glue
Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
parent
37d5775694
commit
0ca07e5a6b
@ -38,30 +38,6 @@ NEXTPNR_NAMESPACE_BEGIN
|
|||||||
namespace {
|
namespace {
|
||||||
struct Router2
|
struct Router2
|
||||||
{
|
{
|
||||||
struct arc_key
|
|
||||||
{
|
|
||||||
NetInfo *net_info;
|
|
||||||
int user_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 : net_info->name < other.net_info->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Hash
|
|
||||||
{
|
|
||||||
std::size_t operator()(const arc_key &arg) const noexcept
|
|
||||||
{
|
|
||||||
std::size_t seed = std::hash<NetInfo *>()(arg.net_info);
|
|
||||||
seed ^= std::hash<int>()(arg.user_idx) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
|
||||||
return seed;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PerArcData
|
struct PerArcData
|
||||||
{
|
{
|
||||||
@ -295,6 +271,24 @@ struct Router2
|
|||||||
return ctx->getDelayNS(ctx->estimateDelay(wire, sink)) / (1 + source_uses);
|
return ctx->getDelayNS(ctx->estimateDelay(wire, sink)) / (1 + source_uses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool check_arc_routing(NetInfo *net, size_t usr)
|
||||||
|
{
|
||||||
|
auto &ad = nets.at(net->udata).arcs.at(usr);
|
||||||
|
WireId src_wire = ctx->getNetinfoSourceWire(net);
|
||||||
|
WireId dst_wire = ctx->getNetinfoSinkWire(net, net->users.at(usr));
|
||||||
|
WireId cursor = dst_wire;
|
||||||
|
while (ad.wires.count(cursor)) {
|
||||||
|
auto &wd = wires.at(cursor);
|
||||||
|
if (wd.bound_nets.size() != 1)
|
||||||
|
return false;
|
||||||
|
auto &uh = ad.wires.at(cursor);
|
||||||
|
if (uh == PipId())
|
||||||
|
break;
|
||||||
|
cursor = ctx->getPipSrcWire(uh);
|
||||||
|
}
|
||||||
|
return (cursor == src_wire);
|
||||||
|
}
|
||||||
|
|
||||||
ArcRouteResult route_arc(ThreadContext &t, NetInfo *net, size_t i, bool is_mt, bool is_bb = true)
|
ArcRouteResult route_arc(ThreadContext &t, NetInfo *net, size_t i, bool is_mt, bool is_bb = true)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -310,6 +304,9 @@ struct Router2
|
|||||||
if (dst_wire == WireId())
|
if (dst_wire == WireId())
|
||||||
ARC_LOG_ERR("No wire found for port %s on destination cell %s.\n", ctx->nameOf(usr.port),
|
ARC_LOG_ERR("No wire found for port %s on destination cell %s.\n", ctx->nameOf(usr.port),
|
||||||
ctx->nameOf(usr.cell));
|
ctx->nameOf(usr.cell));
|
||||||
|
// Check if arc is already legally routed
|
||||||
|
if (check_arc_routing(net, i))
|
||||||
|
return ARC_SUCCESS;
|
||||||
// Ripup arc to start with
|
// Ripup arc to start with
|
||||||
ripup_arc(net, i);
|
ripup_arc(net, i);
|
||||||
|
|
||||||
@ -338,6 +335,9 @@ struct Router2
|
|||||||
continue;
|
continue;
|
||||||
// Evaluate score of next wire
|
// Evaluate score of next wire
|
||||||
WireId next = ctx->getPipSrcWire(dh);
|
WireId next = ctx->getPipSrcWire(dh);
|
||||||
|
auto &nwd = wires.at(next);
|
||||||
|
if (nwd.unavailable)
|
||||||
|
continue;
|
||||||
WireScore next_score;
|
WireScore next_score;
|
||||||
next_score.cost = curr.score.cost + score_wire_for_arc(net, i, next, dh);
|
next_score.cost = curr.score.cost + score_wire_for_arc(net, i, next, dh);
|
||||||
next_score.delay =
|
next_score.delay =
|
||||||
@ -352,7 +352,7 @@ struct Router2
|
|||||||
goto loop_done;
|
goto loop_done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (0) {
|
if (false) {
|
||||||
loop_done:
|
loop_done:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -374,6 +374,7 @@ struct Router2
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#undef ARC_ERR
|
#undef ARC_ERR
|
||||||
|
|
||||||
bool route_net(ThreadContext &t, NetInfo *net, bool is_mt)
|
bool route_net(ThreadContext &t, NetInfo *net, bool is_mt)
|
||||||
{
|
{
|
||||||
ROUTE_LOG_DBG("Routing net '%s'...\n", ctx->nameOf(net));
|
ROUTE_LOG_DBG("Routing net '%s'...\n", ctx->nameOf(net));
|
||||||
@ -400,10 +401,52 @@ struct Router2
|
|||||||
}
|
}
|
||||||
return !have_failures;
|
return !have_failures;
|
||||||
}
|
}
|
||||||
#undef ARC_LOG_DBG
|
#undef ROUTE_LOG_DBG
|
||||||
|
|
||||||
void bind_and_check_legality(NetInfo *net) {}
|
int total_wire_use = 0;
|
||||||
|
int overused_wires = 0;
|
||||||
|
int total_overuse = 0;
|
||||||
|
|
||||||
|
void update_congestion()
|
||||||
|
{
|
||||||
|
total_overuse = 0;
|
||||||
|
overused_wires = 0;
|
||||||
|
total_wire_use = 0;
|
||||||
|
for (auto &wire : wires) {
|
||||||
|
total_wire_use += int(wire.second.bound_nets.size());
|
||||||
|
int overuse = int(wire.second.bound_nets.size()) - 1;
|
||||||
|
if (overuse > 0) {
|
||||||
|
wire.second.hist_cong_cost += overuse * hist_cong_weight;
|
||||||
|
total_overuse += overuse;
|
||||||
|
overused_wires += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void router_test()
|
||||||
|
{
|
||||||
|
setup_nets();
|
||||||
|
setup_wires();
|
||||||
|
curr_cong_weight = 0.5;
|
||||||
|
hist_cong_weight = 1.0;
|
||||||
|
ThreadContext st;
|
||||||
|
int iter = 1;
|
||||||
|
while (total_overuse > 0) {
|
||||||
|
for (auto net : nets_by_udata)
|
||||||
|
route_net(st, net, false);
|
||||||
|
update_congestion();
|
||||||
|
log_info("iter=%d wires=%d overused=%d overuse=%d\n", iter, total_overuse, overused_wires, total_overuse);
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
void router2_test(Context *ctx)
|
||||||
|
{
|
||||||
|
Router2 rt;
|
||||||
|
rt.ctx = ctx;
|
||||||
|
rt.router_test();
|
||||||
|
}
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
26
common/router2.h
Normal file
26
common/router2.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* nextpnr -- Next Generation Place and Route
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 David Shah <dave@ds0.me>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nextpnr.h"
|
||||||
|
|
||||||
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
void router2_test(Context *ctx);
|
||||||
|
|
||||||
|
NEXTPNR_NAMESPACE_END
|
Loading…
Reference in New Issue
Block a user