aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/nextpnr.h2
-rw-r--r--common/place_common.cc22
-rw-r--r--common/placer1.cc32
-rw-r--r--common/timing.cc19
4 files changed, 48 insertions, 27 deletions
diff --git a/common/nextpnr.h b/common/nextpnr.h
index 5704e258..a6617ae4 100644
--- a/common/nextpnr.h
+++ b/common/nextpnr.h
@@ -191,7 +191,7 @@ struct Loc
Loc(int x, int y, int z) : x(x), y(y), z(z) {}
bool operator==(const Loc &other) const { return (x == other.x) && (y == other.y) && (z == other.z); }
- bool operator!=(const Loc &other) const { return (x != other.x) || (y != other.y) || (z == other.z); }
+ bool operator!=(const Loc &other) const { return (x != other.x) || (y != other.y) || (z != other.z); }
};
struct TimingConstrObjectId
diff --git a/common/place_common.cc b/common/place_common.cc
index 04e9b7d0..a13a963c 100644
--- a/common/place_common.cc
+++ b/common/place_common.cc
@@ -431,12 +431,12 @@ class ConstraintLegaliseWorker
print_chain(child, depth + 1);
}
- void print_stats(const char *point)
+ unsigned print_stats(const char *point)
{
float distance_sum = 0;
float max_distance = 0;
- int moved_cells = 0;
- int unplaced_cells = 0;
+ unsigned moved_cells = 0;
+ unsigned unplaced_cells = 0;
for (auto orig : oldLocations) {
if (ctx->cells.at(orig.first)->bel == BelId()) {
unplaced_cells++;
@@ -456,9 +456,10 @@ class ConstraintLegaliseWorker
log_info(" average distance %f\n", (distance_sum / moved_cells));
log_info(" maximum distance %f\n", max_distance);
}
+ return moved_cells + unplaced_cells;
}
- bool legalise_constraints()
+ int legalise_constraints()
{
log_info("Legalising relative constraints...\n");
for (auto cell : sorted(ctx->cells)) {
@@ -470,27 +471,28 @@ class ConstraintLegaliseWorker
if (ctx->verbose)
print_chain(cell.second);
log_error("failed to place chain starting at cell '%s'\n", cell.first.c_str(ctx));
- return false;
+ return -1;
}
}
- print_stats("after legalising chains");
+ if (print_stats("legalising chains") == 0)
+ return 0;
for (auto rippedCell : rippedCells) {
bool res = place_single_cell(ctx, ctx->cells.at(rippedCell).get(), true);
if (!res) {
log_error("failed to place cell '%s' after relative constraint legalisation\n", rippedCell.c_str(ctx));
- return false;
+ return -1;
}
}
- print_stats("after replacing ripped up cells");
+ auto score = print_stats("replacing ripped up cells");
for (auto cell : sorted(ctx->cells))
if (get_constraints_distance(ctx, cell.second) != 0)
log_error("constraint satisfaction check failed for cell '%s' at Bel '%s'\n", cell.first.c_str(ctx),
ctx->getBelName(cell.second->bel).c_str(ctx));
- return true;
+ return score;
}
};
-bool legalise_relative_constraints(Context *ctx) { return ConstraintLegaliseWorker(ctx).legalise_constraints(); }
+bool legalise_relative_constraints(Context *ctx) { return ConstraintLegaliseWorker(ctx).legalise_constraints() > 0; }
// Get the total distance from satisfied constraints for a cell
int get_constraints_distance(const Context *ctx, const CellInfo *cell)
diff --git a/common/placer1.cc b/common/placer1.cc
index 0d7c0701..0fd9a227 100644
--- a/common/placer1.cc
+++ b/common/placer1.cc
@@ -244,21 +244,23 @@ class SAPlacer
}
// Once cooled below legalise threshold, run legalisation and start requiring
// legal moves only
- if (temp < legalise_temp && !require_legal) {
- legalise_relative_constraints(ctx);
- require_legal = true;
- autoplaced.clear();
- for (auto cell : sorted(ctx->cells)) {
- if (cell.second->belStrength < STRENGTH_STRONG)
- autoplaced.push_back(cell.second);
- }
- temp = post_legalise_temp;
- diameter *= post_legalise_dia_scale;
- ctx->shuffle(autoplaced);
+ if (temp < legalise_temp && require_legal) {
+ if (legalise_relative_constraints(ctx)) {
+ // Only increase temperature if something was moved
+ autoplaced.clear();
+ for (auto cell : sorted(ctx->cells)) {
+ if (cell.second->belStrength < STRENGTH_STRONG)
+ autoplaced.push_back(cell.second);
+ }
+ temp = post_legalise_temp;
+ diameter *= post_legalise_dia_scale;
+ ctx->shuffle(autoplaced);
- // Legalisation is a big change so force a slack redistribution here
- if (ctx->slack_redist_iter > 0)
- assign_budget(ctx, true /* quiet */);
+ // Legalisation is a big change so force a slack redistribution here
+ if (ctx->slack_redist_iter > 0)
+ assign_budget(ctx, true /* quiet */);
+ }
+ require_legal = false;
} else if (ctx->slack_redist_iter > 0 && iter % ctx->slack_redist_iter == 0) {
assign_budget(ctx, true /* quiet */);
}
@@ -486,7 +488,7 @@ class SAPlacer
std::unordered_map<IdString, int> bel_types;
std::vector<std::vector<std::vector<std::vector<BelId>>>> fast_bels;
std::unordered_set<BelId> locked_bels;
- bool require_legal = false;
+ bool require_legal = true;
const float legalise_temp = 1;
const float post_legalise_temp = 10;
const float post_legalise_dia_scale = 1.5;
diff --git a/common/timing.cc b/common/timing.cc
index 1d3fec56..b414c6f7 100644
--- a/common/timing.cc
+++ b/common/timing.cc
@@ -634,7 +634,24 @@ void timing_analysis(Context *ctx, bool print_histogram, bool print_fmax, bool p
log_info("%4.1f %4.1f Net %s budget %f ns (%d,%d) -> (%d,%d)\n", ctx->getDelayNS(net_delay),
ctx->getDelayNS(total), net->name.c_str(ctx), ctx->getDelayNS(sink->budget), driver_loc.x,
driver_loc.y, sink_loc.x, sink_loc.y);
- log_info(" Sink %s.%s\n", sink_cell->name.c_str(ctx), sink->port.c_str(ctx));
+ log_info(" Sink %s.%s\n", sink_cell->name.c_str(ctx), sink->port.c_str(ctx));
+ if (ctx->verbose) {
+ auto driver_wire = ctx->getNetinfoSourceWire(net);
+ auto sink_wire = ctx->getNetinfoSinkWire(net, *sink);
+ log_info(" prediction: %f ns estimate: %f ns\n",
+ ctx->getDelayNS(ctx->predictDelay(net, *sink)), ctx->getDelayNS(ctx->estimateDelay(driver_wire, sink_wire)));
+ auto cursor = sink_wire;
+ delay_t delay;
+ while (driver_wire != cursor) {
+ auto it = net->wires.find(cursor);
+ assert(it != net->wires.end());
+ auto pip = it->second.pip;
+ NPNR_ASSERT(pip != PipId());
+ delay = ctx->getPipDelay(pip).maxDelay();
+ log_info(" %1.3f %s\n", ctx->getDelayNS(delay), ctx->getPipName(pip).c_str(ctx));
+ cursor = ctx->getPipSrcWire(pip);
+ }
+ }
last_port = sink->port;
}
};