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 <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;
|
||||||
|
@ -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)
|
||||||
|
@ -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
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 (!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");
|
||||||
|
Loading…
Reference in New Issue
Block a user