aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorSylvain Munaut <tnt@246tNt.com>2018-11-17 19:19:32 +0100
committerSylvain Munaut <tnt@246tNt.com>2018-11-19 18:52:40 +0100
commitd6fd0e7e5b3d0d7eef4013c1b0547a3066b0a485 (patch)
tree92b98fa117c79f2d16fa2b8552cdb4b60348289c /common
parent1851ebb1c6b9edc2d8396494864fa7fa3b833c9d (diff)
downloadnextpnr-d6fd0e7e5b3d0d7eef4013c1b0547a3066b0a485.tar.gz
nextpnr-d6fd0e7e5b3d0d7eef4013c1b0547a3066b0a485.tar.bz2
nextpnr-d6fd0e7e5b3d0d7eef4013c1b0547a3066b0a485.zip
common/placer1: In random pick, only use grid if there is more than 64 BELs
If you have a large grid and very few BELs of a given type, picking a random grid location yields very little odds of finding a BEL of that type. So for those, just put all of them at (0,0) and do a true random pick. Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Diffstat (limited to 'common')
-rw-r--r--common/placer1.cc28
-rw-r--r--common/placer1.h1
2 files changed, 21 insertions, 8 deletions
diff --git a/common/placer1.cc b/common/placer1.cc
index 0fd9a227..0db7ce00 100644
--- a/common/placer1.cc
+++ b/common/placer1.cc
@@ -51,15 +51,20 @@ class SAPlacer
{
int num_bel_types = 0;
for (auto bel : ctx->getBels()) {
- Loc loc = ctx->getBelLocation(bel);
IdString type = ctx->getBelType(bel);
- int type_idx;
if (bel_types.find(type) == bel_types.end()) {
- type_idx = num_bel_types++;
- bel_types[type] = type_idx;
+ bel_types[type] = std::tuple<int, int>(num_bel_types++, 1);
} else {
- type_idx = bel_types.at(type);
+ std::get<1>(bel_types.at(type))++;
}
+ }
+ for (auto bel : ctx->getBels()) {
+ Loc loc = ctx->getBelLocation(bel);
+ IdString type = ctx->getBelType(bel);
+ int type_idx = std::get<0>(bel_types.at(type));
+ int type_cnt = std::get<1>(bel_types.at(type));
+ if (type_cnt < cfg.minBelsForGridPick)
+ loc.x = loc.y = 0;
if (int(fast_bels.size()) < type_idx + 1)
fast_bels.resize(type_idx + 1);
if (int(fast_bels.at(type_idx).size()) < (loc.x + 1))
@@ -463,7 +468,10 @@ class SAPlacer
while (true) {
int nx = ctx->rng(2 * diameter + 1) + std::max(curr_loc.x - diameter, 0);
int ny = ctx->rng(2 * diameter + 1) + std::max(curr_loc.y - diameter, 0);
- int beltype_idx = bel_types.at(targetType);
+ int beltype_idx, beltype_cnt;
+ std::tie(beltype_idx, beltype_cnt) = bel_types.at(targetType);
+ if (beltype_cnt < cfg.minBelsForGridPick)
+ nx = ny = 0;
if (nx >= int(fast_bels.at(beltype_idx).size()))
continue;
if (ny >= int(fast_bels.at(beltype_idx).at(nx).size()))
@@ -485,7 +493,7 @@ class SAPlacer
bool improved = false;
int n_move, n_accept;
int diameter = 35, max_x = 1, max_y = 1;
- std::unordered_map<IdString, int> bel_types;
+ 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;
bool require_legal = true;
@@ -503,7 +511,11 @@ class SAPlacer
std::vector<decltype(NetInfo::udata)> old_udata;
};
-Placer1Cfg::Placer1Cfg(Context *ctx) : Settings(ctx) { constraintWeight = get<float>("placer1/constraintWeight", 10); }
+Placer1Cfg::Placer1Cfg(Context *ctx) : Settings(ctx)
+{
+ constraintWeight = get<float>("placer1/constraintWeight", 10);
+ minBelsForGridPick = get<int>("placer1/minBelsForGridPick", 64);
+}
bool placer1(Context *ctx, Placer1Cfg cfg)
{
diff --git a/common/placer1.h b/common/placer1.h
index 55db1fa5..7305f4b1 100644
--- a/common/placer1.h
+++ b/common/placer1.h
@@ -28,6 +28,7 @@ struct Placer1Cfg : public Settings
{
Placer1Cfg(Context *ctx);
float constraintWeight;
+ int minBelsForGridPick;
};
extern bool placer1(Context *ctx, Placer1Cfg cfg);