Minor refactoring of router infrastructure
Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
parent
d5a032d00e
commit
3fda636e70
206
common/route.cc
206
common/route.cc
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user