diff --git a/src/drt/src/pa/FlexPA.h b/src/drt/src/pa/FlexPA.h index f3428ad1247..b9b3e1f990a 100644 --- a/src/drt/src/pa/FlexPA.h +++ b/src/drt/src/pa/FlexPA.h @@ -211,6 +211,7 @@ class FlexPA bool allow_via, frAccessPointEnum lower_type, frAccessPointEnum upper_type); + bool enclosesOnTrackPlanarAccess(const gtl::rectangle_data& rect, frLayerNum layer_num); @@ -389,8 +390,8 @@ class FlexPA frLayerNum layer_num, frDirEnum dir, bool is_block); - template + template void check_addViaAccess( frAccessPoint* ap, const std::vector>& layer_polys, @@ -399,7 +400,6 @@ class FlexPA T* pin, frInstTerm* inst_term, bool deep_search = false); - template /** * @brief Checks if a Via Access Point is legal @@ -412,13 +412,13 @@ class FlexPA * * @return If the Via Access Point is legal */ + template bool checkViaAccess( frAccessPoint* ap, frVia* via, T* pin, frInstTerm* inst_term, const std::vector>& layer_polys); - template /** * @brief Checks if a the Via Access can be subsequently accesses from the @@ -433,6 +433,7 @@ class FlexPA * * @return If an access from that direction causes no DRV */ + template bool checkDirectionalViaAccess( frAccessPoint* ap, frVia* via, @@ -440,13 +441,12 @@ class FlexPA frInstTerm* inst_term, const std::vector>& layer_polys, frDirEnum dir); - template + template void updatePinStats( const std::vector>& tmp_aps, T* pin, frInstTerm* inst_term); - template /** * @brief initializes the accesses of a given pin but only considered @@ -462,6 +462,22 @@ class FlexPA * * @return if the initialization was sucessful */ + + /** + * @brief initializes the accesses of a given pin but only considered + * acccesses costed bounded between lower and upper cost. + * + * @param aps access points of the pin + * @param apset data of the access points (auxilary) + * @param pin_shapes shapes of the pin + * @param pin the pin + * @param inst_term terminal + * @param lower_type lower bound cost + * @param upper_type upper bound cost + * + * @return if the initialization was sucessful + */ + template bool initPinAccessCostBounded( std::vector>& aps, std::set>& apset, diff --git a/src/drt/src/pa/FlexPA_init.cpp b/src/drt/src/pa/FlexPA_init.cpp index 2f09374519f..c8cdf5ae964 100644 --- a/src/drt/src/pa/FlexPA_init.cpp +++ b/src/drt/src/pa/FlexPA_init.cpp @@ -38,7 +38,7 @@ namespace drt { void FlexPA::initViaRawPriority() { - for (auto layer_num = design_->getTech()->getBottomLayerNum(); + for (int layer_num = design_->getTech()->getBottomLayerNum(); layer_num <= design_->getTech()->getTopLayerNum(); ++layer_num) { if (design_->getTech()->getLayer(layer_num)->getType() @@ -57,17 +57,17 @@ void FlexPA::initViaRawPriority() ViaRawPriorityTuple FlexPA::getViaRawPriority(frViaDef* via_def) { const bool is_not_default_via = !(via_def->getDefault()); - gtl::polygon_90_set_data via_layer_PS1; + gtl::polygon_90_set_data via_layer_ps1; for (auto& fig : via_def->getLayer1Figs()) { const Rect bbox = fig->getBBox(); gtl::rectangle_data bbox_rect( bbox.xMin(), bbox.yMin(), bbox.xMax(), bbox.yMax()); using boost::polygon::operators::operator+=; - via_layer_PS1 += bbox_rect; + via_layer_ps1 += bbox_rect; } gtl::rectangle_data layer1_rect; - gtl::extents(layer1_rect, via_layer_PS1); + gtl::extents(layer1_rect, via_layer_ps1); const bool is_layer1_horz = (gtl::xh(layer1_rect) - gtl::xl(layer1_rect)) > (gtl::yh(layer1_rect) - gtl::yl(layer1_rect)); const frCoord layer1_width @@ -104,7 +104,7 @@ ViaRawPriorityTuple FlexPA::getViaRawPriority(frViaDef* via_def) = (is_layer2_horz && (dir2 == dbTechLayerDir::VERTICAL)) || (!is_layer2_horz && (dir2 == dbTechLayerDir::HORIZONTAL)); - const frCoord layer1_area = gtl::area(via_layer_PS1); + const frCoord layer1_area = gtl::area(via_layer_ps1); const frCoord layer2_area = gtl::area(via_layer_PS2); return std::make_tuple(is_not_default_via, @@ -130,7 +130,7 @@ void FlexPA::initTrackCoords() = (design_->getTech()->getLayer(layer_num)->getDir() == dbTechLayerDir::VERTICAL); const auto is_vert_track - = track_pattern->isHorizontal(); // yes = vertical track + = track_pattern->isHorizontal(); // true = vertical track if ((!is_vert_layer && !is_vert_track) || (is_vert_layer && is_vert_track)) { frCoord curr_coord = track_pattern->getStartCoord(); @@ -157,8 +157,8 @@ void FlexPA::initTrackCoords() } prev_full_coord = curr_full_coord; } - for (auto halfCoord : half_track_coords[i]) { - track_coords_[i][halfCoord] = frAccessPointEnum::HalfGrid; + for (auto half_coord : half_track_coords[i]) { + track_coords_[i][half_coord] = frAccessPointEnum::HalfGrid; } } } diff --git a/src/drt/src/pa/FlexPA_prep.cpp b/src/drt/src/pa/FlexPA_prep.cpp index ec453817a03..074278b49da 100644 --- a/src/drt/src/pa/FlexPA_prep.cpp +++ b/src/drt/src/pa/FlexPA_prep.cpp @@ -53,7 +53,6 @@ template std::vector> FlexPA::mergePinShapes(T* pin, frInstTerm* inst_term, const bool is_shrink) { - std::vector> pin_shapes; frInst* inst = nullptr; if (inst_term) { inst = inst_term->getInst(); @@ -64,22 +63,26 @@ FlexPA::mergePinShapes(T* pin, frInstTerm* inst_term, const bool is_shrink) xform = inst->getUpdatedXform(); } + frTechObject* tech = getDesign()->getTech(); + std::size_t num_layers = tech->getLayers().size(); + std::vector layer_widths; if (is_shrink) { - layer_widths.resize(getDesign()->getTech()->getLayers().size(), 0); + layer_widths.resize(num_layers, 0); for (int i = 0; i < int(layer_widths.size()); i++) { - layer_widths[i] = getDesign()->getTech()->getLayer(i)->getWidth(); + layer_widths[i] = tech->getLayer(i)->getWidth(); } } - pin_shapes.clear(); - pin_shapes.resize(getDesign()->getTech()->getLayers().size()); + std::vector> pin_shapes(num_layers); + for (auto& shape : pin->getFigs()) { if (shape->typeId() == frcRect) { auto obj = static_cast(shape.get()); auto layer_num = obj->getLayerNum(); - if (getDesign()->getTech()->getLayer(layer_num)->getType() - != dbTechLayerType::ROUTING) { + auto layer = tech->getLayer(layer_num); + dbTechLayerDir dir = layer->getDir(); + if (layer->getType() != dbTechLayerType::ROUTING) { continue; } Rect box = obj->getBBox(); @@ -87,11 +90,9 @@ FlexPA::mergePinShapes(T* pin, frInstTerm* inst_term, const bool is_shrink) gtl::rectangle_data rect( box.xMin(), box.yMin(), box.xMax(), box.yMax()); if (is_shrink) { - if (getDesign()->getTech()->getLayer(layer_num)->getDir() - == dbTechLayerDir::HORIZONTAL) { + if (dir == dbTechLayerDir::HORIZONTAL) { gtl::shrink(rect, gtl::VERTICAL, layer_widths[layer_num] / 2); - } else if (getDesign()->getTech()->getLayer(layer_num)->getDir() - == dbTechLayerDir::VERTICAL) { + } else if (dir == dbTechLayerDir::VERTICAL) { gtl::shrink(rect, gtl::HORIZONTAL, layer_widths[layer_num] / 2); } } @@ -121,7 +122,10 @@ FlexPA::mergePinShapes(T* pin, frInstTerm* inst_term, const bool is_shrink) * * @details This follows the Tao of PAO paper cost structure. * On track and half track are the preffered access points, - * this function is responsible for generating them + * this function is responsible for generating them. + * It iterates over every track coord in the range [low, high] + * and inserts one of its coordinates on the coords map. + * if use_nearby_grid is true it changes the access point cost to it. * * TODO: * This function doesn't seem to be getting the best access point. @@ -154,7 +158,9 @@ void FlexPA::genAPOnTrack( // will not generate center for wider edge /** * @details This follows the Tao of PAO paper cost structure. - * Centered Access points are on the center of their pin shape (low, high) + * First it iterates through the range [low, high] to check if there are + * at least 3 possible OnTrack access points as those take priority. + * If false it created and access points in the middle point between [low, high] */ void FlexPA::genAPCentered(std::map& coords, @@ -180,14 +186,79 @@ void FlexPA::genAPCentered(std::map& coords, // If there are less than 3 coords OnGrid will create a Centered Access Point frCoord manu_grid = getDesign()->getTech()->getManufacturingGrid(); frCoord coord = (low + high) / 2 / manu_grid * manu_grid; - auto it = coords.find(coord); - if (it == coords.end()) { + + if (coords.find(coord) == coords.end()) { coords.insert(std::make_pair(coord, frAccessPointEnum::Center)); } else { coords[coord] = std::min(coords[coord], frAccessPointEnum::Center); } } +/** + * @details This follows the Tao of PAO paper cost structure. + * Enclosed Boundary APs satisfy via-in-pin requirement. + * This is the worst access point adressed in the paper + */ + +void FlexPA::genAPEnclosedBoundary(std::map& coords, + const gtl::rectangle_data& rect, + const frLayerNum layer_num, + const bool is_curr_layer_horz) +{ + const auto rect_width = gtl::delta(rect, gtl::HORIZONTAL); + const auto rect_height = gtl::delta(rect, gtl::VERTICAL); + const int max_num_via_trial = 2; + if (layer_num + 1 > getDesign()->getTech()->getTopLayerNum()) { + return; + } + // hardcode first two single vias + std::vector via_defs; + int cnt = 0; + for (auto& [tup, via] : layer_num_to_via_defs_[layer_num + 1][1]) { + via_defs.push_back(via); + cnt++; + if (cnt >= max_num_via_trial) { + break; + } + } + for (auto& via_def : via_defs) { + frVia via(via_def); + const Rect box = via.getLayer1BBox(); + const auto via_width = box.dx(); + const auto via_height = box.dy(); + if (via_width > rect_width || via_height > rect_height) { + continue; + } + if (is_curr_layer_horz) { + auto coord = gtl::yh(rect) - (box.yMax() - 0); + if (coords.find(coord) == coords.end()) { + coords.insert(std::make_pair(coord, frAccessPointEnum::EncOpt)); + } else { + coords[coord] = std::min(coords[coord], frAccessPointEnum::EncOpt); + } + coord = gtl::yl(rect) + (0 - box.yMin()); + if (coords.find(coord) == coords.end()) { + coords.insert(std::make_pair(coord, frAccessPointEnum::EncOpt)); + } else { + coords[coord] = std::min(coords[coord], frAccessPointEnum::EncOpt); + } + } else { + auto coord = gtl::xh(rect) - (box.xMax() - 0); + if (coords.find(coord) == coords.end()) { + coords.insert(std::make_pair(coord, frAccessPointEnum::EncOpt)); + } else { + coords[coord] = std::min(coords[coord], frAccessPointEnum::EncOpt); + } + coord = gtl::xl(rect) + (0 - box.xMin()); + if (coords.find(coord) == coords.end()) { + coords.insert(std::make_pair(coord, frAccessPointEnum::EncOpt)); + } else { + coords[coord] = std::min(coords[coord], frAccessPointEnum::EncOpt); + } + } + } +} + // Responsible for checking if an AP is valid and configuring it void FlexPA::gen_createAccessPoint( std::vector>& aps, @@ -331,71 +402,6 @@ void FlexPA::gen_initializeAccessPoints( } } -/** - * @details This follows the Tao of PAO paper cost structure. - * Enclosed Boundary APs satisfy via-in-pin requirement. - * This is the worst access point adressed in the paper - */ - -void FlexPA::genAPEnclosedBoundary(std::map& coords, - const gtl::rectangle_data& rect, - const frLayerNum layer_num, - const bool is_curr_layer_horz) -{ - const auto rect_width = gtl::delta(rect, gtl::HORIZONTAL); - const auto rect_height = gtl::delta(rect, gtl::VERTICAL); - const int max_num_via_trial = 2; - if (layer_num + 1 > getDesign()->getTech()->getTopLayerNum()) { - return; - } - // hardcode first two single vias - std::vector via_defs; - int cnt = 0; - for (auto& [tup, via] : layer_num_to_via_defs_[layer_num + 1][1]) { - via_defs.push_back(via); - cnt++; - if (cnt >= max_num_via_trial) { - break; - } - } - for (auto& via_def : via_defs) { - frVia via(via_def); - const Rect box = via.getLayer1BBox(); - const auto via_width = box.dx(); - const auto via_height = box.dy(); - if (via_width > rect_width || via_height > rect_height) { - continue; - } - if (is_curr_layer_horz) { - auto coord = gtl::yh(rect) - (box.yMax() - 0); - if (coords.find(coord) == coords.end()) { - coords.insert(std::make_pair(coord, frAccessPointEnum::EncOpt)); - } else { - coords[coord] = std::min(coords[coord], frAccessPointEnum::EncOpt); - } - coord = gtl::yl(rect) + (0 - box.yMin()); - if (coords.find(coord) == coords.end()) { - coords.insert(std::make_pair(coord, frAccessPointEnum::EncOpt)); - } else { - coords[coord] = std::min(coords[coord], frAccessPointEnum::EncOpt); - } - } else { - auto coord = gtl::xh(rect) - (box.xMax() - 0); - if (coords.find(coord) == coords.end()) { - coords.insert(std::make_pair(coord, frAccessPointEnum::EncOpt)); - } else { - coords[coord] = std::min(coords[coord], frAccessPointEnum::EncOpt); - } - coord = gtl::xl(rect) + (0 - box.xMin()); - if (coords.find(coord) == coords.end()) { - coords.insert(std::make_pair(coord, frAccessPointEnum::EncOpt)); - } else { - coords[coord] = std::min(coords[coord], frAccessPointEnum::EncOpt); - } - } - } -} - bool FlexPA::enclosesOnTrackPlanarAccess( const gtl::rectangle_data& rect, frLayerNum layer_num) @@ -441,6 +447,11 @@ bool FlexPA::enclosesOnTrackPlanarAccess( } return true; } + +/** + * @details Generates all necessary access points from a rectangle shape + * In this case a rectangle is one of the pin shapes of the pin + */ void FlexPA::genAPsFromRect(std::vector>& aps, std::set>& apset, const gtl::rectangle_data& rect, @@ -717,6 +728,7 @@ void FlexPA::genAPsFromLayerShapes( // lower 1/2 1, upper on-grid 0 = 1 // lower center 2, upper on-grid 0 = 2 // lower center 2, upper center 2 = 4 + template void FlexPA::genAPsFromPinShapes( std::vector>& aps, @@ -759,7 +771,7 @@ bool FlexPA::check_endPointIsOutside( frCoord x = begin_point.x(); frCoord y = begin_point.y(); const frCoord width = getDesign()->getTech()->getLayer(layer_num)->getWidth(); - const frCoord stepSize = step_size_multiplier * width; + const frCoord step_size = step_size_multiplier * width; const frCoord pitch = getDesign()->getTech()->getLayer(layer_num)->getPitch(); gtl::rectangle_data rect; if (is_block) { @@ -773,28 +785,28 @@ bool FlexPA::check_endPointIsOutside( if (is_block) { x = gtl::xl(rect) - pitch; } else { - x -= stepSize; + x -= step_size; } break; case (frDirEnum::E): if (is_block) { x = gtl::xh(rect) + pitch; } else { - x += stepSize; + x += step_size; } break; case (frDirEnum::S): if (is_block) { y = gtl::yl(rect) - pitch; } else { - y -= stepSize; + y -= step_size; } break; case (frDirEnum::N): if (is_block) { y = gtl::yh(rect) + pitch; } else { - y += stepSize; + y += step_size; } break; default: @@ -1079,11 +1091,7 @@ void FlexPA::check_addViaAccess( } } } - if (valid_via_defs.empty()) { - ap->setAccess(dir, false); - } else { - ap->setAccess(dir, true); - } + ap->setAccess(dir, !valid_via_defs.empty()); for (auto& [ext, idx, via_def] : valid_via_defs) { ap->addViaDef(via_def); } diff --git a/src/drt/src/pa/FlexPA_unique.h b/src/drt/src/pa/FlexPA_unique.h index eac499d59a3..af48c05b3cb 100644 --- a/src/drt/src/pa/FlexPA_unique.h +++ b/src/drt/src/pa/FlexPA_unique.h @@ -50,6 +50,7 @@ class UniqueInsts UniqueInsts(frDesign* design, const frCollection& target_insts, Logger* logger); + /** * @brief Initializes Unique Instances and Pin Acess data. */