diff options
| -rw-r--r-- | common/placer1.cc | 57 | 
1 files changed, 53 insertions, 4 deletions
| diff --git a/common/placer1.cc b/common/placer1.cc index 416c0d31..e4fa0320 100644 --- a/common/placer1.cc +++ b/common/placer1.cc @@ -115,7 +115,29 @@ class SAPlacer              net.second->udata = n++;              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();      } @@ -382,7 +404,8 @@ class SAPlacer                  ctx->unbindBel(cell->bel);              }              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->checkBelAvail(bel)) {                          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 (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)); @@ -593,9 +627,22 @@ class SAPlacer      {          IdString targetType = cell->type;          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) { -            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 nx = ctx->rng(2 * dx + 1) + std::max(curr_loc.x - dx, 0); +            int ny = ctx->rng(2 * dy + 1) + std::max(curr_loc.y - dy, 0);              int beltype_idx, beltype_cnt;              std::tie(beltype_idx, beltype_cnt) = bel_types.at(targetType);              if (beltype_cnt < cfg.minBelsForGridPick) @@ -617,6 +664,7 @@ class SAPlacer                  continue;              if (locked_bels.find(bel) != locked_bels.end())                  continue; +            count++;              return bel;          }      } @@ -842,6 +890,7 @@ class SAPlacer      int n_move, n_accept;      int diameter = 35, max_x = 1, max_y = 1;      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::unordered_set<BelId> locked_bels;      std::vector<NetInfo *> net_by_udata; | 
