Integrating SA placer and legaliser

Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
David Shah 2018-06-29 13:12:44 +02:00
parent 17d6586189
commit b5f473cd7a
6 changed files with 103 additions and 15 deletions

View File

@ -21,6 +21,7 @@
#include <cmath> #include <cmath>
#include "log.h" #include "log.h"
#include "util.h" #include "util.h"
NEXTPNR_NAMESPACE_BEGIN NEXTPNR_NAMESPACE_BEGIN
// Get the total estimated wirelength for a net // 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->getBelType(bel) == targetType && (!require_legality || ctx->isValidBelForCell(cell, bel))) {
if (ctx->checkBelAvail(bel)) { if (ctx->checkBelAvail(bel)) {
wirelen_t wirelen = get_cell_wirelength_at_bel(ctx, cell, bel); wirelen_t wirelen = get_cell_wirelength_at_bel(ctx, cell, bel);
if (wirelen == 0)
wirelen = ctx->rng(100);
if (wirelen <= best_wirelen) { if (wirelen <= best_wirelen) {
best_wirelen = wirelen; best_wirelen = wirelen;
best_bel = bel; best_bel = bel;
} }
} else { } else {
wirelen_t wirelen = get_cell_wirelength_at_bel(ctx, cell, bel); wirelen_t wirelen = get_cell_wirelength_at_bel(ctx, cell, bel);
if (wirelen == 0)
wirelen = ctx->rng(100);
if (wirelen <= best_ripup_wirelen) { if (wirelen <= best_ripup_wirelen) {
ripup_target = ctx->cells.at(ctx->getBoundBelCell(bel)).get(); ripup_target = ctx->cells.at(ctx->getBoundBelCell(bel)).get();
if (ripup_target->belStrength < STRENGTH_STRONG) { 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 (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)); log_error("failed to place cell '%s' of type '%s'\n", cell->name.c_str(ctx), cell->type.c_str(ctx));
} }
--iters; --iters;

View File

@ -38,7 +38,8 @@
#include <vector> #include <vector>
#include "log.h" #include "log.h"
#include "place_common.h" #include "place_common.h"
#include "place_legaliser.h"
#include "util.h"
NEXTPNR_NAMESPACE_BEGIN NEXTPNR_NAMESPACE_BEGIN
class SAPlacer 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 // Recalculate total wirelength entirely to avoid rounding errors
// accumulating over time // accumulating over time
curr_wirelength = 0; curr_wirelength = 0;
@ -254,7 +266,7 @@ class SAPlacer
} }
BelType targetType = ctx->belTypeFromId(cell->type); BelType targetType = ctx->belTypeFromId(cell->type);
for (auto bel : ctx->getBels()) { 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)) { if (ctx->checkBelAvail(bel)) {
uint64_t score = ctx->rng64(); uint64_t score = ctx->rng64();
if (score <= best_score) { if (score <= best_score) {
@ -298,10 +310,14 @@ class SAPlacer
BelId oldBel = cell->bel; BelId oldBel = cell->bel;
IdString other = ctx->getBoundBelCell(newBel); IdString other = ctx->getBoundBelCell(newBel);
CellInfo *other_cell = nullptr; 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; wirelen_t new_wirelength = 0, delta;
ctx->unbindBel(oldBel); ctx->unbindBel(oldBel);
if (other != IdString()) { if (other != IdString()) {
other_cell = ctx->cells[other].get();
ctx->unbindBel(newBel); ctx->unbindBel(newBel);
} }
@ -320,12 +336,13 @@ class SAPlacer
if (other != IdString()) { if (other != IdString()) {
ctx->bindBel(oldBel, other_cell->name, STRENGTH_WEAK); ctx->bindBel(oldBel, other_cell->name, STRENGTH_WEAK);
} }
if (require_legal) {
if (!ctx->isBelLocationValid(newBel) || ((other != IdString() && !ctx->isBelLocationValid(oldBel)))) { if (!ctx->isBelLocationValid(newBel) || ((other != IdString() && !ctx->isBelLocationValid(oldBel)))) {
ctx->unbindBel(newBel); ctx->unbindBel(newBel);
if (other != IdString()) if (other != IdString())
ctx->unbindBel(oldBel); ctx->unbindBel(oldBel);
goto swap_fail; goto swap_fail;
}
} }
new_wirelength = curr_wirelength; new_wirelength = curr_wirelength;
@ -402,6 +419,8 @@ class SAPlacer
std::unordered_map<BelType, int> bel_types; std::unordered_map<BelType, int> bel_types;
std::vector<std::vector<std::vector<std::vector<BelId>>>> fast_bels; std::vector<std::vector<std::vector<std::vector<BelId>>>> fast_bels;
std::unordered_set<BelId> locked_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) bool place_design_sa(Context *ctx, bool timing_driven)

View File

@ -75,16 +75,18 @@ int main(int argc, char *argv[])
} }
if (vm.count("help") || argc == 1) { if (vm.count("help") || argc == 1) {
std::cout << boost::filesystem::basename(argv[0]) << " -- Next Generation Place and Route (git " std::cout << boost::filesystem::basename(argv[0])
"sha1 " GIT_COMMIT_HASH_STR ")\n"; << " -- Next Generation Place and Route (git "
"sha1 " GIT_COMMIT_HASH_STR ")\n";
std::cout << "\n"; std::cout << "\n";
std::cout << options << "\n"; std::cout << options << "\n";
return argc != 1; return argc != 1;
} }
if (vm.count("version")) { if (vm.count("version")) {
std::cout << boost::filesystem::basename(argv[0]) << " -- Next Generation Place and Route (git " std::cout << boost::filesystem::basename(argv[0])
"sha1 " GIT_COMMIT_HASH_STR ")\n"; << " -- Next Generation Place and Route (git "
"sha1 " GIT_COMMIT_HASH_STR ")\n";
return 1; return 1;
} }

28
dummy/place_legaliser.cc Normal file
View File

@ -0,0 +1,28 @@
/*
* nextpnr -- Next Generation Place and Route
*
* Copyright (C) 2018 David Shah <david@symbioticeda.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#include "place_legaliser.h"
NEXTPNR_NAMESPACE_BEGIN
bool legalise_design(Context *ctx) {
return true;
}
NEXTPNR_NAMESPACE_END

31
dummy/place_legaliser.h Normal file
View File

@ -0,0 +1,31 @@
/*
* nextpnr -- Next Generation Place and Route
*
* Copyright (C) 2018 David Shah <david@symbioticeda.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#ifndef PLACE_LEGALISER_H
#define PLACE_LEGALISER_H
#include "nextpnr.h"
NEXTPNR_NAMESPACE_BEGIN
bool legalise_design(Context *ctx);
NEXTPNR_NAMESPACE_END
#endif

View File

@ -372,7 +372,6 @@ int main(int argc, char *argv[])
if (!vm.count("pack-only")) { if (!vm.count("pack-only")) {
if (!place_design_sa(&ctx, timing_driven) && !ctx.force) if (!place_design_sa(&ctx, timing_driven) && !ctx.force)
log_error("Placing design failed.\n"); log_error("Placing design failed.\n");
legalise_design(&ctx);
ctx.check(); ctx.check();
if (!route_design(&ctx) && !ctx.force) if (!route_design(&ctx) && !ctx.force)
log_error("Routing design failed.\n"); log_error("Routing design failed.\n");