Minor refactoring of router infrastructure

Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
Clifford Wolf 2018-06-20 13:32:50 +02:00
parent d5a032d00e
commit 3fda636e70

View File

@ -61,111 +61,32 @@ void ripup_net(Context *ctx, IdString net_name)
struct Router
{
Context *ctx;
IdString net_name;
bool ripup;
delay_t ripup_penalty;
std::unordered_set<IdString> rippedNets;
std::unordered_map<WireId, QueuedWire> visited;
int visitCnt = 0, revisitCnt = 0;
bool routedOkay = false;
delay_t maxDelay = 0.0;
WireId failedDest;
Router(Context *ctx, IdString net_name, bool ripup = false,
delay_t ripup_penalty = 0)
void route(const std::unordered_map<WireId, delay_t> &src_wires,
WireId dst_wire)
{
auto net_info = ctx->nets.at(net_name);
if (ctx->verbose)
log("Routing net %s.\n", net_name.c_str(ctx));
if (ctx->verbose)
log(" Source: %s.%s.\n", net_info->driver.cell->name.c_str(ctx),
net_info->driver.port.c_str(ctx));
auto src_bel = net_info->driver.cell->bel;
if (src_bel == BelId())
log_error("Source cell %s (%s) is not mapped to a bel.\n",
net_info->driver.cell->name.c_str(ctx),
net_info->driver.cell->type.c_str(ctx));
if (ctx->verbose)
log(" Source bel: %s\n", ctx->getBelName(src_bel).c_str(ctx));
IdString driver_port = net_info->driver.port;
auto driver_port_it = net_info->driver.cell->pins.find(driver_port);
if (driver_port_it != net_info->driver.cell->pins.end())
driver_port = driver_port_it->second;
auto src_wire =
ctx->getWireBelPin(src_bel, ctx->portPinFromId(driver_port));
if (src_wire == WireId())
log_error("No wire found for port %s (pin %s) on source cell %s "
"(bel %s).\n",
net_info->driver.port.c_str(ctx), driver_port.c_str(ctx),
net_info->driver.cell->name.c_str(ctx),
ctx->getBelName(src_bel).c_str(ctx));
if (ctx->verbose)
log(" Source wire: %s\n", ctx->getWireName(src_wire).c_str(ctx));
std::unordered_map<WireId, DelayInfo> src_wires;
src_wires[src_wire] = DelayInfo();
net_info->wires[src_wire] = PipId();
ctx->bindWire(src_wire, net_name);
std::vector<PortRef> users_array = net_info->users;
ctx->shuffle(users_array);
for (auto &user_it : users_array) {
if (ctx->verbose)
log(" Route to: %s.%s.\n", user_it.cell->name.c_str(ctx),
user_it.port.c_str(ctx));
auto dst_bel = user_it.cell->bel;
if (dst_bel == BelId())
log_error("Destination cell %s (%s) is not mapped to a bel.\n",
user_it.cell->name.c_str(ctx),
user_it.cell->type.c_str(ctx));
if (ctx->verbose)
log(" Destination bel: %s\n",
ctx->getBelName(dst_bel).c_str(ctx));
IdString user_port = user_it.port;
auto user_port_it = user_it.cell->pins.find(user_port);
if (user_port_it != user_it.cell->pins.end())
user_port = user_port_it->second;
auto dst_wire =
ctx->getWireBelPin(dst_bel, ctx->portPinFromId(user_port));
if (dst_wire == WireId())
log_error("No wire found for port %s (pin %s) on destination "
"cell %s (bel %s).\n",
user_it.port.c_str(ctx), user_port.c_str(ctx),
user_it.cell->name.c_str(ctx),
ctx->getBelName(dst_bel).c_str(ctx));
if (ctx->verbose) {
log(" Destination wire: %s\n",
ctx->getWireName(dst_wire).c_str(ctx));
log(" Path delay estimate: %.2f\n",
float(ctx->estimateDelay(src_wire, dst_wire)));
}
std::unordered_map<WireId, QueuedWire> visited;
std::priority_queue<QueuedWire, std::vector<QueuedWire>,
QueuedWire::Greater>
queue;
visited.clear();
for (auto &it : src_wires) {
QueuedWire qw;
qw.wire = it.first;
qw.pip = PipId();
qw.delay = it.second.avgDelay();
qw.delay = it.second;
qw.togo = ctx->estimateDelay(qw.wire, dst_wire);
qw.randtag = ctx->rng();
@ -231,6 +152,109 @@ struct Router
queue.push(next_qw);
}
}
}
Router(Context *ctx, WireId src_wire, WireId dst_wire, bool ripup = false,
delay_t ripup_penalty = 0)
: ctx(ctx), ripup(ripup), ripup_penalty(ripup_penalty)
{
std::unordered_map<WireId, delay_t> src_wires;
src_wires[src_wire] = 0;
route(src_wires, dst_wire);
}
Router(Context *ctx, IdString net_name, bool ripup = false,
delay_t ripup_penalty = 0)
: ctx(ctx), net_name(net_name), ripup(ripup),
ripup_penalty(ripup_penalty)
{
auto net_info = ctx->nets.at(net_name);
if (ctx->verbose)
log("Routing net %s.\n", net_name.c_str(ctx));
if (ctx->verbose)
log(" Source: %s.%s.\n", net_info->driver.cell->name.c_str(ctx),
net_info->driver.port.c_str(ctx));
auto src_bel = net_info->driver.cell->bel;
if (src_bel == BelId())
log_error("Source cell %s (%s) is not mapped to a bel.\n",
net_info->driver.cell->name.c_str(ctx),
net_info->driver.cell->type.c_str(ctx));
if (ctx->verbose)
log(" Source bel: %s\n", ctx->getBelName(src_bel).c_str(ctx));
IdString driver_port = net_info->driver.port;
auto driver_port_it = net_info->driver.cell->pins.find(driver_port);
if (driver_port_it != net_info->driver.cell->pins.end())
driver_port = driver_port_it->second;
auto src_wire =
ctx->getWireBelPin(src_bel, ctx->portPinFromId(driver_port));
if (src_wire == WireId())
log_error("No wire found for port %s (pin %s) on source cell %s "
"(bel %s).\n",
net_info->driver.port.c_str(ctx), driver_port.c_str(ctx),
net_info->driver.cell->name.c_str(ctx),
ctx->getBelName(src_bel).c_str(ctx));
if (ctx->verbose)
log(" Source wire: %s\n", ctx->getWireName(src_wire).c_str(ctx));
std::unordered_map<WireId, delay_t> src_wires;
src_wires[src_wire] = 0;
net_info->wires[src_wire] = PipId();
ctx->bindWire(src_wire, net_name);
std::vector<PortRef> users_array = net_info->users;
ctx->shuffle(users_array);
for (auto &user_it : users_array) {
if (ctx->verbose)
log(" Route to: %s.%s.\n", user_it.cell->name.c_str(ctx),
user_it.port.c_str(ctx));
auto dst_bel = user_it.cell->bel;
if (dst_bel == BelId())
log_error("Destination cell %s (%s) is not mapped to a bel.\n",
user_it.cell->name.c_str(ctx),
user_it.cell->type.c_str(ctx));
if (ctx->verbose)
log(" Destination bel: %s\n",
ctx->getBelName(dst_bel).c_str(ctx));
IdString user_port = user_it.port;
auto user_port_it = user_it.cell->pins.find(user_port);
if (user_port_it != user_it.cell->pins.end())
user_port = user_port_it->second;
auto dst_wire =
ctx->getWireBelPin(dst_bel, ctx->portPinFromId(user_port));
if (dst_wire == WireId())
log_error("No wire found for port %s (pin %s) on destination "
"cell %s (bel %s).\n",
user_it.port.c_str(ctx), user_port.c_str(ctx),
user_it.cell->name.c_str(ctx),
ctx->getBelName(dst_bel).c_str(ctx));
if (ctx->verbose) {
log(" Destination wire: %s\n",
ctx->getWireName(dst_wire).c_str(ctx));
log(" Path delay estimate: %.2f\n",
float(ctx->estimateDelay(src_wire, dst_wire)));
}
route(src_wires, dst_wire);
if (visited.count(dst_wire) == 0) {
if (ctx->verbose)
@ -287,7 +311,7 @@ struct Router
ctx->bindWire(cursor, net_name);
ctx->bindPip(visited[cursor].pip, net_name);
src_wires[cursor] = ctx->getPipDelay(visited[cursor].pip);
src_wires[cursor] = visited[cursor].delay;
cursor = ctx->getPipSrcWire(visited[cursor].pip);
}
}