aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorDavid Shah <davey1576@gmail.com>2018-06-29 13:12:44 +0200
committerDavid Shah <davey1576@gmail.com>2018-06-29 13:12:44 +0200
commitb5f473cd7a7412eb41e39cdf0b06dbcb6e4c137b (patch)
tree641009c51c9fdf91708f184b23fcb5d0c37afe71 /common
parent17d6586189a8c1433b6ff6048b7e33f7d46afcf2 (diff)
downloadnextpnr-b5f473cd7a7412eb41e39cdf0b06dbcb6e4c137b.tar.gz
nextpnr-b5f473cd7a7412eb41e39cdf0b06dbcb6e4c137b.tar.bz2
nextpnr-b5f473cd7a7412eb41e39cdf0b06dbcb6e4c137b.zip
Integrating SA placer and legaliser
Signed-off-by: David Shah <davey1576@gmail.com>
Diffstat (limited to 'common')
-rw-r--r--common/place_common.cc11
-rw-r--r--common/place_sa.cc37
2 files changed, 38 insertions, 10 deletions
diff --git a/common/place_common.cc b/common/place_common.cc
index 591985f1..12345a89 100644
--- a/common/place_common.cc
+++ b/common/place_common.cc
@@ -21,6 +21,7 @@
#include <cmath>
#include "log.h"
#include "util.h"
+
NEXTPNR_NAMESPACE_BEGIN
// Get the total estimated wirelength for a net
@@ -118,12 +119,16 @@ bool place_single_cell(Context *ctx, CellInfo *cell, bool require_legality)
if (ctx->getBelType(bel) == targetType && (!require_legality || ctx->isValidBelForCell(cell, bel))) {
if (ctx->checkBelAvail(bel)) {
wirelen_t wirelen = get_cell_wirelength_at_bel(ctx, cell, bel);
+ if (wirelen == 0)
+ wirelen = ctx->rng(100);
if (wirelen <= best_wirelen) {
best_wirelen = wirelen;
best_bel = bel;
}
} else {
wirelen_t wirelen = get_cell_wirelength_at_bel(ctx, cell, bel);
+ if (wirelen == 0)
+ wirelen = ctx->rng(100);
if (wirelen <= best_ripup_wirelen) {
ripup_target = ctx->cells.at(ctx->getBoundBelCell(bel)).get();
if (ripup_target->belStrength < STRENGTH_STRONG) {
@@ -135,7 +140,11 @@ bool place_single_cell(Context *ctx, CellInfo *cell, bool require_legality)
}
}
if (best_bel == BelId()) {
- if (iters == 0 || ripup_bel == BelId()) {
+ if (iters == 0) {
+ log_error("failed to place cell '%s' of type '%s' (ripup iteration limit exceeded)\n",
+ cell->name.c_str(ctx), cell->type.c_str(ctx));
+ }
+ if (ripup_bel == BelId()) {
log_error("failed to place cell '%s' of type '%s'\n", cell->name.c_str(ctx), cell->type.c_str(ctx));
}
--iters;
diff --git a/common/place_sa.cc b/common/place_sa.cc
index ed584d60..d8ab24ce 100644
--- a/common/place_sa.cc
+++ b/common/place_sa.cc
@@ -38,7 +38,8 @@
#include <vector>
#include "log.h"
#include "place_common.h"
-
+#include "place_legaliser.h"
+#include "util.h"
NEXTPNR_NAMESPACE_BEGIN
class SAPlacer
@@ -206,6 +207,17 @@ class SAPlacer
}
}
+ if (temp < legalise_temp && !require_legal) {
+ legalise_design(ctx);
+ require_legal = true;
+ autoplaced.clear();
+ for (auto cell : sorted(ctx->cells)) {
+ if (cell.second->belStrength < STRENGTH_STRONG)
+ autoplaced.push_back(cell.second);
+ }
+ ctx->shuffle(autoplaced);
+ }
+
// Recalculate total wirelength entirely to avoid rounding errors
// accumulating over time
curr_wirelength = 0;
@@ -254,7 +266,7 @@ class SAPlacer
}
BelType targetType = ctx->belTypeFromId(cell->type);
for (auto bel : ctx->getBels()) {
- if (ctx->getBelType(bel) == targetType && ctx->isValidBelForCell(cell, bel)) {
+ if (ctx->getBelType(bel) == targetType && (ctx->isValidBelForCell(cell, bel) || !require_legal)) {
if (ctx->checkBelAvail(bel)) {
uint64_t score = ctx->rng64();
if (score <= best_score) {
@@ -298,10 +310,14 @@ class SAPlacer
BelId oldBel = cell->bel;
IdString other = ctx->getBoundBelCell(newBel);
CellInfo *other_cell = nullptr;
+ if (other != IdString()) {
+ other_cell = ctx->cells[other].get();
+ if (other_cell->belStrength > STRENGTH_WEAK)
+ return false;
+ }
wirelen_t new_wirelength = 0, delta;
ctx->unbindBel(oldBel);
if (other != IdString()) {
- other_cell = ctx->cells[other].get();
ctx->unbindBel(newBel);
}
@@ -320,12 +336,13 @@ class SAPlacer
if (other != IdString()) {
ctx->bindBel(oldBel, other_cell->name, STRENGTH_WEAK);
}
-
- if (!ctx->isBelLocationValid(newBel) || ((other != IdString() && !ctx->isBelLocationValid(oldBel)))) {
- ctx->unbindBel(newBel);
- if (other != IdString())
- ctx->unbindBel(oldBel);
- goto swap_fail;
+ if (require_legal) {
+ if (!ctx->isBelLocationValid(newBel) || ((other != IdString() && !ctx->isBelLocationValid(oldBel)))) {
+ ctx->unbindBel(newBel);
+ if (other != IdString())
+ ctx->unbindBel(oldBel);
+ goto swap_fail;
+ }
}
new_wirelength = curr_wirelength;
@@ -402,6 +419,8 @@ class SAPlacer
std::unordered_map<BelType, int> bel_types;
std::vector<std::vector<std::vector<std::vector<BelId>>>> fast_bels;
std::unordered_set<BelId> locked_bels;
+ bool require_legal = false;
+ const float legalise_temp = 20;
};
bool place_design_sa(Context *ctx, bool timing_driven)