Integrating SA placer and legaliser
Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
parent
17d6586189
commit
b5f473cd7a
@ -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;
|
||||
|
@ -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,13 +336,14 @@ class SAPlacer
|
||||
if (other != IdString()) {
|
||||
ctx->bindBel(oldBel, other_cell->name, STRENGTH_WEAK);
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -75,7 +75,8 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
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])
|
||||
<< " -- Next Generation Place and Route (git "
|
||||
"sha1 " GIT_COMMIT_HASH_STR ")\n";
|
||||
std::cout << "\n";
|
||||
std::cout << options << "\n";
|
||||
@ -83,7 +84,8 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (vm.count("version")) {
|
||||
std::cout << boost::filesystem::basename(argv[0]) << " -- Next Generation Place and Route (git "
|
||||
std::cout << boost::filesystem::basename(argv[0])
|
||||
<< " -- Next Generation Place and Route (git "
|
||||
"sha1 " GIT_COMMIT_HASH_STR ")\n";
|
||||
return 1;
|
||||
}
|
||||
|
28
dummy/place_legaliser.cc
Normal file
28
dummy/place_legaliser.cc
Normal 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
31
dummy/place_legaliser.h
Normal 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
|
@ -372,7 +372,6 @@ int main(int argc, char *argv[])
|
||||
if (!vm.count("pack-only")) {
|
||||
if (!place_design_sa(&ctx, timing_driven) && !ctx.force)
|
||||
log_error("Placing design failed.\n");
|
||||
legalise_design(&ctx);
|
||||
ctx.check();
|
||||
if (!route_design(&ctx) && !ctx.force)
|
||||
log_error("Routing design failed.\n");
|
||||
|
Loading…
Reference in New Issue
Block a user