placer1: Improve handling of regions
Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
parent
a8289b699f
commit
0118ac00c4
@ -115,7 +115,29 @@ class SAPlacer
|
|||||||
net.second->udata = n++;
|
net.second->udata = n++;
|
||||||
net_by_udata.push_back(net.second.get());
|
net_by_udata.push_back(net.second.get());
|
||||||
}
|
}
|
||||||
|
for (auto ®ion : sorted(ctx->region)) {
|
||||||
|
Region *r = region.second;
|
||||||
|
BoundingBox bb;
|
||||||
|
if (r->constr_bels) {
|
||||||
|
bb.x0 = std::numeric_limits<int>::max();
|
||||||
|
bb.x1 = std::numeric_limits<int>::min();
|
||||||
|
bb.y0 = std::numeric_limits<int>::max();
|
||||||
|
bb.y1 = std::numeric_limits<int>::min();
|
||||||
|
for (auto bel : r->bels) {
|
||||||
|
Loc loc = ctx->getBelLocation(bel);
|
||||||
|
bb.x0 = std::min(bb.x0, loc.x);
|
||||||
|
bb.x1 = std::max(bb.x1, loc.x);
|
||||||
|
bb.y0 = std::min(bb.y0, loc.y);
|
||||||
|
bb.y1 = std::max(bb.y1, loc.y);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bb.x0 = 0;
|
||||||
|
bb.y0 = 0;
|
||||||
|
bb.x1 = max_x;
|
||||||
|
bb.y1 = max_y;
|
||||||
|
}
|
||||||
|
region_bounds[r->name] = bb;
|
||||||
|
}
|
||||||
build_port_index();
|
build_port_index();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,7 +404,8 @@ class SAPlacer
|
|||||||
ctx->unbindBel(cell->bel);
|
ctx->unbindBel(cell->bel);
|
||||||
}
|
}
|
||||||
IdString targetType = cell->type;
|
IdString targetType = cell->type;
|
||||||
for (auto bel : ctx->getBels()) {
|
|
||||||
|
auto proc_bel = [&](BelId bel) {
|
||||||
if (ctx->getBelType(bel) == targetType && ctx->isValidBelForCell(cell, bel)) {
|
if (ctx->getBelType(bel) == targetType && ctx->isValidBelForCell(cell, bel)) {
|
||||||
if (ctx->checkBelAvail(bel)) {
|
if (ctx->checkBelAvail(bel)) {
|
||||||
uint64_t score = ctx->rng64();
|
uint64_t score = ctx->rng64();
|
||||||
@ -400,7 +423,18 @@ class SAPlacer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (cell->region != nullptr && cell->region->constr_bels) {
|
||||||
|
for (auto bel : cell->region->bels) {
|
||||||
|
proc_bel(bel);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (auto bel : ctx->getBels()) {
|
||||||
|
proc_bel(bel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (best_bel == BelId()) {
|
if (best_bel == BelId()) {
|
||||||
if (iters == 0 || ripup_bel == BelId())
|
if (iters == 0 || 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));
|
||||||
@ -593,9 +627,22 @@ class SAPlacer
|
|||||||
{
|
{
|
||||||
IdString targetType = cell->type;
|
IdString targetType = cell->type;
|
||||||
Loc curr_loc = ctx->getBelLocation(cell->bel);
|
Loc curr_loc = ctx->getBelLocation(cell->bel);
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
int dx = diameter, dy = diameter;
|
||||||
|
if (cell->region != nullptr && cell->region->constr_bels) {
|
||||||
|
dx = std::min(diameter, (region_bounds[cell->region->name].x1 - region_bounds[cell->region->name].x0) + 1);
|
||||||
|
dy = std::min(diameter, (region_bounds[cell->region->name].y1 - region_bounds[cell->region->name].y0) + 1);
|
||||||
|
// Clamp location to within bounds
|
||||||
|
curr_loc.x = std::max(region_bounds[cell->region->name].x0, curr_loc.x);
|
||||||
|
curr_loc.x = std::min(region_bounds[cell->region->name].x1, curr_loc.x);
|
||||||
|
curr_loc.y = std::max(region_bounds[cell->region->name].y0, curr_loc.y);
|
||||||
|
curr_loc.y = std::min(region_bounds[cell->region->name].y1, curr_loc.y);
|
||||||
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
int nx = ctx->rng(2 * diameter + 1) + std::max(curr_loc.x - diameter, 0);
|
int nx = ctx->rng(2 * dx + 1) + std::max(curr_loc.x - dx, 0);
|
||||||
int ny = ctx->rng(2 * diameter + 1) + std::max(curr_loc.y - diameter, 0);
|
int ny = ctx->rng(2 * dy + 1) + std::max(curr_loc.y - dy, 0);
|
||||||
int beltype_idx, beltype_cnt;
|
int beltype_idx, beltype_cnt;
|
||||||
std::tie(beltype_idx, beltype_cnt) = bel_types.at(targetType);
|
std::tie(beltype_idx, beltype_cnt) = bel_types.at(targetType);
|
||||||
if (beltype_cnt < cfg.minBelsForGridPick)
|
if (beltype_cnt < cfg.minBelsForGridPick)
|
||||||
@ -617,6 +664,7 @@ class SAPlacer
|
|||||||
continue;
|
continue;
|
||||||
if (locked_bels.find(bel) != locked_bels.end())
|
if (locked_bels.find(bel) != locked_bels.end())
|
||||||
continue;
|
continue;
|
||||||
|
count++;
|
||||||
return bel;
|
return bel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -842,6 +890,7 @@ class SAPlacer
|
|||||||
int n_move, n_accept;
|
int n_move, n_accept;
|
||||||
int diameter = 35, max_x = 1, max_y = 1;
|
int diameter = 35, max_x = 1, max_y = 1;
|
||||||
std::unordered_map<IdString, std::tuple<int, int>> bel_types;
|
std::unordered_map<IdString, std::tuple<int, int>> bel_types;
|
||||||
|
std::unordered_map<IdString, BoundingBox> region_bounds;
|
||||||
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;
|
||||||
std::vector<NetInfo *> net_by_udata;
|
std::vector<NetInfo *> net_by_udata;
|
||||||
|
Loading…
Reference in New Issue
Block a user