@@ -242,9 +242,25 @@ bool Shape::cut(const ObstructionTree& obstructions,
242242 it != obstructions.qend ();
243243 it++) {
244244 const auto & other_shape = *it;
245+
246+ if (other_shape->net_ != nullptr && net_ == other_shape->net_ ) {
247+ // obstruction is of the same net, so see if the violation is completely
248+ // inside the new strap and therefore is okay
249+ if (is_horizontal) {
250+ if (rect_.yMin () <= other_shape->rect_ .yMin ()
251+ && rect_.yMax () >= other_shape->rect_ .yMax ()) {
252+ continue ;
253+ }
254+ } else {
255+ if (rect_.xMin () <= other_shape->rect_ .xMin ()
256+ && rect_.xMax () >= other_shape->rect_ .xMax ()) {
257+ continue ;
258+ }
259+ }
260+ }
261+
245262 odb::Rect vio_rect
246263 = other_shape->getRectWithLargestObstructionHalo (obs_halo);
247-
248264 // ensure the violation overlap fully with the shape to make cut correctly
249265 if (is_horizontal) {
250266 vio_rect.set_ylo (std::min (obs_.yMin (), vio_rect.yMin ()));
@@ -451,6 +467,33 @@ odb::dbBox* Shape::addBPinToDb(const odb::Rect& rect) const
451467
452468void Shape::populateMapFromDb (odb::dbNet* net, ShapeVectorMap& map)
453469{
470+ // collect fixed bterms
471+ for (auto * bterm : net->getBTerms ()) {
472+ for (auto * bpin : bterm->getBPins ()) {
473+ if (!bpin->getPlacementStatus ().isFixed ()) {
474+ continue ;
475+ }
476+ for (auto * box : bpin->getBoxes ()) {
477+ auto * layer = box->getTechLayer ();
478+ if (layer == nullptr ) {
479+ continue ;
480+ }
481+ if (layer->getRoutingLevel () == 0 ) {
482+ continue ;
483+ }
484+
485+ odb::Rect rect = box->getBox ();
486+
487+ ShapePtr shape = std::make_shared<Shape>(
488+ layer, net, rect, odb::dbWireShapeType::NONE);
489+ shape->setShapeType (Shape::FIXED);
490+ shape->generateObstruction ();
491+ map[layer].push_back (std::move (shape));
492+ }
493+ }
494+ }
495+
496+ // collect existing routing
454497 for (auto * swire : net->getSWires ()) {
455498 for (auto * box : swire->getWires ()) {
456499 auto * layer = box->getTechLayer ();
0 commit comments