aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2018-12-13 14:27:33 +0000
committerDavid Shah <dave@ds0.me>2019-03-22 10:31:54 +0000
commitae33ff397f5bc97d047639a7fb76d5d888050cb2 (patch)
tree56a682fcf13f1126cab738780cc868108e22193b
parentade72de02faf72c2458b10dc94adf2326cc5c759 (diff)
downloadnextpnr-ae33ff397f5bc97d047639a7fb76d5d888050cb2.tar.gz
nextpnr-ae33ff397f5bc97d047639a7fb76d5d888050cb2.tar.bz2
nextpnr-ae33ff397f5bc97d047639a7fb76d5d888050cb2.zip
placer1: Consider regions during placement
Signed-off-by: David Shah <dave@ds0.me>
-rw-r--r--common/place_common.cc8
-rw-r--r--common/place_common.h4
-rw-r--r--common/placer1.cc42
3 files changed, 38 insertions, 16 deletions
diff --git a/common/place_common.cc b/common/place_common.cc
index 0a7b29c7..73a320d0 100644
--- a/common/place_common.cc
+++ b/common/place_common.cc
@@ -529,4 +529,12 @@ int get_constraints_distance(const Context *ctx, const CellInfo *cell)
return dist;
}
+bool check_cell_bel_region(const CellInfo *cell, BelId bel)
+{
+ if (cell->region != nullptr && cell->region->constr_bels && !cell->region->bels.count(bel))
+ return false;
+ else
+ return true;
+}
+
NEXTPNR_NAMESPACE_END
diff --git a/common/place_common.h b/common/place_common.h
index 79dec067..fa5ce4c2 100644
--- a/common/place_common.h
+++ b/common/place_common.h
@@ -49,6 +49,10 @@ bool legalise_relative_constraints(Context *ctx);
// Get the total distance from satisfied constraints for a cell
int get_constraints_distance(const Context *ctx, const CellInfo *cell);
+
+// Check that a Bel is within the region for a cell
+bool check_cell_bel_region(const CellInfo *cell, BelId bel);
+
NEXTPNR_NAMESPACE_END
#endif
diff --git a/common/placer1.cc b/common/placer1.cc
index dca9089a..416c0d31 100644
--- a/common/placer1.cc
+++ b/common/placer1.cc
@@ -44,7 +44,6 @@
#include "timing.h"
#include "util.h"
-
namespace std {
template <> struct hash<std::pair<NEXTPNR_NAMESPACE_PREFIX IdString, std::size_t>>
{
@@ -120,7 +119,8 @@ class SAPlacer
build_port_index();
}
- ~SAPlacer() {
+ ~SAPlacer()
+ {
for (auto &net : ctx->nets)
net.second->udata = old_udata[net.second->udata];
}
@@ -275,8 +275,8 @@ class SAPlacer
if (ctx->verbose)
log("iter #%d: temp = %f, timing cost = "
- "%.0f, wirelen = %.0f, dia = %d, Ra = %.02f \n",
- iter, temp, double(curr_timing_cost), double(curr_wirelen_cost), diameter, Raccept);
+ "%.0f, wirelen = %.0f, dia = %d, Ra = %.02f \n",
+ iter, temp, double(curr_timing_cost), double(curr_wirelen_cost), diameter, Raccept);
if (curr_wirelen_cost < 0.95 * avg_wirelen && curr_wirelen_cost > 0) {
avg_wirelen = 0.8 * avg_wirelen + 0.2 * curr_wirelen_cost;
@@ -301,7 +301,8 @@ class SAPlacer
autoplaced.clear();
chain_basis.clear();
for (auto cell : sorted(ctx->cells)) {
- if (cell.second->belStrength <= STRENGTH_STRONG && cell.second->constr_parent == nullptr && !cell.second->constr_children.empty())
+ if (cell.second->belStrength <= STRENGTH_STRONG && cell.second->constr_parent == nullptr &&
+ !cell.second->constr_children.empty())
chain_basis.push_back(cell.second);
else if (cell.second->belStrength < STRENGTH_STRONG)
autoplaced.push_back(cell.second);
@@ -484,12 +485,14 @@ class SAPlacer
return false;
}
- inline bool is_constrained(CellInfo *cell) {
+ inline bool is_constrained(CellInfo *cell)
+ {
return cell->constr_parent != nullptr || !cell->constr_children.empty();
}
// Swap the Bel of a cell with another, return the original location
- BelId swap_cell_bels(CellInfo *cell, BelId newBel) {
+ BelId swap_cell_bels(CellInfo *cell, BelId newBel)
+ {
BelId oldBel = cell->bel;
CellInfo *bound = ctx->getBoundBelCell(newBel);
if (bound != nullptr)
@@ -502,7 +505,8 @@ class SAPlacer
}
// Discover the relative positions of all cells in a chain
- void discover_chain(Loc baseLoc, CellInfo *cell, std::vector<std::pair<CellInfo*, Loc>> &cell_rel) {
+ void discover_chain(Loc baseLoc, CellInfo *cell, std::vector<std::pair<CellInfo *, Loc>> &cell_rel)
+ {
Loc cellLoc = ctx->getBelLocation(cell->bel);
Loc rel{cellLoc.x - baseLoc.x, cellLoc.y - baseLoc.y, cellLoc.z};
cell_rel.emplace_back(std::make_pair(cell, rel));
@@ -511,10 +515,11 @@ class SAPlacer
}
// Attempt to swap a chain with a non-chain
- bool try_swap_chain(CellInfo *cell, BelId newBase) {
+ bool try_swap_chain(CellInfo *cell, BelId newBase)
+ {
std::vector<std::pair<CellInfo *, Loc>> cell_rel;
std::unordered_set<IdString> cells;
- std::vector<std::pair<CellInfo*, BelId>> moves_made;
+ std::vector<std::pair<CellInfo *, BelId>> moves_made;
std::vector<std::pair<CellInfo *, BelId>> dest_bels;
double delta = 0;
moveChange.reset();
@@ -538,7 +543,8 @@ class SAPlacer
CellInfo *bound = ctx->getBoundBelCell(targetBel);
// We don't consider swapping chains with other chains, at least for the time being - unless it is
// part of this chain
- if (bound != nullptr && !cells.count(bound->name) && (bound->belStrength >= STRENGTH_STRONG || is_constrained(bound)))
+ if (bound != nullptr && !cells.count(bound->name) &&
+ (bound->belStrength >= STRENGTH_STRONG || is_constrained(bound)))
return false;
dest_bels.emplace_back(std::make_pair(cr.first, targetBel));
}
@@ -550,12 +556,14 @@ class SAPlacer
moves_made.emplace_back(std::make_pair(db.first, oldBel));
}
for (const auto &mm : moves_made) {
- if (!ctx->isBelLocationValid(mm.first->bel))
+ if (!ctx->isBelLocationValid(mm.first->bel) || !check_cell_bel_region(mm.first, mm.first->bel))
goto swap_fail;
if (!ctx->isBelLocationValid(mm.second))
goto swap_fail;
- add_move_cell(moveChange, mm.first, mm.second);
CellInfo *bound = ctx->getBoundBelCell(mm.second);
+ if (bound && !check_cell_bel_region(bound, bound->bel))
+ goto swap_fail;
+ add_move_cell(moveChange, mm.first, mm.second);
if (bound != nullptr)
add_move_cell(moveChange, bound, mm.first->bel);
}
@@ -573,7 +581,7 @@ class SAPlacer
}
commit_cost_changes(moveChange);
return true;
-swap_fail:
+ swap_fail:
for (const auto &entry : boost::adaptors::reverse(moves_made))
swap_cell_bels(entry.first, entry.second);
return false;
@@ -605,6 +613,8 @@ swap_fail:
if (loc.z != force_z)
continue;
}
+ if (!check_cell_bel_region(cell, bel))
+ continue;
if (locked_bels.find(bel) != locked_bels.end())
continue;
return bel;
@@ -834,7 +844,7 @@ swap_fail:
std::unordered_map<IdString, std::tuple<int, int>> bel_types;
std::vector<std::vector<std::vector<std::vector<BelId>>>> fast_bels;
std::unordered_set<BelId> locked_bels;
- std::vector<NetInfo*> net_by_udata;
+ std::vector<NetInfo *> net_by_udata;
std::vector<decltype(NetInfo::udata)> old_udata;
bool require_legal = true;
const float legalise_temp = 0.001;
@@ -848,7 +858,7 @@ Placer1Cfg::Placer1Cfg(Context *ctx) : Settings(ctx)
constraintWeight = get<float>("placer1/constraintWeight", 10);
minBelsForGridPick = get<int>("placer1/minBelsForGridPick", 64);
budgetBased = get<bool>("placer1/budgetBased", false);
- startTemp = get<float> ("placer1/startTemp", 1);
+ startTemp = get<float>("placer1/startTemp", 1);
}
bool placer1(Context *ctx, Placer1Cfg cfg)