Fixes and improvements in new router
Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
parent
aeaa0552ba
commit
f0a3a272ca
@ -67,7 +67,7 @@ struct QueuedWire
|
|||||||
WireId wire;
|
WireId wire;
|
||||||
PipId pip;
|
PipId pip;
|
||||||
|
|
||||||
delay_t delay = 0, penalty = 0, togo = 0;
|
delay_t delay = 0, penalty = 0, bonus = 0, togo = 0;
|
||||||
int randtag = 0;
|
int randtag = 0;
|
||||||
|
|
||||||
struct Greater
|
struct Greater
|
||||||
@ -76,6 +76,10 @@ struct QueuedWire
|
|||||||
{
|
{
|
||||||
delay_t l = lhs.delay + lhs.penalty + lhs.togo;
|
delay_t l = lhs.delay + lhs.penalty + lhs.togo;
|
||||||
delay_t r = rhs.delay + rhs.penalty + rhs.togo;
|
delay_t r = rhs.delay + rhs.penalty + rhs.togo;
|
||||||
|
NPNR_ASSERT(l >= 0);
|
||||||
|
NPNR_ASSERT(r >= 0);
|
||||||
|
l -= lhs.bonus;
|
||||||
|
r -= rhs.bonus;
|
||||||
return l == r ? lhs.randtag > rhs.randtag : l > r;
|
return l == r ? lhs.randtag > rhs.randtag : l > r;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -304,6 +308,7 @@ struct Router1
|
|||||||
int visitCnt = 0;
|
int visitCnt = 0;
|
||||||
int maxVisitCnt = INT_MAX;
|
int maxVisitCnt = INT_MAX;
|
||||||
delay_t best_est = 0;
|
delay_t best_est = 0;
|
||||||
|
delay_t best_score = -1;
|
||||||
|
|
||||||
{
|
{
|
||||||
QueuedWire qw;
|
QueuedWire qw;
|
||||||
@ -311,6 +316,7 @@ struct Router1
|
|||||||
qw.pip = PipId();
|
qw.pip = PipId();
|
||||||
qw.delay = ctx->getWireDelay(qw.wire).maxDelay();
|
qw.delay = ctx->getWireDelay(qw.wire).maxDelay();
|
||||||
qw.penalty = 0;
|
qw.penalty = 0;
|
||||||
|
qw.bonus = 0;
|
||||||
if (cfg.useEstimate) {
|
if (cfg.useEstimate) {
|
||||||
qw.togo = ctx->estimateDelay(qw.wire, dst_wire);
|
qw.togo = ctx->estimateDelay(qw.wire, dst_wire);
|
||||||
best_est = qw.delay + qw.togo;
|
best_est = qw.delay + qw.togo;
|
||||||
@ -329,6 +335,7 @@ struct Router1
|
|||||||
for (auto pip : ctx->getPipsDownhill(qw.wire)) {
|
for (auto pip : ctx->getPipsDownhill(qw.wire)) {
|
||||||
delay_t next_delay = qw.delay + ctx->getPipDelay(pip).maxDelay();
|
delay_t next_delay = qw.delay + ctx->getPipDelay(pip).maxDelay();
|
||||||
delay_t next_penalty = qw.penalty;
|
delay_t next_penalty = qw.penalty;
|
||||||
|
delay_t next_bonus = qw.bonus;
|
||||||
|
|
||||||
WireId next_wire = ctx->getPipDstWire(pip);
|
WireId next_wire = ctx->getPipDstWire(pip);
|
||||||
next_delay += ctx->getWireDelay(next_wire).maxDelay();
|
next_delay += ctx->getWireDelay(next_wire).maxDelay();
|
||||||
@ -340,7 +347,7 @@ struct Router1
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ripupWireNet == net_info) {
|
if (ripupWireNet == net_info) {
|
||||||
next_penalty += cfg.wireReusePenalty;
|
next_bonus += cfg.wireReuseBonus;
|
||||||
} else {
|
} else {
|
||||||
if (!ripup)
|
if (!ripup)
|
||||||
continue;
|
continue;
|
||||||
@ -348,6 +355,8 @@ struct Router1
|
|||||||
auto scores_it = wireScores.find(next_wire);
|
auto scores_it = wireScores.find(next_wire);
|
||||||
if (scores_it != wireScores.end())
|
if (scores_it != wireScores.end())
|
||||||
next_penalty += scores_it->second * cfg.wireRipupPenalty;
|
next_penalty += scores_it->second * cfg.wireRipupPenalty;
|
||||||
|
else
|
||||||
|
next_penalty += cfg.wireRipupPenalty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,7 +367,7 @@ struct Router1
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ripupPipNet == net_info) {
|
if (ripupPipNet == net_info) {
|
||||||
next_penalty += cfg.pipReusePenalty;
|
next_bonus += cfg.pipReuseBonus;
|
||||||
} else {
|
} else {
|
||||||
if (!ripup)
|
if (!ripup)
|
||||||
continue;
|
continue;
|
||||||
@ -366,17 +375,36 @@ struct Router1
|
|||||||
auto scores_it = pipScores.find(pip);
|
auto scores_it = pipScores.find(pip);
|
||||||
if (scores_it != pipScores.end())
|
if (scores_it != pipScores.end())
|
||||||
next_penalty += scores_it->second * cfg.pipRipupPenalty;
|
next_penalty += scores_it->second * cfg.pipRipupPenalty;
|
||||||
|
else
|
||||||
|
next_penalty += cfg.pipRipupPenalty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (visited.count(next_wire)) {
|
delay_t next_score = next_delay + next_penalty;
|
||||||
if (visited.at(next_wire).delay + visited.at(next_wire).penalty <= next_delay + next_penalty + ctx->getDelayEpsilon())
|
NPNR_ASSERT(next_score >= 0);
|
||||||
|
|
||||||
|
if ((best_score >= 0) && (next_score - next_bonus - cfg.estimatePrecision > best_score))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto old_visited_it = visited.find(next_wire);
|
||||||
|
if (old_visited_it != visited.end()) {
|
||||||
|
delay_t old_delay = old_visited_it->second.delay;
|
||||||
|
delay_t old_score = old_delay + old_visited_it->second.penalty;
|
||||||
|
NPNR_ASSERT(old_score >= 0);
|
||||||
|
|
||||||
|
if (next_score + ctx->getDelayEpsilon() >= old_score)
|
||||||
continue;
|
continue;
|
||||||
#if 0 // FIXME
|
|
||||||
|
if (next_delay + ctx->getDelayEpsilon() >= old_delay)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (ctx->debug)
|
if (ctx->debug)
|
||||||
log("Found better route to %s. Old vs new delay estimate: %.3f %.3f\n",
|
log("Found better route to %s. Old vs new delay estimate: %.3f (%.3f) %.3f (%.3f)\n",
|
||||||
ctx->getWireName(next_wire).c_str(),
|
ctx->getWireName(next_wire).c_str(ctx),
|
||||||
ctx->getDelayNS(visited.at(next_wire).delay),
|
ctx->getDelayNS(old_score),
|
||||||
|
ctx->getDelayNS(old_visited_it->second.delay),
|
||||||
|
ctx->getDelayNS(next_score),
|
||||||
ctx->getDelayNS(next_delay));
|
ctx->getDelayNS(next_delay));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -386,21 +414,34 @@ struct Router1
|
|||||||
next_qw.pip = pip;
|
next_qw.pip = pip;
|
||||||
next_qw.delay = next_delay;
|
next_qw.delay = next_delay;
|
||||||
next_qw.penalty = next_penalty;
|
next_qw.penalty = next_penalty;
|
||||||
|
next_qw.bonus = next_bonus;
|
||||||
if (cfg.useEstimate) {
|
if (cfg.useEstimate) {
|
||||||
next_qw.togo = ctx->estimateDelay(next_wire, dst_wire);
|
next_qw.togo = ctx->estimateDelay(next_wire, dst_wire);
|
||||||
delay_t this_est = next_qw.delay + next_qw.togo;
|
delay_t this_est = next_qw.delay + next_qw.togo;
|
||||||
if (this_est > best_est + cfg.estimatePrecision)
|
if (this_est/2 - cfg.estimatePrecision > best_est)
|
||||||
continue;
|
continue;
|
||||||
if (best_est > this_est)
|
if (best_est > this_est)
|
||||||
best_est = this_est;
|
best_est = this_est;
|
||||||
}
|
}
|
||||||
next_qw.randtag = ctx->rng();
|
next_qw.randtag = ctx->rng();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (ctx->debug)
|
||||||
|
log("%s -> %s: %.3f (%.3f)\n",
|
||||||
|
ctx->getWireName(qw.wire).c_str(ctx),
|
||||||
|
ctx->getWireName(next_wire).c_str(ctx),
|
||||||
|
ctx->getDelayNS(next_score),
|
||||||
|
ctx->getDelayNS(next_delay));
|
||||||
|
#endif
|
||||||
|
|
||||||
visited[next_qw.wire] = next_qw;
|
visited[next_qw.wire] = next_qw;
|
||||||
queue.push(next_qw);
|
queue.push(next_qw);
|
||||||
|
|
||||||
if (maxVisitCnt == INT_MAX && next_wire == dst_wire)
|
if (next_wire == dst_wire) {
|
||||||
maxVisitCnt = 2*visitCnt;
|
if (maxVisitCnt == INT_MAX)
|
||||||
|
maxVisitCnt = 2*visitCnt;
|
||||||
|
best_score = next_score - next_bonus;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -478,8 +519,8 @@ Router1Cfg::Router1Cfg(Context *ctx) : Settings(ctx)
|
|||||||
wireRipupPenalty = ctx->getRipupDelayPenalty();
|
wireRipupPenalty = ctx->getRipupDelayPenalty();
|
||||||
pipRipupPenalty = ctx->getRipupDelayPenalty();
|
pipRipupPenalty = ctx->getRipupDelayPenalty();
|
||||||
|
|
||||||
wireReusePenalty = -wireRipupPenalty/8;
|
wireReuseBonus = wireRipupPenalty/8;
|
||||||
pipReusePenalty = -pipRipupPenalty/8;
|
pipReuseBonus = pipRipupPenalty/8;
|
||||||
|
|
||||||
estimatePrecision = 100 * ctx->getRipupDelayPenalty();
|
estimatePrecision = 100 * ctx->getRipupDelayPenalty();
|
||||||
}
|
}
|
||||||
|
@ -35,8 +35,8 @@ struct Router1Cfg : Settings
|
|||||||
bool useEstimate;
|
bool useEstimate;
|
||||||
delay_t wireRipupPenalty;
|
delay_t wireRipupPenalty;
|
||||||
delay_t pipRipupPenalty;
|
delay_t pipRipupPenalty;
|
||||||
delay_t wireReusePenalty;
|
delay_t wireReuseBonus;
|
||||||
delay_t pipReusePenalty;
|
delay_t pipReuseBonus;
|
||||||
delay_t estimatePrecision;
|
delay_t estimatePrecision;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user