diff options
| -rw-r--r-- | common/nextpnr.cc | 22 | ||||
| -rw-r--r-- | common/nextpnr.h | 8 | ||||
| -rw-r--r-- | common/place_common.cc | 8 | ||||
| -rw-r--r-- | common/place_common.h | 3 | ||||
| -rw-r--r-- | common/placer1.cc | 21 | ||||
| -rw-r--r-- | common/placer_heap.cc | 19 | 
6 files changed, 43 insertions, 38 deletions
| diff --git a/common/nextpnr.cc b/common/nextpnr.cc index 9a73affc..dd1ebc59 100644 --- a/common/nextpnr.cc +++ b/common/nextpnr.cc @@ -223,6 +223,28 @@ void CellInfo::unsetParam(IdString name) { params.erase(name); }  void CellInfo::setAttr(IdString name, Property value) { attrs[name] = value; }  void CellInfo::unsetAttr(IdString name) { attrs.erase(name); } +bool CellInfo::isConstrained(bool include_abs_z_constr) const +{ +    return constr_parent != nullptr || !constr_children.empty() || (include_abs_z_constr && constr_abs_z); +} + +bool CellInfo::testRegion(BelId bel) const +{ +    return region == nullptr || !region->constr_bels || region->bels.count(bel); +} +Loc CellInfo::getConstrainedLoc(Loc parent_loc) const +{ +    NPNR_ASSERT(constr_parent != nullptr); +    Loc cloc = parent_loc; +    if (constr_x != UNCONSTR) +        cloc.x += constr_x; +    if (constr_y != UNCONSTR) +        cloc.y += constr_y; +    if (constr_z != UNCONSTR) +        cloc.z = constr_abs_z ? constr_z : (parent_loc.z + constr_z); +    return cloc; +} +  std::string Property::to_string() const  {      if (is_string) { diff --git a/common/nextpnr.h b/common/nextpnr.h index c2fe5192..ed227fb6 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -664,6 +664,14 @@ struct CellInfo : ArchCellInfo      void unsetParam(IdString name);      void setAttr(IdString name, Property value);      void unsetAttr(IdString name); + +    // return true if the cell has placement constraints (optionally excluding the case where the only case is an +    // absolute z constraint) +    bool isConstrained(bool include_abs_z_constr = true) const; +    // check whether a bel complies with the cell's region constraint +    bool testRegion(BelId bel) const; +    // get the constrained location for this cell given a provisional location for its parent +    Loc getConstrainedLoc(Loc parent_loc) const;  };  enum TimingPortClass diff --git a/common/place_common.cc b/common/place_common.cc index e5b48ffb..31b93420 100644 --- a/common/place_common.cc +++ b/common/place_common.cc @@ -536,12 +536,4 @@ 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 fa5ce4c2..434233fd 100644 --- a/common/place_common.h +++ b/common/place_common.h @@ -50,9 +50,6 @@ 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 270430e9..837010fe 100644 --- a/common/placer1.cc +++ b/common/placer1.cc @@ -504,12 +504,12 @@ class SAPlacer      {          static const double epsilon = 1e-20;          moveChange.reset(this); -        if (!require_legal && is_constrained(cell)) +        if (!require_legal && cell->isConstrained(false))              return false;          BelId oldBel = cell->bel;          CellInfo *other_cell = ctx->getBoundBelCell(newBel);          if (!require_legal && other_cell != nullptr && -            (is_constrained(other_cell) || other_cell->belStrength > STRENGTH_WEAK)) { +            (other_cell->isConstrained(false) || other_cell->belStrength > STRENGTH_WEAK)) {              return false;          }          int old_dist = get_constraints_distance(ctx, cell); @@ -589,11 +589,6 @@ class SAPlacer          return false;      } -    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)      { @@ -605,9 +600,9 @@ class SAPlacer          if (bound != nullptr)              ctx->unbindBel(newBel);          ctx->unbindBel(oldBel); -        ctx->bindBel(newBel, cell, is_constrained(cell) ? STRENGTH_STRONG : STRENGTH_WEAK); +        ctx->bindBel(newBel, cell, cell->isConstrained(false) ? STRENGTH_STRONG : STRENGTH_WEAK);          if (bound != nullptr) { -            ctx->bindBel(oldBel, bound, is_constrained(bound) ? STRENGTH_STRONG : STRENGTH_WEAK); +            ctx->bindBel(oldBel, bound, bound->isConstrained(false) ? STRENGTH_STRONG : STRENGTH_WEAK);              if (cfg.netShareWeight > 0)                  update_nets_by_tile(bound, ctx->getBelLocation(newBel), ctx->getBelLocation(oldBel));          } @@ -658,7 +653,7 @@ class SAPlacer              // 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))) +                (bound->belStrength >= STRENGTH_STRONG || bound->isConstrained(false)))                  return false;              dest_bels.emplace_back(std::make_pair(cr.first, targetBel));          } @@ -676,12 +671,12 @@ class SAPlacer                  add_move_cell(moveChange, bound, db.second);          }          for (const auto &mm : moves_made) { -            if (!ctx->isBelLocationValid(mm.first->bel) || !check_cell_bel_region(mm.first, mm.first->bel)) +            if (!ctx->isBelLocationValid(mm.first->bel) || !mm.first->testRegion(mm.first->bel))                  goto swap_fail;              if (!ctx->isBelLocationValid(mm.second))                  goto swap_fail;              CellInfo *bound = ctx->getBoundBelCell(mm.second); -            if (bound && !check_cell_bel_region(bound, bound->bel)) +            if (bound && !bound->testRegion(bound->bel))                  goto swap_fail;          }          compute_cost_changes(moveChange); @@ -752,7 +747,7 @@ class SAPlacer                  if (loc.z != force_z)                      continue;              } -            if (!check_cell_bel_region(cell, bel)) +            if (!cell->testRegion(bel))                  continue;              if (locked_bels.find(bel) != locked_bels.end())                  continue; diff --git a/common/placer_heap.cc b/common/placer_heap.cc index 0bd292f0..8a3b427f 100644 --- a/common/placer_heap.cc +++ b/common/placer_heap.cc @@ -937,7 +937,7 @@ class HeAPPlacer                      // The case where we have no relative constraints                      for (auto sz : fb->at(nx).at(ny)) {                          // Look through all bels in this tile; checking region constraint if applicable -                        if (ci->region != nullptr && ci->region->constr_bels && !ci->region->bels.count(sz)) +                        if (!ci->testRegion(sz))                              continue;                          // Prefer available bels; unless we are dealing with a wide radius (e.g. difficult control sets)                          // or occasionally trigger a tiebreaker @@ -945,8 +945,7 @@ class HeAPPlacer                              CellInfo *bound = ctx->getBoundBelCell(sz);                              if (bound != nullptr) {                                  // Only rip up cells without constraints -                                if (bound->constr_parent != nullptr || !bound->constr_children.empty() || -                                    bound->constr_abs_z) +                                if (bound->isConstrained())                                      continue;                                  ctx->unbindBel(bound->bel);                              } @@ -1020,7 +1019,7 @@ class HeAPPlacer                              // Get the bel we're going to place this cell at                              BelId target = ctx->getBelByLocation(ploc);                              // Check it satisfies the region constraint if applicable -                            if (vc->region != nullptr && vc->region->constr_bels && !vc->region->bels.count(target)) +                            if (!vc->testRegion(target))                                  goto fail;                              CellInfo *bound;                              // Check that the target bel exists and is of a suitable type @@ -1029,21 +1028,13 @@ class HeAPPlacer                              bound = ctx->getBoundBelCell(target);                              // Chains cannot overlap; so if we have to ripup a cell make sure it isn't part of a chain                              if (bound != nullptr) -                                if (bound->constr_z != bound->UNCONSTR || bound->constr_parent != nullptr || -                                    !bound->constr_children.empty() || bound->belStrength > STRENGTH_WEAK) +                                if (bound->isConstrained() || bound->belStrength > STRENGTH_WEAK)                                      goto fail;                              targets.emplace_back(vc, target);                              for (auto child : vc->constr_children) {                                  // For all the constrained children; compute the location we need to place them at and                                  // add them to the queue -                                Loc cloc = ploc; -                                if (child->constr_x != child->UNCONSTR) -                                    cloc.x += child->constr_x; -                                if (child->constr_y != child->UNCONSTR) -                                    cloc.y += child->constr_y; -                                if (child->constr_z != child->UNCONSTR) -                                    cloc.z = child->constr_abs_z ? child->constr_z : (ploc.z + child->constr_z); -                                visit.emplace(child, cloc); +                                visit.emplace(child, child->getConstrainedLoc(ploc));                              }                          }                          // Actually perform the move; keeping track of the moves we make so we can revert them if needed | 
