diff --git a/src/drt/src/pa/FlexPA.h b/src/drt/src/pa/FlexPA.h index 605256f8162..3b934d86954 100644 --- a/src/drt/src/pa/FlexPA.h +++ b/src/drt/src/pa/FlexPA.h @@ -721,6 +721,7 @@ class FlexPA * * @param unique_inst unique inst */ + bool instPrefersHorizontal(frInst* unique_inst); void prepPatternInst(frInst* unique_inst); /** diff --git a/src/drt/src/pa/FlexPA_acc_pattern.cpp b/src/drt/src/pa/FlexPA_acc_pattern.cpp index 2afccc8f96d..69759da36ff 100644 --- a/src/drt/src/pa/FlexPA_acc_pattern.cpp +++ b/src/drt/src/pa/FlexPA_acc_pattern.cpp @@ -82,14 +82,42 @@ void FlexPA::addToInstsSet(frInst* inst) insts_set_.insert(inst); } +bool FlexPA::instPrefersHorizontal(frInst* unique_inst) +{ + const int pin_access_idx = unique_inst->getPinAccessIdx(); + // Positive if most access points are on Horizontal layers, Negative if on + // Vertical Layers + if (pin_access_idx < 0) { + return true; + } + int layer_direction_bias = 0; + const auto tech = getDesign()->getTech(); + for (auto& inst_term : unique_inst->getInstTerms()) { + if (isSkipInstTerm(inst_term.get())) { + continue; + } + for (auto& pin : inst_term->getTerm()->getPins()) { + for (auto& ap : pin->getPinAccess(pin_access_idx)->getAccessPoints()) { + if (tech->getLayer(ap->getLayerNum())->isHorizontal()) { + layer_direction_bias++; + } else { + layer_direction_bias--; + } + } + } + } + return layer_direction_bias >= 0; +} + void FlexPA::prepPatternInst(frInst* unique_inst) { - int num_valid_pattern = prepPatternInstHelper(unique_inst, true); + const bool prefer_x = !instPrefersHorizontal(unique_inst); + int num_valid_pattern = prepPatternInstHelper(unique_inst, prefer_x); if (num_valid_pattern > 0) { return; } - num_valid_pattern = prepPatternInstHelper(unique_inst, false); + num_valid_pattern = prepPatternInstHelper(unique_inst, !prefer_x); if (num_valid_pattern == 0) { logger_->warn(DRT,