diff --git a/default.nix b/default.nix index 4db21cb81eb..73c8f2f319c 100644 --- a/default.nix +++ b/default.nix @@ -67,6 +67,7 @@ # or-tools stdenv, overrideSDK, + git, }: let or-tools' = (or-tools.override { @@ -102,6 +103,10 @@ patchShebangs . ''; + shellHook = '' + alias ord-format-changed="${git}/bin/git diff --name-only | grep -E '\.(cpp|cc|c|h|hh)$' | xargs clang-format -i -style=file:.clang-format"; + ''; + qt5Libs = [ libsForQt5.qt5.qtbase libsForQt5.qt5.qtcharts diff --git a/src/dbSta/src/dbNetwork.cc b/src/dbSta/src/dbNetwork.cc index 2fad03807cd..70bf2626df5 100644 --- a/src/dbSta/src/dbNetwork.cc +++ b/src/dbSta/src/dbNetwork.cc @@ -848,23 +848,19 @@ Instance* dbNetwork::parent(const Instance* instance) const staToDb(instance, db_inst, mod_inst); if (mod_inst) { auto parent_module = mod_inst->getParent(); - if (parent_module){ - if (auto parent_inst = parent_module->getModInst()) { - if (parent_inst){ - return dbToSta(parent_inst); - } - } + if (parent_module) { + auto parent_inst = parent_module->getModInst(); + if (parent_inst) { + return dbToSta(parent_inst); + } } } - if (hierarchy_){ - if (db_inst) { - auto parent_module = db_inst->getModule(); - if (parent_module){ - if (auto parent_inst = parent_module->getModInst()) { - if (parent_inst){ - return dbToSta(parent_inst); - } - } + if (db_inst) { + auto parent_module = db_inst->getModule(); + if (parent_module) { + auto parent_inst = parent_module->getModInst(); + if (parent_inst) { + return dbToSta(parent_inst); } } } diff --git a/src/dft/src/dft.tcl b/src/dft/src/dft.tcl index d1841a5ac8c..fbe5892d766 100644 --- a/src/dft/src/dft.tcl +++ b/src/dft/src/dft.tcl @@ -99,7 +99,7 @@ proc set_dft_config { args } { } sta::define_cmd_args "report_dft_config" { } -proc report_dft_config { } { +proc report_dft_config { args } { sta::parse_key_args "report_dft_config" args keys {} flags {} dft::report_dft_config } diff --git a/src/drt/src/db/obj/frBlock.h b/src/drt/src/db/obj/frBlock.h index 120e072c7ab..71fc8250bd8 100644 --- a/src/drt/src/db/obj/frBlock.h +++ b/src/drt/src/db/obj/frBlock.h @@ -286,6 +286,14 @@ class frBlock : public frBlockObject } return Point(idxX, idxY); } + bool isValidGCellIdx(const Point& pt) const + { + const auto& gp = getGCellPatterns(); + const auto& xgp = gp[0]; + const auto& ygp = gp[1]; + return pt.x() >= 0 && pt.x() < xgp.getCount() && pt.y() >= 0 + && pt.y() < ygp.getCount(); + } const frList>& getMarkers() const { return markers_; diff --git a/src/drt/src/io/GuideProcessor.cpp b/src/drt/src/io/GuideProcessor.cpp index c318b710923..9cc370f5e08 100644 --- a/src/drt/src/io/GuideProcessor.cpp +++ b/src/drt/src/io/GuideProcessor.cpp @@ -62,18 +62,6 @@ std::vector getPinShapes(const frBlockObject* pin) return pinShapes; } -/** - * @brief Returns bounding box of the given pin. - * @note Assumes pin's typeId() is either frcBTerm or frcInstTerm - */ -Rect getPinBBox(const frBlockObject* pin) -{ - if (pin->typeId() == frcBTerm) { - return static_cast(pin)->getBBox(); - } else { - return static_cast(pin)->getBBox(true); - } -} /** * @brief Returns name of the given pin. * @note Assumes pin's typeId() is either frcBTerm or frcInstTerm @@ -86,112 +74,126 @@ std::string getPinName(const frBlockObject* pin) return static_cast(pin)->getName(); } } +/** + * Returns the preferred access point for required pin. + * + * The function returns the preferred acces point of the iterm from the + * required pin index. If there is no preferred access point set for that pin, + * then the first access point for that pin is returned. + * + * @param iterm The ITerm we are considering. + * @param pin_idx The pin index of the pin we are considering. + * @returns The preferred access point if found, and nullptr otherwise. + */ +frAccessPoint* getPrefAp(const frInstTerm* iterm, const int pin_idx) +{ + const int pin_access_idx = iterm->getInst()->getPinAccessIdx(); + const auto pin = iterm->getTerm()->getPins().at(pin_idx).get(); + if (!pin->hasPinAccess()) { + return nullptr; + } + frAccessPoint* pref_ap = (iterm->getAccessPoints())[pin_idx]; -bool isPinCoveredByGuides(const frBlockObject* pin, - const std::vector& guides) + if (!pref_ap) { + auto pa = pin->getPinAccess(pin_access_idx); + if (pa->getNumAccessPoints() != 0) { + pref_ap = pin->getPinAccess(pin_access_idx)->getAccessPoint(0); + } + } + return pref_ap; +} +std::vector getAccessPoints(const frBlockObject* pin) { - std::vector pin_shapes = getPinShapes(pin); - // checks if there is a guide that overlaps with any of the pin shapes - for (const auto& pin_rect : pin_shapes) { - for (const auto& guide : guides) { - if (guide.getLayerNum() == pin_rect.getLayerNum() - && guide.getBBox().overlaps(pin_rect.getBBox())) { - return true; + std::vector result; + if (pin->typeId() == frcInstTerm) { + auto iterm = static_cast(pin); + auto transform = iterm->getInst()->getTransform(); + transform.setOrient(odb::dbOrientType::R0); + const int pin_access_idx = iterm->getInst()->getPinAccessIdx(); + for (const auto& mpin : iterm->getTerm()->getPins()) { + if (!mpin->hasPinAccess()) { + continue; + } + for (const auto& ap : + mpin->getPinAccess(pin_access_idx)->getAccessPoints()) { + auto ap_loc = ap->getPoint(); + transform.apply(ap_loc); + result.emplace_back(ap_loc, ap->getLayerNum()); + } + } + } else { + auto bterm = static_cast(pin); + for (const auto& bpin : bterm->getPins()) { + if (!bpin->hasPinAccess()) { + continue; + } + for (int i = 0; i < bpin->getNumPinAccess(); i++) { + auto pa = bpin->getPinAccess(i); + for (const auto& ap : pa->getAccessPoints()) { + result.emplace_back(ap->getPoint(), ap->getLayerNum()); + } } } } - return false; + return result; } /** - * @brief Finds intersecting guides with point(x,y). - * - * The function iterates over the guides list, finds the guides that - * intersect with point(x,y)'s gcell, and adds their indices to the out_guides - * list - * - * @param out_guides The resulting list of indices of the intersecting guides - * @param guides The lookup list of guides + * @brief Checks if any of the pins' accesspoints is covered by the net's guides * + * @param pin The pin we are checking. + * @param guides The list of the net guides. + * @returns True if any access point is covered by any guide. */ -void findIntersectingGuides(const int x, - const int y, - std::set& out_guides, - const std::vector& guides, - frDesign* design) +bool isPinCoveredByGuides(const frBlockObject* pin, + const std::vector& guides) { - const Point g_cell = design->getTopBlock()->getGCellCenter({x, y}); - for (int i = 0; i < (int) guides.size(); i++) { - if (guides[i].getBBox().intersects(g_cell)) { - out_guides.insert(i); + for (const auto& ap_loc : getAccessPoints(pin)) { + for (const auto& guide : guides) { + if (guide.getLayerNum() == ap_loc.z() + && guide.getBBox().overlaps(ap_loc)) { + return true; + } } } + return false; } /** - * @brief Returns the best pin shape location to later use for patching guides. + * @brief Returns the best gcell location to later use for patching guides. * - * This function iterates over all the pin shapes and finds the one with the - * highest intersection area with a single gcell. It also returns the list of - * guides that intersect with the pin's gcells. + * The function returns the gcell location with the highest number of access + * points. * - * @param candidate_guides_indices The resulting list of indices of the - * intersecting guides with all gcells the pin touches - * @return The chosen pinShape's gcell index + * @return The chosen best gcell index */ Point3D findBestPinLocation(frDesign* design, frBlockObject* pin, - const std::vector& guides, - std::set& candidate_guides_indices) + const std::vector& guides) { - Rect pin_bbox = getPinBBox(pin); - // adjusting pin bounding box as pins tangent to gcell aren't considered as - // part of them - pin_bbox.init(pin_bbox.xMin() + 1, - pin_bbox.yMin() + 1, - pin_bbox.xMax() - 1, - pin_bbox.yMax() - 1); - - // set pin_bbox to gCell coords - const Point ll_gcell = design->getTopBlock()->getGCellIdx(pin_bbox.ll()); - const Point ur_gcell = design->getTopBlock()->getGCellIdx(pin_bbox.ur()); - - // finds the gCell with higher pinShape overlapping area (approximate) - frArea best_area = 0, area = 0; - Point3D best_pin_loc_idx; - std::vector pin_shapes = getPinShapes(pin); - for (int x = ll_gcell.x(); x <= ur_gcell.x(); x++) { - for (int y = ll_gcell.y(); y <= ur_gcell.y(); y++) { - const Point gcell_center(x, y); - const Rect gcell_box = design->getTopBlock()->getGCellBox(gcell_center); - for (int z = 0; z < (int) design->getTech()->getLayers().size(); z++) { - if (design->getTech()->getLayer(z)->getType() - != dbTechLayerType::ROUTING) { - continue; - } - area = 0; - for (const auto& pinRect : pin_shapes) { - if (pinRect.getLayerNum() != z) { - continue; - } - Rect intersection; - gcell_box.intersection(pinRect.getBBox(), intersection); - area += intersection.area(); - } - if (area > best_area) { - best_area = area; - best_pin_loc_idx.set(x, y, z); - } + std::map gcell_to_ap_count; // map from gcell index to number + // of accesspoints it holds. + frCoord min_dist_to_guides = std::numeric_limits::max(); + for (const auto& ap_loc : getAccessPoints(pin)) { + auto ap_gcell_idx = design->getTopBlock()->getGCellIdx(ap_loc); + auto gcell_center = design->getTopBlock()->getGCellCenter(ap_gcell_idx); + for (const auto& guide : guides) { + auto dist = odb::manhattanDistance(guide.getBBox(), gcell_center); + if (dist < min_dist_to_guides) { + gcell_to_ap_count.clear(); + min_dist_to_guides = dist; + gcell_to_ap_count[Point3D(ap_gcell_idx, ap_loc.z())]++; + } else if (dist == min_dist_to_guides) { + gcell_to_ap_count[Point3D(ap_gcell_idx, ap_loc.z())]++; } - // finds guides in the neighboring gCells - findIntersectingGuides( - x - 1, y, candidate_guides_indices, guides, design); - findIntersectingGuides( - x + 1, y, candidate_guides_indices, guides, design); - findIntersectingGuides( - x, y - 1, candidate_guides_indices, guides, design); - findIntersectingGuides( - x, y + 1, candidate_guides_indices, guides, design); + } + } + Point3D best_pin_loc_idx; + int highest_count = 0; + for (const auto& [gcell_idx, count] : gcell_to_ap_count) { + if (count > highest_count) { + best_pin_loc_idx = gcell_idx; + highest_count = count; } } return best_pin_loc_idx; @@ -199,7 +201,7 @@ Point3D findBestPinLocation(frDesign* design, /** * @brief Returns the index of the closest guide to best_pin_loc_coords. * - * This function iterates over the candidate guides, finds the guide with the + * This function iterates over the guides, finds the guide with the * minimal distance to best_pin_loc_coords and returns it. * * @param best_pin_loc_coords The gcell center point of the chosen pin shape @@ -207,30 +209,31 @@ Point3D findBestPinLocation(frDesign* design, */ int findClosestGuide(const Point3D& best_pin_loc_coords, const std::vector& guides, - const std::set& candidate_guides_indices, const frCoord layer_change_penalty) { int closest_guide_idx = -1; int dist = 0; int min_dist = std::numeric_limits::max(); - for (const auto& guideIdx : candidate_guides_indices) { - dist = odb::manhattanDistance(guides[guideIdx].getBBox(), - best_pin_loc_coords); - dist += abs(guides[guideIdx].getLayerNum() - best_pin_loc_coords.z()) + int guide_idx = 0; + for (const auto& guide : guides) { + dist = odb::manhattanDistance(guide.getBBox(), best_pin_loc_coords); + dist += abs(guide.getLayerNum() - best_pin_loc_coords.z()) * layer_change_penalty; if (dist < min_dist) { min_dist = dist; - closest_guide_idx = guideIdx; + closest_guide_idx = guide_idx; } + guide_idx++; } return closest_guide_idx; } /** - * @brief Adjusts the guide point to the coordinate of the nearest gcell center. + * @brief Adjusts the guide point to the coordinate of the nearest gcell + * center. * - * Given a point X on a guide perimeter, this function adjust it to X' which is - * the center of the nearest gcell from the most left, right, north, or south - * gcells of the guide. See the following figure for more clarification + * Given a point X on a guide perimeter, this function adjust it to X' which + * is the center of the nearest gcell from the most left, right, north, or + * south gcells of the guide. See the following figure for more clarification * * =========================X=========== * | | | | | @@ -239,7 +242,8 @@ int findClosestGuide(const Point3D& best_pin_loc_coords, * | | | | | * | | | | | * ===================================== - * @param guide_pt A point on the guide perimeter that is adjusted from X to X' + * @param guide_pt A point on the guide perimeter that is adjusted from X to + * X' * @param guide_bbox The bounding box of the guide on which relies guide_pt * @param gcell_half_size_horz Half the horizontal size of the gcell * @param gcell_half_size_vert Half the vertical size of the gcell @@ -267,8 +271,8 @@ void adjustGuidePoint(Point3D& guide_pt, * @brief Extends the chosen guide to cover the best_pin_loc_coords. * * The function extends the chosen guide to cover the best_pin_loc_coords if - * possible. The function also adjusts the guide_pt to the new extension. Check - * the following figure where X is the original guide_pt, b_pt is the + * possible. The function also adjusts the guide_pt to the new extension. + * Check the following figure where X is the original guide_pt, b_pt is the * best_pin_loc_coords. X' = b_pt should be the resulting guide_pt. * * =====================================--------------------- @@ -285,8 +289,8 @@ void adjustGuidePoint(Point3D& guide_pt, * @param guide The guide we are attempting to extend to cover * best_pin_loc_coords * @param guide_pt The center of the gcell on the guide from which we should - * extend. See `adjustGuidePoint()` as this guide_pt is after adjustment. It is - * updated if the guide is extended. + * extend. See `adjustGuidePoint()` as this guide_pt is after adjustment. It + * is updated if the guide is extended. * @see adjustGuidePoint() */ void extendGuide(frDesign* design, @@ -323,8 +327,8 @@ void extendGuide(frDesign* design, * guides and the pin z coordinate. * * The function creates guides of 1-gcell size centered at best_pin_loc_coords - * on all layers in the range ]start_z, best_pin_loc_coords.z()]. start_z is the - * layerNum of the chosen closest guide. + * on all layers in the range ]start_z, best_pin_loc_coords.z()]. start_z is + * the layerNum of the chosen closest guide. * * @param best_pin_loc_coords The gcell center point of the chosen pin shape * @param start_z The layerNum of the chosen closest guide. @@ -351,8 +355,8 @@ void fillGuidesUpToZ(const Point3D& best_pin_loc_coords, } } /** - * @brief Connects the guides with the best pin shape location (on the 2D plane - * only) + * @brief Connects the guides with the best pin shape location (on the 2D + * plane only) * * The function creates a patch guide that connects the closest guide to * best_pin_loc_coords (without consideration to different layers) @@ -413,8 +417,8 @@ void logGuidesRead(const int num_guides, utl::Logger* logger) * - Above the sepecified top routing layer * - Below the specified bottom routing layer and the via access layer * @note If a layer is invalid, this produces an error unless it is above the - * top routing layer for a net that has pins above the top routing layer. In the - * latest case, we just ignore the guide and the pin is handled by + * top routing layer for a net that has pins above the top routing layer. In + * the latest case, we just ignore the guide and the pin is handled by * io::Parser::setBTerms_addPinFig_helper * @param layer_num The layer_num of the guide returned by this function if it * is a valid layer @@ -505,8 +509,31 @@ void initGuideIntervals(const std::vector& rects, } } } + +bool gcellHasGuide(frCoord pivot_idx, + frCoord other_idx, + const frLayerNum curr_layer_num, + const TrackIntervalsByLayer& intvs) +{ + if (curr_layer_num % 4 == 2) { + std::swap(pivot_idx, other_idx); + } + for (frLayerNum layer_num = 0; layer_num < intvs.size(); layer_num += 2) { + const auto& layer_intvs = intvs[layer_num]; + auto it = layer_intvs.find(pivot_idx); + if (it != layer_intvs.end() + && boost::icl::contains(it->second, other_idx)) { + return true; + } + if (curr_layer_num % 2 == 0) { + std::swap(pivot_idx, other_idx); + } + } + return false; +} /** - * @brief Checks if there exists an interval with the specified passed arguments + * @brief Checks if there exists an interval with the specified passed + * arguments * * The function checks if there exists an interval on layer_num with any track * index from begin_idx to end_idx that contains both indices; track_idx1 and @@ -524,6 +551,9 @@ bool hasGuideInterval(const frCoord begin_idx, const frLayerNum layer_num, const TrackIntervalsByLayer& intvs) { + if (layer_num < 0 || layer_num >= intvs.size()) { + return false; + } for (auto it = intvs[layer_num].lower_bound(begin_idx); it != intvs[layer_num].end() && it->first <= end_idx; it++) { @@ -534,6 +564,37 @@ bool hasGuideInterval(const frCoord begin_idx, } return false; } +struct BridgeGuide +{ + frCoord track_idx{-1}; + frCoord begin_idx{-1}; + frCoord end_idx{-1}; + frLayerNum layer_num{-1}; + BridgeGuide(frCoord track_idx_in = -1, + frCoord idx1 = -1, + frCoord idx2 = -1, + frLayerNum layer_num_in = -1) + : track_idx(track_idx_in), + begin_idx(std::min(idx1, idx2)), + end_idx(std::max(idx1, idx2)), + layer_num(layer_num_in) + { + } + frCoord getDist() const + { + return layer_num == -1 ? std::numeric_limits::max() + : end_idx - begin_idx; + } + bool operator<(const BridgeGuide& rhs) const + { + const auto curr_dist = getDist(); + const auto rhs_dis = rhs.getDist(); + if (curr_dist == rhs_dis) { + return layer_num > rhs.layer_num; + } + return curr_dist < rhs_dis; + } +}; /** * @brief Adds Bridge guides for touching guides on the same layer if needed. * @@ -544,23 +605,40 @@ bool hasGuideInterval(const frCoord begin_idx, */ void addTouchingGuidesBridges(TrackIntervalsByLayer& intvs, utl::Logger* logger) { - struct BridgeGuide - { - frCoord track_idx{-1}; - frCoord begin_idx{-1}; - frCoord end_idx{-1}; - frLayerNum layer_num{-1}; - BridgeGuide(frCoord track_idx_in, - frCoord begin_idx_in, - frCoord end_idx_in, - frLayerNum layer_num_in) - : track_idx(track_idx_in), - begin_idx(begin_idx_in), - end_idx(end_idx_in), - layer_num(layer_num_in) - { + // connect corner edges + for (int layer_num = intvs.size() - 1; layer_num >= 0; layer_num--) { + const auto& curr_layer_intvs = intvs[layer_num]; + int prev_track_idx = -2; + for (const auto& [curr_track_idx, curr_track_intvs] : curr_layer_intvs) { + if (curr_track_idx == prev_track_idx + 1) { + const auto& prev_track_intvs = curr_layer_intvs.at(prev_track_idx); + + for (auto intv1 : curr_track_intvs) { + for (auto intv2 : prev_track_intvs) { + if (boost::icl::intersects(intv1, intv2)) { + continue; + } + if (intv1.upper() + 1 == intv2.lower() + && !gcellHasGuide( + curr_track_idx, intv1.upper() + 1, layer_num, intvs) + && !gcellHasGuide( + prev_track_idx, intv1.upper(), layer_num, intvs)) { + intvs[layer_num][curr_track_idx].insert( + Interval::closed(intv1.upper(), intv1.upper() + 1)); + } else if (intv2.upper() + 1 == intv1.lower() + && !gcellHasGuide( + prev_track_idx, intv2.upper() + 1, layer_num, intvs) + && !gcellHasGuide( + curr_track_idx, intv2.upper(), layer_num, intvs)) { + intvs[layer_num][prev_track_idx].insert( + Interval::closed(intv2.upper(), intv2.upper() + 1)); + } + } + } + } + prev_track_idx = curr_track_idx; } - }; + } std::vector bridge_guides; // append touching edges @@ -617,34 +695,6 @@ void addTouchingGuidesBridges(TrackIntervalsByLayer& intvs, utl::Logger* logger) Interval::closed(bridge.begin_idx, bridge.end_idx)); } } -/** - * Returns the preferred access point for required pin. - * - * The function returns the preferred acces point of the iterm from the required - * pin index. If there is no preferred access point set for that pin, then the - * first access point for that pin is returned. - * - * @param iterm The ITerm we are considering. - * @param pin_idx The pin index of the pin we are considering. - * @returns The preferred access point if found, and nullptr otherwise. - */ -frAccessPoint* getPrefAp(const frInstTerm* iterm, const int pin_idx) -{ - const int pin_access_idx = iterm->getInst()->getPinAccessIdx(); - const auto pin = iterm->getTerm()->getPins().at(pin_idx).get(); - if (!pin->hasPinAccess()) { - return nullptr; - } - frAccessPoint* pref_ap = (iterm->getAccessPoints())[pin_idx]; - - if (!pref_ap) { - auto pa = pin->getPinAccess(pin_access_idx); - if (pa->getNumAccessPoints() != 0) { - pref_ap = pin->getPinAccess(pin_access_idx)->getAccessPoint(0); - } - } - return pref_ap; -} } // namespace @@ -934,22 +984,17 @@ void GuideProcessor::patchGuides(frNet* net, "Pin {} not in any guide. Attempting to patch guides to cover " "(at least part of) the pin.", name); - std::set candidate_guides_indices; const Point3D best_pin_loc_idx - = findBestPinLocation(getDesign(), pin, guides, candidate_guides_indices); + = findBestPinLocation(getDesign(), pin, guides); // The x/y/z coordinates of best_pin_loc_idx const Point3D best_pin_loc_coords( getDesign()->getTopBlock()->getGCellCenter(best_pin_loc_idx), best_pin_loc_idx.z()); - if (candidate_guides_indices.empty()) { - logger_->warn(DRT, 1001, "No guide in the pin neighborhood"); - return; - } // get the guide that is closest to the gCell // TODO: test passing layer_change_penalty = gcell size - const int closest_guide_idx = findClosestGuide( - best_pin_loc_coords, guides, candidate_guides_indices, 1); - // gets the point in the closer guide that is closer to the bestPinLoc + const int closest_guide_idx + = findClosestGuide(best_pin_loc_coords, guides, 1); + patchGuides_helper( net, guides, best_pin_loc_idx, best_pin_loc_coords, closest_guide_idx); } @@ -1109,7 +1154,7 @@ void GuideProcessor::genGuides_split( const TrackIntervalsByLayer& intvs, const std::map& gcell_pin_map, frBlockObjectMap>& pin_gcell_map, - bool first_iter) const + bool via_access_only) const { rects.clear(); // layer_num->track_idx->routing_dir_track_idx->set of pins @@ -1134,7 +1179,7 @@ void GuideProcessor::genGuides_split( auto end_idx = intv.upper(); std::set split_indices; // hardcode layerNum <= VIA_ACCESS_LAYERNUM not used for GR - if (first_iter && layer_num <= VIA_ACCESS_LAYERNUM) { + if (via_access_only && layer_num <= VIA_ACCESS_LAYERNUM) { // split by pin split::splitByPins(pin_helper, layer_num, @@ -1234,66 +1279,21 @@ void GuideProcessor::initGCellPinMap( std::map& gcell_pin_map) const { for (auto instTerm : net->getInstTerms()) { - if (DBPROCESSNODE == "GF14_13M_3Mx_2Cx_4Kx_2Hx_2Gx_LB" - && mapITermAccessPointsToGCells(gcell_pin_map, instTerm)) { - continue; - } - mapPinShapesToGCells(gcell_pin_map, instTerm); + mapTermAccessPointsToGCells(gcell_pin_map, instTerm); } for (auto term : net->getBTerms()) { - if (DBPROCESSNODE == "GF14_13M_3Mx_2Cx_4Kx_2Hx_2Gx_LB" - && mapBTermAccessPointsToGCells(gcell_pin_map, term)) { - continue; - } - mapPinShapesToGCells(gcell_pin_map, term); + mapTermAccessPointsToGCells(gcell_pin_map, term); } } -bool GuideProcessor::mapITermAccessPointsToGCells( +void GuideProcessor::mapTermAccessPointsToGCells( std::map& gcell_pin_map, - frInstTerm* inst_term) const + frBlockObject* pin) const { - const size_t num_pins = inst_term->getTerm()->getPins().size(); - const frInst* inst = inst_term->getInst(); - dbTransform transform = inst->getTransform(); - transform.setOrient(dbOrientType(dbOrientType::R0)); - - int pins_covered = 0; - for (int pin_idx = 0; pin_idx < num_pins; pin_idx++) { - const frAccessPoint* pref_ap = getPrefAp(inst_term, pin_idx); - if (pref_ap) { - Point bp = pref_ap->getPoint(); - transform.apply(bp); - const frLayerNum layer_num = pref_ap->getLayerNum(); - const Point idx = getDesign()->getTopBlock()->getGCellIdx(bp); - gcell_pin_map[Point3D(idx, layer_num)].insert(inst_term); - pins_covered++; - } + for (const auto& ap_loc : getAccessPoints(pin)) { + const Point idx = getDesign()->getTopBlock()->getGCellIdx(ap_loc); + gcell_pin_map[Point3D(idx, ap_loc.z())].insert(pin); } - return (pins_covered == num_pins); -} - -bool GuideProcessor::mapBTermAccessPointsToGCells( - std::map& gcell_pin_map, - frBTerm* term) const -{ - int pins_covered = 0; - for (const auto& pin : term->getPins()) { - if (!pin->hasPinAccess()) { - continue; - } - const auto& access_points = pin->getPinAccess(0)->getAccessPoints(); - if (access_points.empty()) { - continue; - } - const frAccessPoint* pref_ap = access_points[0].get(); - const Point& bp = pref_ap->getPoint(); - const frLayerNum layer_num = pref_ap->getLayerNum(); - const Point idx = getDesign()->getTopBlock()->getGCellIdx(bp); - gcell_pin_map[Point3D(idx, layer_num)].insert(term); - pins_covered++; - } - return pins_covered == term->getPins().size(); } void GuideProcessor::initPinGCellMap( @@ -1374,16 +1374,18 @@ void GuideProcessor::genGuides(frNet* net, std::vector& rects) bool path_found = false; // Run for 3 iterations max - for (int i = 0; i < 3; i++) { - const bool is_first_iter = (i == 0); - const bool is_last_iter = (i == 2); - if (!is_last_iter) { + for (int i = 0; i < 4; i++) { + const bool force_pin_feed_through = (i >= 2); + const bool via_access_only = (i == 0); + const bool patch_guides_on_failure = (i == 2); + if (i != 2) // no change in rects in this iteration + { genGuides_split( rects, intvs, gcell_pin_map, pin_gcell_map, - is_first_iter); // split on LU intersecting guides and pins + via_access_only); // split on LU intersecting guides and pins if (pin_gcell_map.empty()) { logger_->warn(DRT, 214, "genGuides empty gcell_pin_map."); debugPrint(logger_, @@ -1420,13 +1422,16 @@ void GuideProcessor::genGuides(frNet* net, std::vector& rects) } } GuidePathFinder path_finder( - design_, logger_, net, is_last_iter, rects, pin_gcell_map); - path_finder.setAllowWarnings(!is_first_iter); + design_, logger_, net, force_pin_feed_through, rects, pin_gcell_map); + path_finder.setAllowWarnings(i != 0); if (path_finder.traverseGraph()) { path_found = true; path_finder.commitPathToGuides(rects, pin_gcell_map, tmpGRPins_); break; } + if (patch_guides_on_failure) { + path_finder.connectDisconnectedComponents(rects, intvs); + } } if (!path_found) { logger_->error(DRT, 218, "Guide is not connected to design."); @@ -1766,6 +1771,86 @@ bool GuidePathFinder::traverseGraph() return success; } +void GuidePathFinder::bfs(int node_idx) +{ + visited_.clear(); + visited_.resize(getNodeCount(), false); + std::queue queue; + queue.push({node_idx, -1, 0}); + while (!queue.empty()) { + auto curr_wavefront = queue.front(); + queue.pop(); + visited_[curr_wavefront.node_idx] = true; + for (auto neighbor_idx : adj_list_[curr_wavefront.node_idx]) { + if (!visited_[neighbor_idx]) { + queue.push( + {neighbor_idx, curr_wavefront.node_idx, curr_wavefront.cost + 1}); + } + } + } +} + +void GuidePathFinder::connectDisconnectedComponents( + const std::vector& rects, + TrackIntervalsByLayer& intvs) +{ + const int unvisited_pin_idx + = std::distance(visited_.begin(), + std::find_if(visited_.begin() + getGuideCount() + 1, + visited_.end(), + [](bool x) { return !x; })); + auto getVisitedIndices = [this]() { + std::vector indices; + for (int i = 0; i < getGuideCount(); i++) { + if (visited_[i]) { + indices.push_back(i); + } + } + return indices; + }; + bfs(getGuideCount()); + const auto component1 = getVisitedIndices(); + bfs(unvisited_pin_idx); + const auto component2 = getVisitedIndices(); + BridgeGuide best_bridge; + + for (const auto idx1 : component1) { + for (const auto idx2 : component2) { + if (rects[idx1].getLayerNum() != rects[idx2].getLayerNum()) { + continue; + } + const auto layer_num = rects[idx1].getLayerNum(); + const bool is_horizontal = getTech()->getLayer(layer_num)->isHorizontal(); + const frCoord track_idx1 = is_horizontal ? rects[idx1].getBBox().yMin() + : rects[idx1].getBBox().xMin(); + const frCoord track_idx2 = is_horizontal ? rects[idx2].getBBox().yMin() + : rects[idx2].getBBox().xMin(); + if (std::abs(track_idx1 - track_idx2) > 1) { + continue; + } + + const frCoord begin_idx1 = is_horizontal ? rects[idx1].getBBox().xMin() + : rects[idx1].getBBox().yMin(); + const frCoord end_idx1 = is_horizontal ? rects[idx1].getBBox().xMax() + : rects[idx1].getBBox().yMax(); + const frCoord begin_idx2 = is_horizontal ? rects[idx2].getBBox().xMin() + : rects[idx2].getBBox().yMin(); + const frCoord end_idx2 = is_horizontal ? rects[idx2].getBBox().xMax() + : rects[idx2].getBBox().yMax(); + + const BridgeGuide bridge1(track_idx1, end_idx1, begin_idx2, layer_num); + const BridgeGuide bridge2(track_idx2, end_idx2, begin_idx1, layer_num); + best_bridge = std::min(best_bridge, bridge1); + best_bridge = std::min(best_bridge, bridge2); + } + } + if (best_bridge.layer_num == -1) { + return; + } + intvs[best_bridge.layer_num][best_bridge.track_idx].insert( + Interval::closed(best_bridge.begin_idx, best_bridge.end_idx)); + addTouchingGuidesBridges(intvs, logger_); +} void GuideProcessor::saveGuidesUpdates() { auto block = db_->getChip()->getBlock(); diff --git a/src/drt/src/io/GuideProcessor.h b/src/drt/src/io/GuideProcessor.h index 05054068f6e..70246b50062 100644 --- a/src/drt/src/io/GuideProcessor.h +++ b/src/drt/src/io/GuideProcessor.h @@ -164,14 +164,16 @@ class GuideProcessor * @param intvs The track intervals calculated by genGuides_prep * @param gcell_pin_map Map from gcell index to pins. * @param pin_gcell_map Map from pin object to gcell indices. - * @param first_iter True if this the first iteration. + * @param via_access_only True if this the first iteration. Indicates that + * splitting is gonna consider Guides on VIA_ACCESS_LAYER_NUM or below as via + * guides only. * */ void genGuides_split(std::vector& rects, const TrackIntervalsByLayer& intvs, const std::map& gcell_pin_map, frBlockObjectMap>& pin_gcell_map, - bool first_iter) const; + bool via_access_only) const; /** * Initializes a map of gcell location to set of pins * @@ -199,8 +201,8 @@ class GuideProcessor void mapPinShapesToGCells(std::map& gcell_pin_map, frBlockObject* term) const; /** - * Populates gcell_pin_map with the values associated with the passed ITerm - * based on preferred access points. + * Populates gcell_pin_map with the values associated with the passed pin + * based on access points. * * Does a similar job to `mapPinShapesToGCells`. But instead of relying on * pin shapes and their intersection with gcells, it relies on the preferred @@ -208,22 +210,11 @@ class GuideProcessor * * @param gcell_pin_map The map to be populated with the results. * @param term The current pin we are processing. - * @returns True if all pins' preferred access points are considered. */ - bool mapITermAccessPointsToGCells( + void mapTermAccessPointsToGCells( std::map& gcell_pin_map, - frInstTerm* inst_term) const; - /** - * Populates gcell_pin_map with the values associated with the passed BTerm - * based on preferred access points. - * - * @param gcell_pin_map The map to be populated with the results. - * @param term The current pin we are processing. - * @returns True if all pins' preferred access points are considered. - */ - bool mapBTermAccessPointsToGCells( - std::map& gcell_pin_map, - frBTerm* term) const; + frBlockObject* pin) const; + void initPinGCellMap(frNet* net, frBlockObjectMap>& pin_gcell_map); // write guide @@ -276,6 +267,13 @@ class GuidePathFinder * @return True if all pins are visited, false otherwise. */ bool traverseGraph(); + + /** + * @brief Connects disconnected guides through adding a patch bridge guide. + */ + void connectDisconnectedComponents(const std::vector& rects, + TrackIntervalsByLayer& intvs); + /** * @brief Writes the final resulting set of guides to the net and updates the * GRPins. @@ -407,7 +405,12 @@ class GuidePathFinder const std::vector& pins, const std::vector>& pin_to_gcell, std::vector>& gr_pins) const; + /** + * @brief Does a bfs search from the given node idx. + */ + void bfs(int node_idx); frDesign* getDesign() const { return design_; } + frTechObject* getTech() const { return design_->getTech(); } frDesign* design_{nullptr}; Logger* logger_{nullptr}; @@ -421,5 +424,7 @@ class GuidePathFinder std::vector visited_; std::vector is_on_path_; std::vector prev_idx_; + frBlockObjectMap> pin_gcell_map_; + std::vector rects_; }; } // namespace drt::io \ No newline at end of file diff --git a/src/drt/src/pa/FlexPA.h b/src/drt/src/pa/FlexPA.h index 77a8d337753..feaed29dccd 100644 --- a/src/drt/src/pa/FlexPA.h +++ b/src/drt/src/pa/FlexPA.h @@ -374,25 +374,33 @@ class FlexPA frInstTerm* inst_term); /** - * @brief Determines coordinates of an End Point given a Begin Point. + * @brief Generates an end_point given an begin_point in the direction * - * @param end_point the End Point to be filled - * @param layer_polys a vector with all the pin polygons - * @param begin_point the Begin Point - * @param layer_num the number of the layer where begin_point is - * @param dir the direction the End Point is from the Begin Point - * @param is_block if the instance is a macro block. + * @param layer_polys Pin Polygons on the layer (used for a check) + * TODO: maybe the check can be moves to isPointOusideShapes, but not sure + * @param begin_point The begin reference point + * @param layer_num layer where the point is being created + * @param dir direction where the point will be created + * @param is_block wether the begin_point is from a macro block * - * @return if any polygon on the layer contains the End Point + * @returns the generated end point */ - bool check_endPointIsOutside( - Point& end_point, + Point genEndPoint( const std::vector>& layer_polys, const Point& begin_point, frLayerNum layer_num, frDirEnum dir, bool is_block); + /** + * @brief Checks if a point is outside the layer_polygons + * + * @return if the point is outside the pin shapes + */ + bool isPointOutsideShapes( + const Point& point, + const std::vector>& layer_polys); + template void check_addViaAccess( frAccessPoint* ap, diff --git a/src/drt/src/pa/FlexPA_prep.cpp b/src/drt/src/pa/FlexPA_prep.cpp index 2a19643eac8..8e6b79f663a 100644 --- a/src/drt/src/pa/FlexPA_prep.cpp +++ b/src/drt/src/pa/FlexPA_prep.cpp @@ -691,8 +691,7 @@ void FlexPA::genAPsFromPinShapes( } } -bool FlexPA::check_endPointIsOutside( - Point& end_point, +Point FlexPA::genEndPoint( const std::vector>& layer_polys, const Point& begin_point, const frLayerNum layer_num, @@ -744,17 +743,21 @@ bool FlexPA::check_endPointIsOutside( default: logger_->error(DRT, 70, "Unexpected direction in getPlanarEP."); } - end_point = {x, y}; - const gtl::point_data pt(x, y); - bool outside = true; + return {x, y}; +} + +bool FlexPA::isPointOutsideShapes( + const Point& point, + const std::vector>& layer_polys) +{ + const gtl::point_data pt(point.getX(), point.getY()); for (auto& layer_poly : layer_polys) { if (gtl::contains(layer_poly, pt)) { - outside = false; + return false; break; } } - - return outside; + return true; } template @@ -773,9 +776,9 @@ void FlexPA::check_addPlanarAccess( const bool is_block = inst_term && inst_term->getInst()->getMaster()->getMasterType().isBlock(); - Point end_point; - const bool is_outside = check_endPointIsOutside( - end_point, layer_polys, begin_point, ap->getLayerNum(), dir, is_block); + const Point end_point + = genEndPoint(layer_polys, begin_point, ap->getLayerNum(), dir, is_block); + const bool is_outside = isPointOutsideShapes(end_point, layer_polys); // skip if two width within shape for standard cell if (!is_outside) { ap->setAccess(dir, false); @@ -1071,13 +1074,11 @@ bool FlexPA::checkDirectionalViaAccess( const bool is_block = inst_term && inst_term->getInst()->getMaster()->getMasterType().isBlock(); - Point end_point; - check_endPointIsOutside(end_point, - layer_polys, - begin_point, - via->getViaDef()->getLayer2Num(), - dir, - is_block); + const Point end_point = genEndPoint(layer_polys, + begin_point, + via->getViaDef()->getLayer2Num(), + dir, + is_block); if (inst_term && inst_term->hasNet()) { via->addToNet(inst_term->getNet()); diff --git a/src/drt/test/ndr_vias1.ok b/src/drt/test/ndr_vias1.ok index f66ef2baa0f..2e226e79abf 100644 --- a/src/drt/test/ndr_vias1.ok +++ b/src/drt/test/ndr_vias1.ok @@ -38,14 +38,15 @@ [INFO DRT-0033] met4 shape region query size = 0. [INFO DRT-0033] via4 shape region query size = 0. [INFO DRT-0033] met5 shape region query size = 0. +[INFO DRT-1000] Pin _284_/A not in any guide. Attempting to patch guides to cover (at least part of) the pin. [INFO DRT-0178] Init guide query. [INFO DRT-0036] FR_MASTERSLICE guide region query size = 0. [INFO DRT-0036] FR_VIA guide region query size = 0. [INFO DRT-0036] li1 guide region query size = 51. [INFO DRT-0036] mcon guide region query size = 0. -[INFO DRT-0036] met1 guide region query size = 56. +[INFO DRT-0036] met1 guide region query size = 57. [INFO DRT-0036] via guide region query size = 0. -[INFO DRT-0036] met2 guide region query size = 34. +[INFO DRT-0036] met2 guide region query size = 35. [INFO DRT-0036] via2 guide region query size = 0. [INFO DRT-0036] met3 guide region query size = 0. [INFO DRT-0036] via3 guide region query size = 0. diff --git a/src/drt/test/ndr_vias2.ok b/src/drt/test/ndr_vias2.ok index 2b97f82f653..c00dbd6c06d 100644 --- a/src/drt/test/ndr_vias2.ok +++ b/src/drt/test/ndr_vias2.ok @@ -38,6 +38,7 @@ [INFO DRT-0033] met4 shape region query size = 0. [INFO DRT-0033] via4 shape region query size = 0. [INFO DRT-0033] met5 shape region query size = 0. +[INFO DRT-1000] Pin _284_/A not in any guide. Attempting to patch guides to cover (at least part of) the pin. [INFO DRT-0178] Init guide query. [INFO DRT-0036] FR_MASTERSLICE guide region query size = 0. [INFO DRT-0036] FR_VIA guide region query size = 0. @@ -45,12 +46,12 @@ [INFO DRT-0036] mcon guide region query size = 0. [INFO DRT-0036] met1 guide region query size = 49. [INFO DRT-0036] via guide region query size = 0. -[INFO DRT-0036] met2 guide region query size = 48. +[INFO DRT-0036] met2 guide region query size = 47. [INFO DRT-0036] via2 guide region query size = 0. -[INFO DRT-0036] met3 guide region query size = 47. +[INFO DRT-0036] met3 guide region query size = 46. [INFO DRT-0036] via3 guide region query size = 0. -[INFO DRT-0036] met4 guide region query size = 53. +[INFO DRT-0036] met4 guide region query size = 52. [INFO DRT-0036] via4 guide region query size = 0. -[INFO DRT-0036] met5 guide region query size = 31. +[INFO DRT-0036] met5 guide region query size = 30. [INFO DRT-0179] Init gr pin query. No differences found. diff --git a/src/gui/src/chartsWidget.cpp b/src/gui/src/chartsWidget.cpp index ca1cce2c2b1..3aedb054adc 100644 --- a/src/gui/src/chartsWidget.cpp +++ b/src/gui/src/chartsWidget.cpp @@ -274,7 +274,7 @@ SlackHistogramData ChartsWidget::fetchSlackHistogramData() StaPins end_points = stagui_->getEndPoints(); removeUnconstrainedPinsAndSetLimits(end_points); - data.constrained_pins = end_points; + data.constrained_pins = std::move(end_points); for (sta::Clock* clock : *stagui_->getClocks()) { data.clocks.insert(clock); diff --git a/src/gui/src/dbDescriptors.cpp b/src/gui/src/dbDescriptors.cpp index 99d6fbbbb51..4a4d27575fb 100644 --- a/src/gui/src/dbDescriptors.cpp +++ b/src/gui/src/dbDescriptors.cpp @@ -1820,6 +1820,11 @@ Descriptor::Properties DbBTermDescriptor::getProperties(std::any object) const {"IO type", bterm->getIoType().getString()}, {"Access Points", aps}}; + std::optional constraint = bterm->getConstraintRegion(); + if (constraint) { + props.push_back({"Constraint Region", constraint.value()}); + } + populateODBProperties(props, bterm); return props; @@ -3995,6 +4000,10 @@ Descriptor::Properties DbSiteDescriptor::getProperties(std::any object) const } props.push_back({"Symmetry", symmetry}); + if (auto site = std::any_cast(&object)) { + props.push_back({"Index", site->index_in_row}); + } + populateODBProperties(props, site); return props; diff --git a/src/gui/src/dbDescriptors.h b/src/gui/src/dbDescriptors.h index 157f1747ab3..3c68ca84689 100644 --- a/src/gui/src/dbDescriptors.h +++ b/src/gui/src/dbDescriptors.h @@ -665,7 +665,8 @@ class DbSiteDescriptor : public Descriptor struct SpecificSite { odb::dbSite* site; - odb::Rect rect; + const odb::Rect rect; + const int index_in_row; }; DbSiteDescriptor(odb::dbDatabase* db); diff --git a/src/gui/src/gui.tcl b/src/gui/src/gui.tcl index d97fd985e4d..1dd852e4ae5 100644 --- a/src/gui/src/gui.tcl +++ b/src/gui/src/gui.tcl @@ -199,7 +199,7 @@ proc save_clocktree_image { args } { if { [info exists keys(-clock)] } { set clock $keys(-clock) } else { - utl:error GUI 88 "-clock is required" + utl::error GUI 88 "-clock is required" } gui::save_clocktree_image $path $clock $corner $width $height diff --git a/src/gui/src/layoutViewer.cpp b/src/gui/src/layoutViewer.cpp index 9e13ee03b1b..0d3f5be7c86 100644 --- a/src/gui/src/layoutViewer.cpp +++ b/src/gui/src/layoutViewer.cpp @@ -751,7 +751,8 @@ std::pair LayoutViewer::searchNearestEdge( } if (options_->areSitesVisible()) { - for (const auto& [row, row_site] : getRowRects(block_, search_line)) { + for (const auto& [row, row_site, index] : + getRowRects(block_, search_line)) { odb::dbSite* site = nullptr; if (row->getObjectType() == odb::dbObjectType::dbSiteObj) { site = static_cast(row); @@ -997,7 +998,7 @@ void LayoutViewer::selectAt(odb::Rect region, std::vector& selections) } if (options_->areSitesVisible() && options_->areSitesSelectable()) { - for (const auto& [row_obj, rect] : getRowRects(block_, region)) { + for (const auto& [row_obj, rect, index] : getRowRects(block_, region)) { odb::dbSite* site = nullptr; if (row_obj->getObjectType() == odb::dbObjectType::dbSiteObj) { site = static_cast(row_obj); @@ -1013,8 +1014,8 @@ void LayoutViewer::selectAt(odb::Rect region, std::vector& selections) selections.push_back( gui_->makeSelected(static_cast(row_obj))); } else { - selections.push_back( - gui_->makeSelected(DbSiteDescriptor::SpecificSite{site, rect})); + selections.push_back(gui_->makeSelected( + DbSiteDescriptor::SpecificSite{site, rect, index})); } } } @@ -1425,9 +1426,8 @@ const LayoutViewer::Boxes* LayoutViewer::boxesByLayer(dbMaster* master, return nullptr; } -std::vector> LayoutViewer::getRowRects( - odb::dbBlock* block, - const odb::Rect& bounds) +std::vector> +LayoutViewer::getRowRects(odb::dbBlock* block, const odb::Rect& bounds) { const int min_resolution_site = nominalViewableResolution(); int min_resolution_row = min_resolution_site; @@ -1444,11 +1444,11 @@ std::vector> LayoutViewer::getRowRects( bounds.yMax(), min_resolution_row); - std::vector> rects; + std::vector> rects; for (auto& [box, row] : rows) { odb::Point pt = row->getOrigin(); - rects.emplace_back(row, row->getBBox()); + rects.emplace_back(row, row->getBBox(), 0); dbSite* site = row->getSite(); int spacing = row->getSpacing(); @@ -1493,7 +1493,7 @@ std::vector> LayoutViewer::getRowRects( const Rect row_rect(pt.x(), pt.y(), pt.x() + w, pt.y() + h); if (row_rect.intersects(bounds)) { // only paint rows that can be seen - rects.emplace_back(obj, row_rect); + rects.emplace_back(obj, row_rect, i); } if (dir == dbRowDir::HORIZONTAL) { diff --git a/src/gui/src/layoutViewer.h b/src/gui/src/layoutViewer.h index c990e61bbc6..0687e145087 100644 --- a/src/gui/src/layoutViewer.h +++ b/src/gui/src/layoutViewer.h @@ -323,7 +323,7 @@ class LayoutViewer : public QWidget int instanceSizeLimit() const; int shapeSizeLimit() const; - std::vector> getRowRects( + std::vector> getRowRects( odb::dbBlock* block, const odb::Rect& bounds); diff --git a/src/gui/src/renderThread.cpp b/src/gui/src/renderThread.cpp index b367b4b43d6..d2ce56cb00a 100644 --- a/src/gui/src/renderThread.cpp +++ b/src/gui/src/renderThread.cpp @@ -377,7 +377,8 @@ void RenderThread::drawRows(QPainter* painter, return; } - for (const auto& [row, row_site] : viewer_->getRowRects(block, bounds)) { + for (const auto& [row, row_site, index] : + viewer_->getRowRects(block, bounds)) { if (restart_) { break; } diff --git a/src/gui/src/staDescriptors.cpp b/src/gui/src/staDescriptors.cpp index 9b149db9c6c..836496c1d9c 100644 --- a/src/gui/src/staDescriptors.cpp +++ b/src/gui/src/staDescriptors.cpp @@ -206,7 +206,7 @@ Descriptor::Properties LibertyLibraryDescriptor::getProperties( for (auto* corner : *sta_->corners()) { for (const sta::MinMax* min_max : {sta::MinMax::min(), sta::MinMax::max()}) { - const auto libs = corner->libertyLibraries(min_max); + const auto& libs = corner->libertyLibraries(min_max); if (std::find(libs.begin(), libs.end(), library) != libs.end()) { corners.insert(gui->makeSelected(corner)); } diff --git a/src/gui/src/staGuiInterface.cpp b/src/gui/src/staGuiInterface.cpp index fae12df0182..f1541435fab 100644 --- a/src/gui/src/staGuiInterface.cpp +++ b/src/gui/src/staGuiInterface.cpp @@ -1036,8 +1036,13 @@ TimingPathList STAGuiInterface::getTimingPaths( sta::RiseFallBoth::riseFall()); } - sta::Search* search = sta_->search(); + std::unique_ptr group_names; + if (!path_group_name.empty()) { + group_names = std::make_unique(); + group_names->insert(path_group_name.c_str()); + } + sta::Search* search = sta_->search(); sta::PathEndSeq path_ends = search->findPathEnds( // from, thrus, to, unconstrained e_from, @@ -1054,7 +1059,7 @@ TimingPathList STAGuiInterface::getTimingPaths( -sta::INF, sta::INF, // slack_min, slack_max, true, // sort_by_slack - nullptr, // group_names + group_names.get(), // setup, hold, recovery, removal, use_max_, !use_max_, @@ -1064,13 +1069,7 @@ TimingPathList STAGuiInterface::getTimingPaths( false, false); - sta::PathGroup* path_group - = search->findPathGroup(path_group_name.c_str(), sta::MinMax::max()); for (auto& path_end : path_ends) { - if (path_group && path_group != search->pathGroup(path_end)) { - continue; - } - TimingPath* timing_path = new TimingPath(); sta::Path* path = path_end->path(); diff --git a/src/ifp/README.md b/src/ifp/README.md index 5af0ae9f051..6ec0e64f03a 100644 --- a/src/ifp/README.md +++ b/src/ifp/README.md @@ -60,6 +60,7 @@ initialize_floorplan [-additional_sites site_names] [-site site_name] [-row_parity NONE|EVEN|ODD] + [-flip_sites site_names] ``` #### Options @@ -74,6 +75,7 @@ initialize_floorplan | `-die_area` | Die area coordinates in microns (lower left x/y and upper right x/y coordinates). | | `-core_area` | Core area coordinates in microns (lower left x/y and upper right x/y coordinates). | | `-row_parity` | Snap to either an odd (`ODD`) or even (`EVEN`) number of rows. Defaults to `NONE` (no constraint on parity). | +| `-flip_sites` | Flip the orientations of rows matching these sites. Sites listed under this option will create `FS`-oriented rows at even indices and `N`-oriented rows at odd ones, and vice versa for sites not listed under this option. (e.g. `{SITEXX, SITEYY}`) | ### Make Tracks diff --git a/src/ifp/include/ifp/InitFloorplan.hh b/src/ifp/include/ifp/InitFloorplan.hh index f280592c199..05369bfce2d 100644 --- a/src/ifp/include/ifp/InitFloorplan.hh +++ b/src/ifp/include/ifp/InitFloorplan.hh @@ -78,7 +78,8 @@ class InitFloorplan int core_space_right, odb::dbSite* base_site, const std::vector& additional_sites = {}, - RowParity row_parity = RowParity::NONE); + RowParity row_parity = RowParity::NONE, + const std::set& flipped_sites = {}); // The base_site determines the single-height rows. For hybrid rows it is // a site containing a row pattern. @@ -86,7 +87,8 @@ class InitFloorplan const odb::Rect& core, odb::dbSite* base_site, const std::vector& additional_sites = {}, - RowParity row_parity = RowParity::NONE); + RowParity row_parity = RowParity::NONE, + const std::set& flipped_sites = {}); void insertTiecells(odb::dbMTerm* tie_term, const std::string& prefix = "TIEOFF_"); @@ -115,7 +117,8 @@ class InitFloorplan void makeUniformRows(odb::dbSite* base_site, const SitesByName& sites_by_name, const odb::Rect& core, - RowParity row_parity); + RowParity row_parity, + const std::set& flipped_sites); void makeHybridRows(odb::dbSite* base_hybrid_site, const SitesByName& sites_by_name, const odb::Rect& core); diff --git a/src/ifp/src/InitFloorplan-py.i b/src/ifp/src/InitFloorplan-py.i index 5570ec06926..2a05159a834 100644 --- a/src/ifp/src/InitFloorplan-py.i +++ b/src/ifp/src/InitFloorplan-py.i @@ -40,8 +40,35 @@ %include "../../Exception-py.i" %include - -%import +%include +%include %import "dbtypes.i" +%typemap(typecheck,precedence=SWIG_TYPECHECK_STRING) ifp::RowParity { + const char *str = PyUnicode_AsUTF8($input); + $1 = strcasecmp(str, "NONE") != 0 || strcasecmp(str, "EVEN") != 0 || strcasecmp(str, "ODD") != 0; +} + +%typemap(in) ifp::RowParity { + const char *str = PyUnicode_AsUTF8($input); + if (strcasecmp(str, "NONE") == 0) { + $1 = ifp::RowParity::NONE; + } else if (strcasecmp(str, "EVEN") == 0) { + $1 = ifp::RowParity::EVEN; + } else if (strcasecmp(str, "ODD") == 0) { + $1 = ifp::RowParity::ODD; + } else { + $1 = ifp::RowParity::NONE; + } +} + +// These are needed to coax swig into sending or returning Python +// lists, arrays, or sets (as appropriate) of opaque pointers. Note +// that you must %include (not %import) and +// before these definitions +namespace std { + %template(site_list) std::vector; + %template(site_set) std::set; +} + %include "ifp/InitFloorplan.hh" diff --git a/src/ifp/src/InitFloorplan.cc b/src/ifp/src/InitFloorplan.cc index 1bc0da85b75..d24c8eaea59 100644 --- a/src/ifp/src/InitFloorplan.cc +++ b/src/ifp/src/InitFloorplan.cc @@ -107,7 +107,8 @@ void InitFloorplan::initFloorplan( int core_space_right, odb::dbSite* base_site, const std::vector& additional_sites, - RowParity row_parity) + RowParity row_parity, + const std::set& flipped_sites) { utl::Validator v(logger_, IFP); v.check_non_negative("utilization", utilization, 12); @@ -135,7 +136,8 @@ void InitFloorplan::initFloorplan( {core_lx, core_ly, core_ux, core_uy}, base_site, additional_sites, - row_parity); + row_parity, + flipped_sites); } double InitFloorplan::designArea() @@ -160,7 +162,8 @@ void InitFloorplan::initFloorplan( const odb::Rect& core, odb::dbSite* base_site, const std::vector& additional_sites, - RowParity row_parity) + RowParity row_parity, + const std::set& flipped_sites) { Rect die_area(snapToMfgGrid(die.xMin()), snapToMfgGrid(die.yMin()), @@ -227,7 +230,8 @@ void InitFloorplan::initFloorplan( } makeHybridRows(base_site, sites_by_name, snapped_core); } else { - makeUniformRows(base_site, sites_by_name, snapped_core, row_parity); + makeUniformRows( + base_site, sites_by_name, snapped_core, row_parity, flipped_sites); } updateVoltageDomain(clx, cly, cux, cuy); @@ -417,7 +421,8 @@ void InitFloorplan::addUsedSites( void InitFloorplan::makeUniformRows(odb::dbSite* base_site, const SitesByName& sites_by_name, const odb::Rect& core, - RowParity row_parity) + RowParity row_parity, + const std::set& flipped_sites) { const int core_dx = core.dx(); const int core_dy = core.dy(); @@ -427,7 +432,7 @@ void InitFloorplan::makeUniformRows(odb::dbSite* base_site, auto make_rows = [&](dbSite* site) { const uint site_dy = site->getHeight(); int rows_y = core_dy / site_dy; - + bool flip = flipped_sites.find(site) != flipped_sites.end(); switch (row_parity) { case RowParity::NONE: break; @@ -445,8 +450,8 @@ void InitFloorplan::makeUniformRows(odb::dbSite* base_site, int y = core.yMin(); for (int row = 0; row < rows_y; row++) { - dbOrientType orient = (row % 2 == 0) ? dbOrientType::R0 // N - : dbOrientType::MX; // FS + dbOrientType orient = ((row + flip) % 2 == 0) ? dbOrientType::R0 // N + : dbOrientType::MX; // FS string row_name = fmt::format("ROW_{}", block_->getRows().size()); dbRow::create(block_, row_name.c_str(), diff --git a/src/ifp/src/InitFloorplan.i b/src/ifp/src/InitFloorplan.i index 1673033990c..2006a5f20fd 100644 --- a/src/ifp/src/InitFloorplan.i +++ b/src/ifp/src/InitFloorplan.i @@ -102,37 +102,44 @@ namespace ifp { void init_floorplan_core(int die_lx, - int die_ly, - int die_ux, - int die_uy, - int core_lx, - int core_ly, - int core_ux, - int core_uy, - odb::dbSite* site, - const std::vector& additional_sites, - ifp::RowParity row_parity) + int die_ly, + int die_ux, + int die_uy, + int core_lx, + int core_ly, + int core_ux, + int core_uy, + odb::dbSite* site, + const std::vector& additional_sites, + ifp::RowParity row_parity, + const std::vector& flipped_sites) { + std::set flipped_sites_set(flipped_sites.begin(), + flipped_sites.end()); get_floorplan().initFloorplan({die_lx, die_ly, die_ux, die_uy}, {core_lx, core_ly, core_ux, core_uy}, - site, additional_sites, row_parity); + site, additional_sites, row_parity, flipped_sites_set); } void init_floorplan_util(double util, double aspect_ratio, int core_space_bottom, - int core_space_top, + int core_space_top, int core_space_left, int core_space_right, - odb::dbSite* site, - const std::vector& additional_sites, - ifp::RowParity row_parity) + odb::dbSite* site, + const std::vector& additional_sites, + ifp::RowParity row_parity, + const std::vector& flipped_sites) { + std::set flipped_sites_set(flipped_sites.begin(), + flipped_sites.end()); get_floorplan().initFloorplan(util, aspect_ratio, core_space_bottom, core_space_top, core_space_left, core_space_right, - site, additional_sites, row_parity); + site, additional_sites, row_parity, + flipped_sites_set); } void diff --git a/src/ifp/src/InitFloorplan.tcl b/src/ifp/src/InitFloorplan.tcl index f6b7e7334e7..67eed874423 100644 --- a/src/ifp/src/InitFloorplan.tcl +++ b/src/ifp/src/InitFloorplan.tcl @@ -40,12 +40,13 @@ sta::define_cmd_args "initialize_floorplan" {[-utilization util]\ [-core_area {lx ly ux uy}]\ [-additional_sites site_names]\ [-site site_name]\ - [-row_parity NONE|ODD|EVEN]} + [-row_parity NONE|ODD|EVEN]\ + [-flip_sites site_names]} proc initialize_floorplan { args } { sta::parse_key_args "initialize_floorplan" args \ keys {-utilization -aspect_ratio -core_space \ - -die_area -core_area -site -additional_sites -row_parity} \ + -die_area -core_area -site -additional_sites -row_parity -flip_sites} \ flags {} sta::check_argc_eq0 "initialize_floorplan" $args @@ -64,6 +65,13 @@ proc initialize_floorplan { args } { } } + set flipped_sites {} + if { [info exists keys(-flip_sites)] } { + foreach sitename $keys(-flip_sites) { + lappend flipped_sites [ifp::find_site $sitename] + } + } + set row_parity "NONE" if { [info exists keys(-row_parity)] } { set row_parity $keys(-row_parity) @@ -111,7 +119,8 @@ proc initialize_floorplan { args } { [ord::microns_to_dbu $core_sp_right] \ $site \ $additional_sites \ - $row_parity + $row_parity \ + $flipped_sites } elseif { [info exists keys(-die_area)] } { set die_area $keys(-die_area) if { [llength $die_area] != 4 } { @@ -143,7 +152,8 @@ proc initialize_floorplan { args } { [ord::microns_to_dbu $core_ux] [ord::microns_to_dbu $core_uy] \ $site \ $additional_sites \ - $row_parity + $row_parity \ + $flipped_sites } else { utl::error IFP 17 "no -core_area specified." } diff --git a/src/ifp/test/init_floorplan_flip_sites.defok b/src/ifp/test/init_floorplan_flip_sites.defok new file mode 100644 index 00000000000..e7ffd6dfc39 --- /dev/null +++ b/src/ifp/test/init_floorplan_flip_sites.defok @@ -0,0 +1,604 @@ +VERSION 5.8 ; +DIVIDERCHAR "/" ; +BUSBITCHARS "[]" ; +DESIGN top ; +UNITS DISTANCE MICRONS 2000 ; +DIEAREA ( 0 0 ) ( 2000000 2000000 ) ; +ROW ROW_0 FreePDK45_38x28_10R_NP_162NW_34O 200260 201600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_1 FreePDK45_38x28_10R_NP_162NW_34O 200260 204400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_2 FreePDK45_38x28_10R_NP_162NW_34O 200260 207200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_3 FreePDK45_38x28_10R_NP_162NW_34O 200260 210000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_4 FreePDK45_38x28_10R_NP_162NW_34O 200260 212800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_5 FreePDK45_38x28_10R_NP_162NW_34O 200260 215600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_6 FreePDK45_38x28_10R_NP_162NW_34O 200260 218400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_7 FreePDK45_38x28_10R_NP_162NW_34O 200260 221200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_8 FreePDK45_38x28_10R_NP_162NW_34O 200260 224000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_9 FreePDK45_38x28_10R_NP_162NW_34O 200260 226800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_10 FreePDK45_38x28_10R_NP_162NW_34O 200260 229600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_11 FreePDK45_38x28_10R_NP_162NW_34O 200260 232400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_12 FreePDK45_38x28_10R_NP_162NW_34O 200260 235200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_13 FreePDK45_38x28_10R_NP_162NW_34O 200260 238000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_14 FreePDK45_38x28_10R_NP_162NW_34O 200260 240800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_15 FreePDK45_38x28_10R_NP_162NW_34O 200260 243600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_16 FreePDK45_38x28_10R_NP_162NW_34O 200260 246400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_17 FreePDK45_38x28_10R_NP_162NW_34O 200260 249200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_18 FreePDK45_38x28_10R_NP_162NW_34O 200260 252000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_19 FreePDK45_38x28_10R_NP_162NW_34O 200260 254800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_20 FreePDK45_38x28_10R_NP_162NW_34O 200260 257600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_21 FreePDK45_38x28_10R_NP_162NW_34O 200260 260400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_22 FreePDK45_38x28_10R_NP_162NW_34O 200260 263200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_23 FreePDK45_38x28_10R_NP_162NW_34O 200260 266000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_24 FreePDK45_38x28_10R_NP_162NW_34O 200260 268800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_25 FreePDK45_38x28_10R_NP_162NW_34O 200260 271600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_26 FreePDK45_38x28_10R_NP_162NW_34O 200260 274400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_27 FreePDK45_38x28_10R_NP_162NW_34O 200260 277200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_28 FreePDK45_38x28_10R_NP_162NW_34O 200260 280000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_29 FreePDK45_38x28_10R_NP_162NW_34O 200260 282800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_30 FreePDK45_38x28_10R_NP_162NW_34O 200260 285600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_31 FreePDK45_38x28_10R_NP_162NW_34O 200260 288400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_32 FreePDK45_38x28_10R_NP_162NW_34O 200260 291200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_33 FreePDK45_38x28_10R_NP_162NW_34O 200260 294000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_34 FreePDK45_38x28_10R_NP_162NW_34O 200260 296800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_35 FreePDK45_38x28_10R_NP_162NW_34O 200260 299600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_36 FreePDK45_38x28_10R_NP_162NW_34O 200260 302400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_37 FreePDK45_38x28_10R_NP_162NW_34O 200260 305200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_38 FreePDK45_38x28_10R_NP_162NW_34O 200260 308000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_39 FreePDK45_38x28_10R_NP_162NW_34O 200260 310800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_40 FreePDK45_38x28_10R_NP_162NW_34O 200260 313600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_41 FreePDK45_38x28_10R_NP_162NW_34O 200260 316400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_42 FreePDK45_38x28_10R_NP_162NW_34O 200260 319200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_43 FreePDK45_38x28_10R_NP_162NW_34O 200260 322000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_44 FreePDK45_38x28_10R_NP_162NW_34O 200260 324800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_45 FreePDK45_38x28_10R_NP_162NW_34O 200260 327600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_46 FreePDK45_38x28_10R_NP_162NW_34O 200260 330400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_47 FreePDK45_38x28_10R_NP_162NW_34O 200260 333200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_48 FreePDK45_38x28_10R_NP_162NW_34O 200260 336000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_49 FreePDK45_38x28_10R_NP_162NW_34O 200260 338800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_50 FreePDK45_38x28_10R_NP_162NW_34O 200260 341600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_51 FreePDK45_38x28_10R_NP_162NW_34O 200260 344400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_52 FreePDK45_38x28_10R_NP_162NW_34O 200260 347200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_53 FreePDK45_38x28_10R_NP_162NW_34O 200260 350000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_54 FreePDK45_38x28_10R_NP_162NW_34O 200260 352800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_55 FreePDK45_38x28_10R_NP_162NW_34O 200260 355600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_56 FreePDK45_38x28_10R_NP_162NW_34O 200260 358400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_57 FreePDK45_38x28_10R_NP_162NW_34O 200260 361200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_58 FreePDK45_38x28_10R_NP_162NW_34O 200260 364000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_59 FreePDK45_38x28_10R_NP_162NW_34O 200260 366800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_60 FreePDK45_38x28_10R_NP_162NW_34O 200260 369600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_61 FreePDK45_38x28_10R_NP_162NW_34O 200260 372400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_62 FreePDK45_38x28_10R_NP_162NW_34O 200260 375200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_63 FreePDK45_38x28_10R_NP_162NW_34O 200260 378000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_64 FreePDK45_38x28_10R_NP_162NW_34O 200260 380800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_65 FreePDK45_38x28_10R_NP_162NW_34O 200260 383600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_66 FreePDK45_38x28_10R_NP_162NW_34O 200260 386400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_67 FreePDK45_38x28_10R_NP_162NW_34O 200260 389200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_68 FreePDK45_38x28_10R_NP_162NW_34O 200260 392000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_69 FreePDK45_38x28_10R_NP_162NW_34O 200260 394800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_70 FreePDK45_38x28_10R_NP_162NW_34O 200260 397600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_71 FreePDK45_38x28_10R_NP_162NW_34O 200260 400400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_72 FreePDK45_38x28_10R_NP_162NW_34O 200260 403200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_73 FreePDK45_38x28_10R_NP_162NW_34O 200260 406000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_74 FreePDK45_38x28_10R_NP_162NW_34O 200260 408800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_75 FreePDK45_38x28_10R_NP_162NW_34O 200260 411600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_76 FreePDK45_38x28_10R_NP_162NW_34O 200260 414400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_77 FreePDK45_38x28_10R_NP_162NW_34O 200260 417200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_78 FreePDK45_38x28_10R_NP_162NW_34O 200260 420000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_79 FreePDK45_38x28_10R_NP_162NW_34O 200260 422800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_80 FreePDK45_38x28_10R_NP_162NW_34O 200260 425600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_81 FreePDK45_38x28_10R_NP_162NW_34O 200260 428400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_82 FreePDK45_38x28_10R_NP_162NW_34O 200260 431200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_83 FreePDK45_38x28_10R_NP_162NW_34O 200260 434000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_84 FreePDK45_38x28_10R_NP_162NW_34O 200260 436800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_85 FreePDK45_38x28_10R_NP_162NW_34O 200260 439600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_86 FreePDK45_38x28_10R_NP_162NW_34O 200260 442400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_87 FreePDK45_38x28_10R_NP_162NW_34O 200260 445200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_88 FreePDK45_38x28_10R_NP_162NW_34O 200260 448000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_89 FreePDK45_38x28_10R_NP_162NW_34O 200260 450800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_90 FreePDK45_38x28_10R_NP_162NW_34O 200260 453600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_91 FreePDK45_38x28_10R_NP_162NW_34O 200260 456400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_92 FreePDK45_38x28_10R_NP_162NW_34O 200260 459200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_93 FreePDK45_38x28_10R_NP_162NW_34O 200260 462000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_94 FreePDK45_38x28_10R_NP_162NW_34O 200260 464800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_95 FreePDK45_38x28_10R_NP_162NW_34O 200260 467600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_96 FreePDK45_38x28_10R_NP_162NW_34O 200260 470400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_97 FreePDK45_38x28_10R_NP_162NW_34O 200260 473200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_98 FreePDK45_38x28_10R_NP_162NW_34O 200260 476000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_99 FreePDK45_38x28_10R_NP_162NW_34O 200260 478800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_100 FreePDK45_38x28_10R_NP_162NW_34O 200260 481600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_101 FreePDK45_38x28_10R_NP_162NW_34O 200260 484400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_102 FreePDK45_38x28_10R_NP_162NW_34O 200260 487200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_103 FreePDK45_38x28_10R_NP_162NW_34O 200260 490000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_104 FreePDK45_38x28_10R_NP_162NW_34O 200260 492800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_105 FreePDK45_38x28_10R_NP_162NW_34O 200260 495600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_106 FreePDK45_38x28_10R_NP_162NW_34O 200260 498400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_107 FreePDK45_38x28_10R_NP_162NW_34O 200260 501200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_108 FreePDK45_38x28_10R_NP_162NW_34O 200260 504000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_109 FreePDK45_38x28_10R_NP_162NW_34O 200260 506800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_110 FreePDK45_38x28_10R_NP_162NW_34O 200260 509600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_111 FreePDK45_38x28_10R_NP_162NW_34O 200260 512400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_112 FreePDK45_38x28_10R_NP_162NW_34O 200260 515200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_113 FreePDK45_38x28_10R_NP_162NW_34O 200260 518000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_114 FreePDK45_38x28_10R_NP_162NW_34O 200260 520800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_115 FreePDK45_38x28_10R_NP_162NW_34O 200260 523600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_116 FreePDK45_38x28_10R_NP_162NW_34O 200260 526400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_117 FreePDK45_38x28_10R_NP_162NW_34O 200260 529200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_118 FreePDK45_38x28_10R_NP_162NW_34O 200260 532000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_119 FreePDK45_38x28_10R_NP_162NW_34O 200260 534800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_120 FreePDK45_38x28_10R_NP_162NW_34O 200260 537600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_121 FreePDK45_38x28_10R_NP_162NW_34O 200260 540400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_122 FreePDK45_38x28_10R_NP_162NW_34O 200260 543200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_123 FreePDK45_38x28_10R_NP_162NW_34O 200260 546000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_124 FreePDK45_38x28_10R_NP_162NW_34O 200260 548800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_125 FreePDK45_38x28_10R_NP_162NW_34O 200260 551600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_126 FreePDK45_38x28_10R_NP_162NW_34O 200260 554400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_127 FreePDK45_38x28_10R_NP_162NW_34O 200260 557200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_128 FreePDK45_38x28_10R_NP_162NW_34O 200260 560000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_129 FreePDK45_38x28_10R_NP_162NW_34O 200260 562800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_130 FreePDK45_38x28_10R_NP_162NW_34O 200260 565600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_131 FreePDK45_38x28_10R_NP_162NW_34O 200260 568400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_132 FreePDK45_38x28_10R_NP_162NW_34O 200260 571200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_133 FreePDK45_38x28_10R_NP_162NW_34O 200260 574000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_134 FreePDK45_38x28_10R_NP_162NW_34O 200260 576800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_135 FreePDK45_38x28_10R_NP_162NW_34O 200260 579600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_136 FreePDK45_38x28_10R_NP_162NW_34O 200260 582400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_137 FreePDK45_38x28_10R_NP_162NW_34O 200260 585200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_138 FreePDK45_38x28_10R_NP_162NW_34O 200260 588000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_139 FreePDK45_38x28_10R_NP_162NW_34O 200260 590800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_140 FreePDK45_38x28_10R_NP_162NW_34O 200260 593600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_141 FreePDK45_38x28_10R_NP_162NW_34O 200260 596400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_142 FreePDK45_38x28_10R_NP_162NW_34O 200260 599200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_143 FreePDK45_38x28_10R_NP_162NW_34O 200260 602000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_144 FreePDK45_38x28_10R_NP_162NW_34O 200260 604800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_145 FreePDK45_38x28_10R_NP_162NW_34O 200260 607600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_146 FreePDK45_38x28_10R_NP_162NW_34O 200260 610400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_147 FreePDK45_38x28_10R_NP_162NW_34O 200260 613200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_148 FreePDK45_38x28_10R_NP_162NW_34O 200260 616000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_149 FreePDK45_38x28_10R_NP_162NW_34O 200260 618800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_150 FreePDK45_38x28_10R_NP_162NW_34O 200260 621600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_151 FreePDK45_38x28_10R_NP_162NW_34O 200260 624400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_152 FreePDK45_38x28_10R_NP_162NW_34O 200260 627200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_153 FreePDK45_38x28_10R_NP_162NW_34O 200260 630000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_154 FreePDK45_38x28_10R_NP_162NW_34O 200260 632800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_155 FreePDK45_38x28_10R_NP_162NW_34O 200260 635600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_156 FreePDK45_38x28_10R_NP_162NW_34O 200260 638400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_157 FreePDK45_38x28_10R_NP_162NW_34O 200260 641200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_158 FreePDK45_38x28_10R_NP_162NW_34O 200260 644000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_159 FreePDK45_38x28_10R_NP_162NW_34O 200260 646800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_160 FreePDK45_38x28_10R_NP_162NW_34O 200260 649600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_161 FreePDK45_38x28_10R_NP_162NW_34O 200260 652400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_162 FreePDK45_38x28_10R_NP_162NW_34O 200260 655200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_163 FreePDK45_38x28_10R_NP_162NW_34O 200260 658000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_164 FreePDK45_38x28_10R_NP_162NW_34O 200260 660800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_165 FreePDK45_38x28_10R_NP_162NW_34O 200260 663600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_166 FreePDK45_38x28_10R_NP_162NW_34O 200260 666400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_167 FreePDK45_38x28_10R_NP_162NW_34O 200260 669200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_168 FreePDK45_38x28_10R_NP_162NW_34O 200260 672000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_169 FreePDK45_38x28_10R_NP_162NW_34O 200260 674800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_170 FreePDK45_38x28_10R_NP_162NW_34O 200260 677600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_171 FreePDK45_38x28_10R_NP_162NW_34O 200260 680400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_172 FreePDK45_38x28_10R_NP_162NW_34O 200260 683200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_173 FreePDK45_38x28_10R_NP_162NW_34O 200260 686000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_174 FreePDK45_38x28_10R_NP_162NW_34O 200260 688800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_175 FreePDK45_38x28_10R_NP_162NW_34O 200260 691600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_176 FreePDK45_38x28_10R_NP_162NW_34O 200260 694400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_177 FreePDK45_38x28_10R_NP_162NW_34O 200260 697200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_178 FreePDK45_38x28_10R_NP_162NW_34O 200260 700000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_179 FreePDK45_38x28_10R_NP_162NW_34O 200260 702800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_180 FreePDK45_38x28_10R_NP_162NW_34O 200260 705600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_181 FreePDK45_38x28_10R_NP_162NW_34O 200260 708400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_182 FreePDK45_38x28_10R_NP_162NW_34O 200260 711200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_183 FreePDK45_38x28_10R_NP_162NW_34O 200260 714000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_184 FreePDK45_38x28_10R_NP_162NW_34O 200260 716800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_185 FreePDK45_38x28_10R_NP_162NW_34O 200260 719600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_186 FreePDK45_38x28_10R_NP_162NW_34O 200260 722400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_187 FreePDK45_38x28_10R_NP_162NW_34O 200260 725200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_188 FreePDK45_38x28_10R_NP_162NW_34O 200260 728000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_189 FreePDK45_38x28_10R_NP_162NW_34O 200260 730800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_190 FreePDK45_38x28_10R_NP_162NW_34O 200260 733600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_191 FreePDK45_38x28_10R_NP_162NW_34O 200260 736400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_192 FreePDK45_38x28_10R_NP_162NW_34O 200260 739200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_193 FreePDK45_38x28_10R_NP_162NW_34O 200260 742000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_194 FreePDK45_38x28_10R_NP_162NW_34O 200260 744800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_195 FreePDK45_38x28_10R_NP_162NW_34O 200260 747600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_196 FreePDK45_38x28_10R_NP_162NW_34O 200260 750400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_197 FreePDK45_38x28_10R_NP_162NW_34O 200260 753200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_198 FreePDK45_38x28_10R_NP_162NW_34O 200260 756000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_199 FreePDK45_38x28_10R_NP_162NW_34O 200260 758800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_200 FreePDK45_38x28_10R_NP_162NW_34O 200260 761600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_201 FreePDK45_38x28_10R_NP_162NW_34O 200260 764400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_202 FreePDK45_38x28_10R_NP_162NW_34O 200260 767200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_203 FreePDK45_38x28_10R_NP_162NW_34O 200260 770000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_204 FreePDK45_38x28_10R_NP_162NW_34O 200260 772800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_205 FreePDK45_38x28_10R_NP_162NW_34O 200260 775600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_206 FreePDK45_38x28_10R_NP_162NW_34O 200260 778400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_207 FreePDK45_38x28_10R_NP_162NW_34O 200260 781200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_208 FreePDK45_38x28_10R_NP_162NW_34O 200260 784000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_209 FreePDK45_38x28_10R_NP_162NW_34O 200260 786800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_210 FreePDK45_38x28_10R_NP_162NW_34O 200260 789600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_211 FreePDK45_38x28_10R_NP_162NW_34O 200260 792400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_212 FreePDK45_38x28_10R_NP_162NW_34O 200260 795200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_213 FreePDK45_38x28_10R_NP_162NW_34O 200260 798000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_214 FreePDK45_38x28_10R_NP_162NW_34O 200260 800800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_215 FreePDK45_38x28_10R_NP_162NW_34O 200260 803600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_216 FreePDK45_38x28_10R_NP_162NW_34O 200260 806400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_217 FreePDK45_38x28_10R_NP_162NW_34O 200260 809200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_218 FreePDK45_38x28_10R_NP_162NW_34O 200260 812000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_219 FreePDK45_38x28_10R_NP_162NW_34O 200260 814800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_220 FreePDK45_38x28_10R_NP_162NW_34O 200260 817600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_221 FreePDK45_38x28_10R_NP_162NW_34O 200260 820400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_222 FreePDK45_38x28_10R_NP_162NW_34O 200260 823200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_223 FreePDK45_38x28_10R_NP_162NW_34O 200260 826000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_224 FreePDK45_38x28_10R_NP_162NW_34O 200260 828800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_225 FreePDK45_38x28_10R_NP_162NW_34O 200260 831600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_226 FreePDK45_38x28_10R_NP_162NW_34O 200260 834400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_227 FreePDK45_38x28_10R_NP_162NW_34O 200260 837200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_228 FreePDK45_38x28_10R_NP_162NW_34O 200260 840000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_229 FreePDK45_38x28_10R_NP_162NW_34O 200260 842800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_230 FreePDK45_38x28_10R_NP_162NW_34O 200260 845600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_231 FreePDK45_38x28_10R_NP_162NW_34O 200260 848400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_232 FreePDK45_38x28_10R_NP_162NW_34O 200260 851200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_233 FreePDK45_38x28_10R_NP_162NW_34O 200260 854000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_234 FreePDK45_38x28_10R_NP_162NW_34O 200260 856800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_235 FreePDK45_38x28_10R_NP_162NW_34O 200260 859600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_236 FreePDK45_38x28_10R_NP_162NW_34O 200260 862400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_237 FreePDK45_38x28_10R_NP_162NW_34O 200260 865200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_238 FreePDK45_38x28_10R_NP_162NW_34O 200260 868000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_239 FreePDK45_38x28_10R_NP_162NW_34O 200260 870800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_240 FreePDK45_38x28_10R_NP_162NW_34O 200260 873600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_241 FreePDK45_38x28_10R_NP_162NW_34O 200260 876400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_242 FreePDK45_38x28_10R_NP_162NW_34O 200260 879200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_243 FreePDK45_38x28_10R_NP_162NW_34O 200260 882000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_244 FreePDK45_38x28_10R_NP_162NW_34O 200260 884800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_245 FreePDK45_38x28_10R_NP_162NW_34O 200260 887600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_246 FreePDK45_38x28_10R_NP_162NW_34O 200260 890400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_247 FreePDK45_38x28_10R_NP_162NW_34O 200260 893200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_248 FreePDK45_38x28_10R_NP_162NW_34O 200260 896000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_249 FreePDK45_38x28_10R_NP_162NW_34O 200260 898800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_250 FreePDK45_38x28_10R_NP_162NW_34O 200260 901600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_251 FreePDK45_38x28_10R_NP_162NW_34O 200260 904400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_252 FreePDK45_38x28_10R_NP_162NW_34O 200260 907200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_253 FreePDK45_38x28_10R_NP_162NW_34O 200260 910000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_254 FreePDK45_38x28_10R_NP_162NW_34O 200260 912800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_255 FreePDK45_38x28_10R_NP_162NW_34O 200260 915600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_256 FreePDK45_38x28_10R_NP_162NW_34O 200260 918400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_257 FreePDK45_38x28_10R_NP_162NW_34O 200260 921200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_258 FreePDK45_38x28_10R_NP_162NW_34O 200260 924000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_259 FreePDK45_38x28_10R_NP_162NW_34O 200260 926800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_260 FreePDK45_38x28_10R_NP_162NW_34O 200260 929600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_261 FreePDK45_38x28_10R_NP_162NW_34O 200260 932400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_262 FreePDK45_38x28_10R_NP_162NW_34O 200260 935200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_263 FreePDK45_38x28_10R_NP_162NW_34O 200260 938000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_264 FreePDK45_38x28_10R_NP_162NW_34O 200260 940800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_265 FreePDK45_38x28_10R_NP_162NW_34O 200260 943600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_266 FreePDK45_38x28_10R_NP_162NW_34O 200260 946400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_267 FreePDK45_38x28_10R_NP_162NW_34O 200260 949200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_268 FreePDK45_38x28_10R_NP_162NW_34O 200260 952000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_269 FreePDK45_38x28_10R_NP_162NW_34O 200260 954800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_270 FreePDK45_38x28_10R_NP_162NW_34O 200260 957600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_271 FreePDK45_38x28_10R_NP_162NW_34O 200260 960400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_272 FreePDK45_38x28_10R_NP_162NW_34O 200260 963200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_273 FreePDK45_38x28_10R_NP_162NW_34O 200260 966000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_274 FreePDK45_38x28_10R_NP_162NW_34O 200260 968800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_275 FreePDK45_38x28_10R_NP_162NW_34O 200260 971600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_276 FreePDK45_38x28_10R_NP_162NW_34O 200260 974400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_277 FreePDK45_38x28_10R_NP_162NW_34O 200260 977200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_278 FreePDK45_38x28_10R_NP_162NW_34O 200260 980000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_279 FreePDK45_38x28_10R_NP_162NW_34O 200260 982800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_280 FreePDK45_38x28_10R_NP_162NW_34O 200260 985600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_281 FreePDK45_38x28_10R_NP_162NW_34O 200260 988400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_282 FreePDK45_38x28_10R_NP_162NW_34O 200260 991200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_283 FreePDK45_38x28_10R_NP_162NW_34O 200260 994000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_284 FreePDK45_38x28_10R_NP_162NW_34O 200260 996800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_285 FreePDK45_38x28_10R_NP_162NW_34O 200260 999600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_286 FreePDK45_38x28_10R_NP_162NW_34O 200260 1002400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_287 FreePDK45_38x28_10R_NP_162NW_34O 200260 1005200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_288 FreePDK45_38x28_10R_NP_162NW_34O 200260 1008000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_289 FreePDK45_38x28_10R_NP_162NW_34O 200260 1010800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_290 FreePDK45_38x28_10R_NP_162NW_34O 200260 1013600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_291 FreePDK45_38x28_10R_NP_162NW_34O 200260 1016400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_292 FreePDK45_38x28_10R_NP_162NW_34O 200260 1019200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_293 FreePDK45_38x28_10R_NP_162NW_34O 200260 1022000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_294 FreePDK45_38x28_10R_NP_162NW_34O 200260 1024800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_295 FreePDK45_38x28_10R_NP_162NW_34O 200260 1027600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_296 FreePDK45_38x28_10R_NP_162NW_34O 200260 1030400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_297 FreePDK45_38x28_10R_NP_162NW_34O 200260 1033200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_298 FreePDK45_38x28_10R_NP_162NW_34O 200260 1036000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_299 FreePDK45_38x28_10R_NP_162NW_34O 200260 1038800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_300 FreePDK45_38x28_10R_NP_162NW_34O 200260 1041600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_301 FreePDK45_38x28_10R_NP_162NW_34O 200260 1044400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_302 FreePDK45_38x28_10R_NP_162NW_34O 200260 1047200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_303 FreePDK45_38x28_10R_NP_162NW_34O 200260 1050000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_304 FreePDK45_38x28_10R_NP_162NW_34O 200260 1052800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_305 FreePDK45_38x28_10R_NP_162NW_34O 200260 1055600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_306 FreePDK45_38x28_10R_NP_162NW_34O 200260 1058400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_307 FreePDK45_38x28_10R_NP_162NW_34O 200260 1061200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_308 FreePDK45_38x28_10R_NP_162NW_34O 200260 1064000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_309 FreePDK45_38x28_10R_NP_162NW_34O 200260 1066800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_310 FreePDK45_38x28_10R_NP_162NW_34O 200260 1069600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_311 FreePDK45_38x28_10R_NP_162NW_34O 200260 1072400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_312 FreePDK45_38x28_10R_NP_162NW_34O 200260 1075200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_313 FreePDK45_38x28_10R_NP_162NW_34O 200260 1078000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_314 FreePDK45_38x28_10R_NP_162NW_34O 200260 1080800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_315 FreePDK45_38x28_10R_NP_162NW_34O 200260 1083600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_316 FreePDK45_38x28_10R_NP_162NW_34O 200260 1086400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_317 FreePDK45_38x28_10R_NP_162NW_34O 200260 1089200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_318 FreePDK45_38x28_10R_NP_162NW_34O 200260 1092000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_319 FreePDK45_38x28_10R_NP_162NW_34O 200260 1094800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_320 FreePDK45_38x28_10R_NP_162NW_34O 200260 1097600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_321 FreePDK45_38x28_10R_NP_162NW_34O 200260 1100400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_322 FreePDK45_38x28_10R_NP_162NW_34O 200260 1103200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_323 FreePDK45_38x28_10R_NP_162NW_34O 200260 1106000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_324 FreePDK45_38x28_10R_NP_162NW_34O 200260 1108800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_325 FreePDK45_38x28_10R_NP_162NW_34O 200260 1111600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_326 FreePDK45_38x28_10R_NP_162NW_34O 200260 1114400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_327 FreePDK45_38x28_10R_NP_162NW_34O 200260 1117200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_328 FreePDK45_38x28_10R_NP_162NW_34O 200260 1120000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_329 FreePDK45_38x28_10R_NP_162NW_34O 200260 1122800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_330 FreePDK45_38x28_10R_NP_162NW_34O 200260 1125600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_331 FreePDK45_38x28_10R_NP_162NW_34O 200260 1128400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_332 FreePDK45_38x28_10R_NP_162NW_34O 200260 1131200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_333 FreePDK45_38x28_10R_NP_162NW_34O 200260 1134000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_334 FreePDK45_38x28_10R_NP_162NW_34O 200260 1136800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_335 FreePDK45_38x28_10R_NP_162NW_34O 200260 1139600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_336 FreePDK45_38x28_10R_NP_162NW_34O 200260 1142400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_337 FreePDK45_38x28_10R_NP_162NW_34O 200260 1145200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_338 FreePDK45_38x28_10R_NP_162NW_34O 200260 1148000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_339 FreePDK45_38x28_10R_NP_162NW_34O 200260 1150800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_340 FreePDK45_38x28_10R_NP_162NW_34O 200260 1153600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_341 FreePDK45_38x28_10R_NP_162NW_34O 200260 1156400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_342 FreePDK45_38x28_10R_NP_162NW_34O 200260 1159200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_343 FreePDK45_38x28_10R_NP_162NW_34O 200260 1162000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_344 FreePDK45_38x28_10R_NP_162NW_34O 200260 1164800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_345 FreePDK45_38x28_10R_NP_162NW_34O 200260 1167600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_346 FreePDK45_38x28_10R_NP_162NW_34O 200260 1170400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_347 FreePDK45_38x28_10R_NP_162NW_34O 200260 1173200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_348 FreePDK45_38x28_10R_NP_162NW_34O 200260 1176000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_349 FreePDK45_38x28_10R_NP_162NW_34O 200260 1178800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_350 FreePDK45_38x28_10R_NP_162NW_34O 200260 1181600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_351 FreePDK45_38x28_10R_NP_162NW_34O 200260 1184400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_352 FreePDK45_38x28_10R_NP_162NW_34O 200260 1187200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_353 FreePDK45_38x28_10R_NP_162NW_34O 200260 1190000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_354 FreePDK45_38x28_10R_NP_162NW_34O 200260 1192800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_355 FreePDK45_38x28_10R_NP_162NW_34O 200260 1195600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_356 FreePDK45_38x28_10R_NP_162NW_34O 200260 1198400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_357 FreePDK45_38x28_10R_NP_162NW_34O 200260 1201200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_358 FreePDK45_38x28_10R_NP_162NW_34O 200260 1204000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_359 FreePDK45_38x28_10R_NP_162NW_34O 200260 1206800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_360 FreePDK45_38x28_10R_NP_162NW_34O 200260 1209600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_361 FreePDK45_38x28_10R_NP_162NW_34O 200260 1212400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_362 FreePDK45_38x28_10R_NP_162NW_34O 200260 1215200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_363 FreePDK45_38x28_10R_NP_162NW_34O 200260 1218000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_364 FreePDK45_38x28_10R_NP_162NW_34O 200260 1220800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_365 FreePDK45_38x28_10R_NP_162NW_34O 200260 1223600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_366 FreePDK45_38x28_10R_NP_162NW_34O 200260 1226400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_367 FreePDK45_38x28_10R_NP_162NW_34O 200260 1229200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_368 FreePDK45_38x28_10R_NP_162NW_34O 200260 1232000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_369 FreePDK45_38x28_10R_NP_162NW_34O 200260 1234800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_370 FreePDK45_38x28_10R_NP_162NW_34O 200260 1237600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_371 FreePDK45_38x28_10R_NP_162NW_34O 200260 1240400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_372 FreePDK45_38x28_10R_NP_162NW_34O 200260 1243200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_373 FreePDK45_38x28_10R_NP_162NW_34O 200260 1246000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_374 FreePDK45_38x28_10R_NP_162NW_34O 200260 1248800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_375 FreePDK45_38x28_10R_NP_162NW_34O 200260 1251600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_376 FreePDK45_38x28_10R_NP_162NW_34O 200260 1254400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_377 FreePDK45_38x28_10R_NP_162NW_34O 200260 1257200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_378 FreePDK45_38x28_10R_NP_162NW_34O 200260 1260000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_379 FreePDK45_38x28_10R_NP_162NW_34O 200260 1262800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_380 FreePDK45_38x28_10R_NP_162NW_34O 200260 1265600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_381 FreePDK45_38x28_10R_NP_162NW_34O 200260 1268400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_382 FreePDK45_38x28_10R_NP_162NW_34O 200260 1271200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_383 FreePDK45_38x28_10R_NP_162NW_34O 200260 1274000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_384 FreePDK45_38x28_10R_NP_162NW_34O 200260 1276800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_385 FreePDK45_38x28_10R_NP_162NW_34O 200260 1279600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_386 FreePDK45_38x28_10R_NP_162NW_34O 200260 1282400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_387 FreePDK45_38x28_10R_NP_162NW_34O 200260 1285200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_388 FreePDK45_38x28_10R_NP_162NW_34O 200260 1288000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_389 FreePDK45_38x28_10R_NP_162NW_34O 200260 1290800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_390 FreePDK45_38x28_10R_NP_162NW_34O 200260 1293600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_391 FreePDK45_38x28_10R_NP_162NW_34O 200260 1296400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_392 FreePDK45_38x28_10R_NP_162NW_34O 200260 1299200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_393 FreePDK45_38x28_10R_NP_162NW_34O 200260 1302000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_394 FreePDK45_38x28_10R_NP_162NW_34O 200260 1304800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_395 FreePDK45_38x28_10R_NP_162NW_34O 200260 1307600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_396 FreePDK45_38x28_10R_NP_162NW_34O 200260 1310400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_397 FreePDK45_38x28_10R_NP_162NW_34O 200260 1313200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_398 FreePDK45_38x28_10R_NP_162NW_34O 200260 1316000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_399 FreePDK45_38x28_10R_NP_162NW_34O 200260 1318800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_400 FreePDK45_38x28_10R_NP_162NW_34O 200260 1321600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_401 FreePDK45_38x28_10R_NP_162NW_34O 200260 1324400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_402 FreePDK45_38x28_10R_NP_162NW_34O 200260 1327200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_403 FreePDK45_38x28_10R_NP_162NW_34O 200260 1330000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_404 FreePDK45_38x28_10R_NP_162NW_34O 200260 1332800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_405 FreePDK45_38x28_10R_NP_162NW_34O 200260 1335600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_406 FreePDK45_38x28_10R_NP_162NW_34O 200260 1338400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_407 FreePDK45_38x28_10R_NP_162NW_34O 200260 1341200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_408 FreePDK45_38x28_10R_NP_162NW_34O 200260 1344000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_409 FreePDK45_38x28_10R_NP_162NW_34O 200260 1346800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_410 FreePDK45_38x28_10R_NP_162NW_34O 200260 1349600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_411 FreePDK45_38x28_10R_NP_162NW_34O 200260 1352400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_412 FreePDK45_38x28_10R_NP_162NW_34O 200260 1355200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_413 FreePDK45_38x28_10R_NP_162NW_34O 200260 1358000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_414 FreePDK45_38x28_10R_NP_162NW_34O 200260 1360800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_415 FreePDK45_38x28_10R_NP_162NW_34O 200260 1363600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_416 FreePDK45_38x28_10R_NP_162NW_34O 200260 1366400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_417 FreePDK45_38x28_10R_NP_162NW_34O 200260 1369200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_418 FreePDK45_38x28_10R_NP_162NW_34O 200260 1372000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_419 FreePDK45_38x28_10R_NP_162NW_34O 200260 1374800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_420 FreePDK45_38x28_10R_NP_162NW_34O 200260 1377600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_421 FreePDK45_38x28_10R_NP_162NW_34O 200260 1380400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_422 FreePDK45_38x28_10R_NP_162NW_34O 200260 1383200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_423 FreePDK45_38x28_10R_NP_162NW_34O 200260 1386000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_424 FreePDK45_38x28_10R_NP_162NW_34O 200260 1388800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_425 FreePDK45_38x28_10R_NP_162NW_34O 200260 1391600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_426 FreePDK45_38x28_10R_NP_162NW_34O 200260 1394400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_427 FreePDK45_38x28_10R_NP_162NW_34O 200260 1397200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_428 FreePDK45_38x28_10R_NP_162NW_34O 200260 1400000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_429 FreePDK45_38x28_10R_NP_162NW_34O 200260 1402800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_430 FreePDK45_38x28_10R_NP_162NW_34O 200260 1405600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_431 FreePDK45_38x28_10R_NP_162NW_34O 200260 1408400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_432 FreePDK45_38x28_10R_NP_162NW_34O 200260 1411200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_433 FreePDK45_38x28_10R_NP_162NW_34O 200260 1414000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_434 FreePDK45_38x28_10R_NP_162NW_34O 200260 1416800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_435 FreePDK45_38x28_10R_NP_162NW_34O 200260 1419600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_436 FreePDK45_38x28_10R_NP_162NW_34O 200260 1422400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_437 FreePDK45_38x28_10R_NP_162NW_34O 200260 1425200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_438 FreePDK45_38x28_10R_NP_162NW_34O 200260 1428000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_439 FreePDK45_38x28_10R_NP_162NW_34O 200260 1430800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_440 FreePDK45_38x28_10R_NP_162NW_34O 200260 1433600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_441 FreePDK45_38x28_10R_NP_162NW_34O 200260 1436400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_442 FreePDK45_38x28_10R_NP_162NW_34O 200260 1439200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_443 FreePDK45_38x28_10R_NP_162NW_34O 200260 1442000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_444 FreePDK45_38x28_10R_NP_162NW_34O 200260 1444800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_445 FreePDK45_38x28_10R_NP_162NW_34O 200260 1447600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_446 FreePDK45_38x28_10R_NP_162NW_34O 200260 1450400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_447 FreePDK45_38x28_10R_NP_162NW_34O 200260 1453200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_448 FreePDK45_38x28_10R_NP_162NW_34O 200260 1456000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_449 FreePDK45_38x28_10R_NP_162NW_34O 200260 1458800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_450 FreePDK45_38x28_10R_NP_162NW_34O 200260 1461600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_451 FreePDK45_38x28_10R_NP_162NW_34O 200260 1464400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_452 FreePDK45_38x28_10R_NP_162NW_34O 200260 1467200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_453 FreePDK45_38x28_10R_NP_162NW_34O 200260 1470000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_454 FreePDK45_38x28_10R_NP_162NW_34O 200260 1472800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_455 FreePDK45_38x28_10R_NP_162NW_34O 200260 1475600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_456 FreePDK45_38x28_10R_NP_162NW_34O 200260 1478400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_457 FreePDK45_38x28_10R_NP_162NW_34O 200260 1481200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_458 FreePDK45_38x28_10R_NP_162NW_34O 200260 1484000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_459 FreePDK45_38x28_10R_NP_162NW_34O 200260 1486800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_460 FreePDK45_38x28_10R_NP_162NW_34O 200260 1489600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_461 FreePDK45_38x28_10R_NP_162NW_34O 200260 1492400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_462 FreePDK45_38x28_10R_NP_162NW_34O 200260 1495200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_463 FreePDK45_38x28_10R_NP_162NW_34O 200260 1498000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_464 FreePDK45_38x28_10R_NP_162NW_34O 200260 1500800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_465 FreePDK45_38x28_10R_NP_162NW_34O 200260 1503600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_466 FreePDK45_38x28_10R_NP_162NW_34O 200260 1506400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_467 FreePDK45_38x28_10R_NP_162NW_34O 200260 1509200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_468 FreePDK45_38x28_10R_NP_162NW_34O 200260 1512000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_469 FreePDK45_38x28_10R_NP_162NW_34O 200260 1514800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_470 FreePDK45_38x28_10R_NP_162NW_34O 200260 1517600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_471 FreePDK45_38x28_10R_NP_162NW_34O 200260 1520400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_472 FreePDK45_38x28_10R_NP_162NW_34O 200260 1523200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_473 FreePDK45_38x28_10R_NP_162NW_34O 200260 1526000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_474 FreePDK45_38x28_10R_NP_162NW_34O 200260 1528800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_475 FreePDK45_38x28_10R_NP_162NW_34O 200260 1531600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_476 FreePDK45_38x28_10R_NP_162NW_34O 200260 1534400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_477 FreePDK45_38x28_10R_NP_162NW_34O 200260 1537200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_478 FreePDK45_38x28_10R_NP_162NW_34O 200260 1540000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_479 FreePDK45_38x28_10R_NP_162NW_34O 200260 1542800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_480 FreePDK45_38x28_10R_NP_162NW_34O 200260 1545600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_481 FreePDK45_38x28_10R_NP_162NW_34O 200260 1548400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_482 FreePDK45_38x28_10R_NP_162NW_34O 200260 1551200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_483 FreePDK45_38x28_10R_NP_162NW_34O 200260 1554000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_484 FreePDK45_38x28_10R_NP_162NW_34O 200260 1556800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_485 FreePDK45_38x28_10R_NP_162NW_34O 200260 1559600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_486 FreePDK45_38x28_10R_NP_162NW_34O 200260 1562400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_487 FreePDK45_38x28_10R_NP_162NW_34O 200260 1565200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_488 FreePDK45_38x28_10R_NP_162NW_34O 200260 1568000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_489 FreePDK45_38x28_10R_NP_162NW_34O 200260 1570800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_490 FreePDK45_38x28_10R_NP_162NW_34O 200260 1573600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_491 FreePDK45_38x28_10R_NP_162NW_34O 200260 1576400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_492 FreePDK45_38x28_10R_NP_162NW_34O 200260 1579200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_493 FreePDK45_38x28_10R_NP_162NW_34O 200260 1582000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_494 FreePDK45_38x28_10R_NP_162NW_34O 200260 1584800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_495 FreePDK45_38x28_10R_NP_162NW_34O 200260 1587600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_496 FreePDK45_38x28_10R_NP_162NW_34O 200260 1590400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_497 FreePDK45_38x28_10R_NP_162NW_34O 200260 1593200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_498 FreePDK45_38x28_10R_NP_162NW_34O 200260 1596000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_499 FreePDK45_38x28_10R_NP_162NW_34O 200260 1598800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_500 FreePDK45_38x28_10R_NP_162NW_34O 200260 1601600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_501 FreePDK45_38x28_10R_NP_162NW_34O 200260 1604400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_502 FreePDK45_38x28_10R_NP_162NW_34O 200260 1607200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_503 FreePDK45_38x28_10R_NP_162NW_34O 200260 1610000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_504 FreePDK45_38x28_10R_NP_162NW_34O 200260 1612800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_505 FreePDK45_38x28_10R_NP_162NW_34O 200260 1615600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_506 FreePDK45_38x28_10R_NP_162NW_34O 200260 1618400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_507 FreePDK45_38x28_10R_NP_162NW_34O 200260 1621200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_508 FreePDK45_38x28_10R_NP_162NW_34O 200260 1624000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_509 FreePDK45_38x28_10R_NP_162NW_34O 200260 1626800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_510 FreePDK45_38x28_10R_NP_162NW_34O 200260 1629600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_511 FreePDK45_38x28_10R_NP_162NW_34O 200260 1632400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_512 FreePDK45_38x28_10R_NP_162NW_34O 200260 1635200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_513 FreePDK45_38x28_10R_NP_162NW_34O 200260 1638000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_514 FreePDK45_38x28_10R_NP_162NW_34O 200260 1640800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_515 FreePDK45_38x28_10R_NP_162NW_34O 200260 1643600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_516 FreePDK45_38x28_10R_NP_162NW_34O 200260 1646400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_517 FreePDK45_38x28_10R_NP_162NW_34O 200260 1649200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_518 FreePDK45_38x28_10R_NP_162NW_34O 200260 1652000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_519 FreePDK45_38x28_10R_NP_162NW_34O 200260 1654800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_520 FreePDK45_38x28_10R_NP_162NW_34O 200260 1657600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_521 FreePDK45_38x28_10R_NP_162NW_34O 200260 1660400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_522 FreePDK45_38x28_10R_NP_162NW_34O 200260 1663200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_523 FreePDK45_38x28_10R_NP_162NW_34O 200260 1666000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_524 FreePDK45_38x28_10R_NP_162NW_34O 200260 1668800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_525 FreePDK45_38x28_10R_NP_162NW_34O 200260 1671600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_526 FreePDK45_38x28_10R_NP_162NW_34O 200260 1674400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_527 FreePDK45_38x28_10R_NP_162NW_34O 200260 1677200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_528 FreePDK45_38x28_10R_NP_162NW_34O 200260 1680000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_529 FreePDK45_38x28_10R_NP_162NW_34O 200260 1682800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_530 FreePDK45_38x28_10R_NP_162NW_34O 200260 1685600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_531 FreePDK45_38x28_10R_NP_162NW_34O 200260 1688400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_532 FreePDK45_38x28_10R_NP_162NW_34O 200260 1691200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_533 FreePDK45_38x28_10R_NP_162NW_34O 200260 1694000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_534 FreePDK45_38x28_10R_NP_162NW_34O 200260 1696800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_535 FreePDK45_38x28_10R_NP_162NW_34O 200260 1699600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_536 FreePDK45_38x28_10R_NP_162NW_34O 200260 1702400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_537 FreePDK45_38x28_10R_NP_162NW_34O 200260 1705200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_538 FreePDK45_38x28_10R_NP_162NW_34O 200260 1708000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_539 FreePDK45_38x28_10R_NP_162NW_34O 200260 1710800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_540 FreePDK45_38x28_10R_NP_162NW_34O 200260 1713600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_541 FreePDK45_38x28_10R_NP_162NW_34O 200260 1716400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_542 FreePDK45_38x28_10R_NP_162NW_34O 200260 1719200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_543 FreePDK45_38x28_10R_NP_162NW_34O 200260 1722000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_544 FreePDK45_38x28_10R_NP_162NW_34O 200260 1724800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_545 FreePDK45_38x28_10R_NP_162NW_34O 200260 1727600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_546 FreePDK45_38x28_10R_NP_162NW_34O 200260 1730400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_547 FreePDK45_38x28_10R_NP_162NW_34O 200260 1733200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_548 FreePDK45_38x28_10R_NP_162NW_34O 200260 1736000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_549 FreePDK45_38x28_10R_NP_162NW_34O 200260 1738800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_550 FreePDK45_38x28_10R_NP_162NW_34O 200260 1741600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_551 FreePDK45_38x28_10R_NP_162NW_34O 200260 1744400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_552 FreePDK45_38x28_10R_NP_162NW_34O 200260 1747200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_553 FreePDK45_38x28_10R_NP_162NW_34O 200260 1750000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_554 FreePDK45_38x28_10R_NP_162NW_34O 200260 1752800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_555 FreePDK45_38x28_10R_NP_162NW_34O 200260 1755600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_556 FreePDK45_38x28_10R_NP_162NW_34O 200260 1758400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_557 FreePDK45_38x28_10R_NP_162NW_34O 200260 1761200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_558 FreePDK45_38x28_10R_NP_162NW_34O 200260 1764000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_559 FreePDK45_38x28_10R_NP_162NW_34O 200260 1766800 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_560 FreePDK45_38x28_10R_NP_162NW_34O 200260 1769600 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_561 FreePDK45_38x28_10R_NP_162NW_34O 200260 1772400 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_562 FreePDK45_38x28_10R_NP_162NW_34O 200260 1775200 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_563 FreePDK45_38x28_10R_NP_162NW_34O 200260 1778000 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_564 FreePDK45_38x28_10R_NP_162NW_34O 200260 1780800 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_565 FreePDK45_38x28_10R_NP_162NW_34O 200260 1783600 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_566 FreePDK45_38x28_10R_NP_162NW_34O 200260 1786400 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_567 FreePDK45_38x28_10R_NP_162NW_34O 200260 1789200 N DO 4209 BY 1 STEP 380 0 ; +ROW ROW_568 FreePDK45_38x28_10R_NP_162NW_34O 200260 1792000 FS DO 4209 BY 1 STEP 380 0 ; +ROW ROW_569 FreePDK45_38x28_10R_NP_162NW_34O 200260 1794800 N DO 4209 BY 1 STEP 380 0 ; +COMPONENTS 5 ; + - r1 DFF_X1 ; + - r2 DFF_X1 ; + - r3 DFF_X1 ; + - u1 BUF_X1 ; + - u2 AND2_X1 ; +END COMPONENTS +PINS 6 ; + - clk1 + NET clk1 + DIRECTION INPUT + USE SIGNAL ; + - clk2 + NET clk2 + DIRECTION INPUT + USE SIGNAL ; + - clk3 + NET clk3 + DIRECTION INPUT + USE SIGNAL ; + - in1 + NET in1 + DIRECTION INPUT + USE SIGNAL ; + - in2 + NET in2 + DIRECTION INPUT + USE SIGNAL ; + - out + NET out + DIRECTION OUTPUT + USE SIGNAL ; +END PINS +NETS 10 ; + - clk1 ( PIN clk1 ) ( r1 CK ) + USE SIGNAL ; + - clk2 ( PIN clk2 ) ( r2 CK ) + USE SIGNAL ; + - clk3 ( PIN clk3 ) ( r3 CK ) + USE SIGNAL ; + - in1 ( PIN in1 ) ( r1 D ) + USE SIGNAL ; + - in2 ( PIN in2 ) ( r2 D ) + USE SIGNAL ; + - out ( PIN out ) ( r3 Q ) + USE SIGNAL ; + - r1q ( u2 A1 ) ( r1 Q ) + USE SIGNAL ; + - r2q ( u1 A ) ( r2 Q ) + USE SIGNAL ; + - u1z ( u2 A2 ) ( u1 Z ) + USE SIGNAL ; + - u2z ( u2 ZN ) ( r3 D ) + USE SIGNAL ; +END NETS +END DESIGN diff --git a/src/ifp/test/init_floorplan_flip_sites.ok b/src/ifp/test/init_floorplan_flip_sites.ok new file mode 100644 index 00000000000..9382402e957 --- /dev/null +++ b/src/ifp/test/init_floorplan_flip_sites.ok @@ -0,0 +1,4 @@ +[INFO ODB-0227] LEF file: Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells +[WARNING IFP-0028] Core area lower left (100.000, 100.000) snapped to (100.130, 100.800). +[INFO IFP-0001] Added 570 rows of 4209 site FreePDK45_38x28_10R_NP_162NW_34O. +No differences found. diff --git a/src/ifp/test/init_floorplan_flip_sites.py b/src/ifp/test/init_floorplan_flip_sites.py new file mode 100644 index 00000000000..c278ff05825 --- /dev/null +++ b/src/ifp/test/init_floorplan_flip_sites.py @@ -0,0 +1,25 @@ +from openroad import Tech, Design +import helpers + +tech = Tech() +tech.readLef("Nangate45/Nangate45.lef") +tech.readLiberty("Nangate45/Nangate45_typ.lib") + +design = Design(tech) +design.readVerilog("reg1.v") +design.link("top") + +floorplan = design.getFloorplan() +site = floorplan.findSite("FreePDK45_38x28_10R_NP_162NW_34O") +floorplan.initFloorplan( + helpers.make_rect(design, 0, 0, 1000, 1000), + helpers.make_rect(design, 100, 100, 900, 900), + site, + [], + "NONE", + [site], +) + +def_file = helpers.make_result_file("init_floorplan_flip_sites.def") +design.writeDef(def_file) +helpers.diff_files("init_floorplan_flip_sites.defok", def_file) diff --git a/src/ifp/test/init_floorplan_flip_sites.tcl b/src/ifp/test/init_floorplan_flip_sites.tcl new file mode 100644 index 00000000000..df68f9536ff --- /dev/null +++ b/src/ifp/test/init_floorplan_flip_sites.tcl @@ -0,0 +1,14 @@ +# init_floorplan +source "helpers.tcl" +read_lef Nangate45/Nangate45.lef +read_liberty Nangate45/Nangate45_typ.lib +read_verilog reg1.v +link_design top +initialize_floorplan -die_area "0 0 1000 1000" \ + -core_area "100 100 900 900" \ + -site FreePDK45_38x28_10R_NP_162NW_34O\ + -flip_sites "FreePDK45_38x28_10R_NP_162NW_34O" + +set def_file [make_result_file init_floorplan_flip_sites.def] +write_def $def_file +diff_files init_floorplan_flip_sites.defok $def_file diff --git a/src/ifp/test/regression_tests.tcl b/src/ifp/test/regression_tests.tcl index b06f1f8fcc6..65912ce12e8 100644 --- a/src/ifp/test/regression_tests.tcl +++ b/src/ifp/test/regression_tests.tcl @@ -1,6 +1,6 @@ record_tests { hybrid_rows - hybrid_rows2 + hybrid_rows2 init_floorplan1 init_floorplan2 init_floorplan3 @@ -26,6 +26,7 @@ record_tests { upf_shifter_test init_floorplan_even_rows init_floorplan_odd_rows + init_floorplan_flip_sites #ifp_man_tcl_check #ifp_readme_msgs_check } diff --git a/src/mpl2/src/Mpl2Observer.h b/src/mpl2/src/Mpl2Observer.h index f089b8992cf..5f8f481f5e0 100644 --- a/src/mpl2/src/Mpl2Observer.h +++ b/src/mpl2/src/Mpl2Observer.h @@ -65,7 +65,7 @@ class Mpl2Observer virtual void startSA() {} virtual void saStep(const std::vector& macros) {} virtual void saStep(const std::vector& macros) {} - virtual void endSA() {} + virtual void endSA(float norm_cost) {} virtual void drawResult() {} virtual void finishedClustering(Cluster* root) {} diff --git a/src/mpl2/src/SimulatedAnnealingCore.cpp b/src/mpl2/src/SimulatedAnnealingCore.cpp index 8c522461cde..1dd10b0dcaa 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.cpp +++ b/src/mpl2/src/SimulatedAnnealingCore.cpp @@ -564,7 +564,6 @@ void SimulatedAnnealingCore::fastSA() graphics_->startSA(); } - // record the previous status float cost = calNormCost(); float pre_cost = cost; float delta_cost = 0.0; @@ -573,16 +572,31 @@ void SimulatedAnnealingCore::fastSA() const float min_t = 1e-10; const float t_factor = std::exp(std::log(min_t / init_temperature_) / max_num_step_); - notch_weight_ = 0.0; // notch pealty is too expensive, we try to avoid - // calculating notch penalty at very beginning - // const for restart + + // Used to ensure notch penalty is used only in the latter steps + // as it is too expensive + notch_weight_ = 0.0; + int num_restart = 1; const int max_num_restart = 2; - // SA process + + SequencePair best_valid_result; + if (isValid()) { + updateBestValidResult(best_valid_result); + } + while (step <= max_num_step_) { for (int i = 0; i < num_perturb_per_step_; i++) { perturb(); cost = calNormCost(); + + const bool keep_result + = cost < pre_cost || best_valid_result.pos_sequence.empty(); + + if (isValid() && keep_result) { + updateBestValidResult(best_valid_result); + } + delta_cost = cost - pre_cost; const float num = distribution_(generator_); const float prob @@ -593,13 +607,13 @@ void SimulatedAnnealingCore::fastSA() restore(); } } - // temperature *= 0.985; + temperature *= t_factor; + step++; + cost_list_.push_back(pre_cost); T_list_.push_back(temperature); - // increase step - step++; - // check if restart condition + if ((num_restart <= max_num_restart) && (step == std::floor(max_num_step_ / max_num_restart) && (outline_penalty_ > 0.0))) { @@ -611,16 +625,15 @@ void SimulatedAnnealingCore::fastSA() step = 1; num_perturb_per_step_ *= 2; temperature = init_temperature_; - } // end if - // only consider the last step to optimize notch weight + } + if (step == max_num_step_ - macros_.size() * 2) { notch_weight_ = original_notch_weight_; packFloorplan(); calPenalty(); pre_cost = calNormCost(); } - } // end while - // update the final results + } packFloorplan(); if (graphics_) { @@ -628,12 +641,23 @@ void SimulatedAnnealingCore::fastSA() } calPenalty(); + if (!isValid() && !best_valid_result.pos_sequence.empty()) { + pos_seq_ = best_valid_result.pos_sequence; + neg_seq_ = best_valid_result.neg_sequence; + + packFloorplan(); + if (graphics_) { + graphics_->doNotSkip(); + } + calPenalty(); + } + if (centralization_on_) { attemptCentralization(calNormCost()); } if (graphics_) { - graphics_->endSA(); + graphics_->endSA(calNormCost()); } } @@ -690,6 +714,14 @@ void SimulatedAnnealingCore::moveFloorplan( calPenalty(); } +template +void SimulatedAnnealingCore::updateBestValidResult( + SequencePair& best_valid_result) +{ + best_valid_result.pos_sequence = pos_seq_; + best_valid_result.neg_sequence = neg_seq_; +} + template void SimulatedAnnealingCore::writeCostFile( const std::string& file_name) const diff --git a/src/mpl2/src/SimulatedAnnealingCore.h b/src/mpl2/src/SimulatedAnnealingCore.h index 6862a066923..52e2eb910dd 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.h +++ b/src/mpl2/src/SimulatedAnnealingCore.h @@ -134,6 +134,7 @@ class SimulatedAnnealingCore void initSequencePair(); void attemptCentralization(float pre_cost); void moveFloorplan(const std::pair& offset); + void updateBestValidResult(SequencePair& best_valid_result); virtual float calNormCost() const = 0; virtual void calPenalty() = 0; diff --git a/src/mpl2/src/graphics.cpp b/src/mpl2/src/graphics.cpp index ef72796632a..768179e8ffa 100644 --- a/src/mpl2/src/graphics.cpp +++ b/src/mpl2/src/graphics.cpp @@ -80,7 +80,7 @@ void Graphics::startSA() skipped_ = 0; } -void Graphics::endSA() +void Graphics::endSA(const float norm_cost) { if (!active_) { return; @@ -94,6 +94,7 @@ void Graphics::endSA() logger_->report("Skipped to end: {}", skipped_); } logger_->report("------ End ------"); + report(norm_cost); gui::Gui::get()->pause(); } @@ -133,6 +134,19 @@ void Graphics::report(const char* name, const std::optional& value) } } +void Graphics::report(const float norm_cost) +{ + report("Area", area_penalty_); + report("Outline Penalty", outline_penalty_); + report("Wirelength", wirelength_penalty_); + report("Fence Penalty", fence_penalty_); + report("Guidance Penalty", guidance_penalty_); + report("Boundary Penalty", boundary_penalty_); + report("Macro Blockage Penalty", macro_blockage_penalty_); + report("Notch Penalty", notch_penalty_); + report("Normalized Cost", std::optional({1.0f, norm_cost})); +} + void Graphics::drawResult() { if (!only_final_result_) { @@ -206,16 +220,8 @@ void Graphics::penaltyCalculated(float norm_cost) if (norm_cost < best_norm_cost_ || drawing_last_step) { logger_->report("------ Penalty ------"); + report(norm_cost); - report("Area", area_penalty_); - report("Outline Penalty", outline_penalty_); - report("Wirelength", wirelength_penalty_); - report("Fence Penalty", fence_penalty_); - report("Guidance Penalty", guidance_penalty_); - report("Boundary Penalty", boundary_penalty_); - report("Macro Blockage Penalty", macro_blockage_penalty_); - report("Notch Penalty", notch_penalty_); - report("Normalized Cost", std::optional({1.0f, norm_cost})); if (skipped_ > 0) { logger_->report("Skipped: {}", skipped_); skipped_ = 0; diff --git a/src/mpl2/src/graphics.h b/src/mpl2/src/graphics.h index e6afd78de08..789eff1efac 100644 --- a/src/mpl2/src/graphics.h +++ b/src/mpl2/src/graphics.h @@ -58,7 +58,7 @@ class Graphics : public gui::Renderer, public Mpl2Observer void startSA() override; void saStep(const std::vector& macros) override; void saStep(const std::vector& macros) override; - void endSA() override; + void endSA(float norm_cost) override; void drawResult() override; void finishedClustering(Cluster* root) override; @@ -105,6 +105,7 @@ class Graphics : public gui::Renderer, public Mpl2Observer template void report(const char* name, const std::optional& value); + void report(float norm_cost); std::vector soft_macros_; std::vector hard_macros_; diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 6c8d69e0521..eae31890220 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -1855,11 +1855,6 @@ void HierRTLMP::runHierarchicalMacroPlacement(Cluster* parent) best_cost = std::numeric_limits::max(); begin_check = 0; end_check = std::min(check_interval, remaining_runs); - - int outline_weight, boundary_weight; - setWeightsForConvergence( - outline_weight, boundary_weight, nets, num_of_macros_to_place); - debugPrint(logger_, MPL, "hierarchical_macro_placement", @@ -1924,11 +1919,11 @@ void HierRTLMP::runHierarchicalMacroPlacement(Cluster* parent) outline, shaped_macros, area_weight_, - outline_weight, + outline_weight_, wirelength_weight_, guidance_weight_, fence_weight_, - boundary_weight, + boundary_weight_, macro_blockage_weight_, notch_weight_, notch_h_th_, @@ -2132,36 +2127,6 @@ void HierRTLMP::adjustMacroBlockageWeight() } } -void HierRTLMP::setWeightsForConvergence(int& outline_weight, - int& boundary_weight, - const std::vector& nets, - const int number_of_placeable_macros) -{ - outline_weight = outline_weight_; - boundary_weight = boundary_weight_; - - if (nets.size() < number_of_placeable_macros / 2) { - // If a design has too few connections, there's a possibily that, for - // some tight outlines, the outline penalty will struggle to win the - // fight against the boundary penalty. This can happen specially for - // large hierarchical designs that were reduced by deltaDebug. - outline_weight *= 2; - boundary_weight /= 2; - - debugPrint(logger_, - MPL, - "hierarchical_macro_placement", - 1, - "Number of bundled nets is below half of the number of " - "placeable macros, adapting " - "weights. Outline {} -> {}, Boundary {} -> {}.", - outline_weight_, - outline_weight, - boundary_weight_, - boundary_weight); - } -} - void HierRTLMP::reportSAWeights() { logger_->report("\nSimmulated Annealing Weights:\n"); @@ -2463,11 +2428,6 @@ void HierRTLMP::runHierarchicalMacroPlacementWithoutBusPlanning(Cluster* parent) int begin_check = 0; int end_check = std::min(check_interval, remaining_runs); float best_cost = std::numeric_limits::max(); - - int outline_weight, boundary_weight; - setWeightsForConvergence( - outline_weight, boundary_weight, nets, num_of_macros_to_place); - debugPrint(logger_, MPL, "hierarchical_macro_placement", @@ -2531,11 +2491,11 @@ void HierRTLMP::runHierarchicalMacroPlacementWithoutBusPlanning(Cluster* parent) outline, shaped_macros, area_weight_, - outline_weight, + outline_weight_, wirelength_weight_, guidance_weight_, fence_weight_, - boundary_weight, + boundary_weight_, macro_blockage_weight_, notch_weight_, notch_h_th_, @@ -2953,11 +2913,6 @@ void HierRTLMP::runEnhancedHierarchicalMacroPlacement(Cluster* parent) const int check_interval = 10; int begin_check = 0; int end_check = std::min(check_interval, remaining_runs); - - int outline_weight, boundary_weight; - setWeightsForConvergence( - outline_weight, boundary_weight, nets, macros_to_place); - debugPrint(logger_, MPL, "hierarchical_macro_placement", @@ -3018,11 +2973,11 @@ void HierRTLMP::runEnhancedHierarchicalMacroPlacement(Cluster* parent) outline, shaped_macros, area_weight_, - outline_weight, + outline_weight_, wirelength_weight_, guidance_weight_, fence_weight_, - boundary_weight, + boundary_weight_, macro_blockage_weight_, notch_weight_, notch_h_th_, diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index bcbdd205233..2635afc01c5 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -192,10 +192,6 @@ class HierRTLMP // Hierarchical Macro Placement 1st stage: Cluster Placement void runHierarchicalMacroPlacement(Cluster* parent); void adjustMacroBlockageWeight(); - void setWeightsForConvergence(int& outline_weight, - int& boundary_weight, - const std::vector& nets, - int number_of_placeable_macros); void reportSAWeights(); void runHierarchicalMacroPlacementWithoutBusPlanning(Cluster* parent); void runEnhancedHierarchicalMacroPlacement(Cluster* parent); diff --git a/src/pdn/src/straps.cpp b/src/pdn/src/straps.cpp index 4a92696cbbb..76187b7079c 100644 --- a/src/pdn/src/straps.cpp +++ b/src/pdn/src/straps.cpp @@ -1557,7 +1557,37 @@ RepairChannelStraps::RepairChannelStraps( setStrapStartEnd(area_.yMin(), area_.yMax()); } - determineParameters(other_shapes); + odb::dbTechLayerDir connect_direction = connect_to->getDirection(); + // find the connecting strap and use it's direction + for (const auto& comp : grid->getStraps()) { + if (comp->getLayer() == connect_to) { + connect_direction = comp->getDirection(); + } + } + + if (connect_direction == odb::dbTechLayerDir::NONE) { + // Assume this layer is horizontal if not set + connect_direction = odb::dbTechLayerDir::HORIZONTAL; + } + + if (connect_direction == getDirection()) { + debugPrint( + getLogger(), + utl::PDN, + "Channel", + 1, + "Reject repair channel due to layer directions {} ({} / {}) -> {} ({})", + connect_to->getName(), + connect_to->getDirection().getString(), + connect_direction.getString(), + getLayer()->getName(), + getDirection().getString()); + invalid_ = true; + } + + if (!invalid_) { + determineParameters(other_shapes); + } if (invalid_) { const TechLayer layer(getLayer()); diff --git a/src/pdn/test/CMakeLists.txt b/src/pdn/test/CMakeLists.txt index ed1888852d0..9b48e788952 100644 --- a/src/pdn/test/CMakeLists.txt +++ b/src/pdn/test/CMakeLists.txt @@ -62,6 +62,7 @@ set(TEST_NAMES macros_cells_overlapping_ports macros_cells_not_fixed macros_cells_via_failure + repair_channel_inf_loop region_temp_sensor region_secondary_nets region_non_rect diff --git a/src/pdn/test/regression_tests.tcl b/src/pdn/test/regression_tests.tcl index 5cb7cd6b691..9b911e8f900 100644 --- a/src/pdn/test/regression_tests.tcl +++ b/src/pdn/test/regression_tests.tcl @@ -72,6 +72,7 @@ record_tests { macros_cells_overlapping_ports macros_cells_not_fixed macros_cells_via_failure + repair_channel_inf_loop region_temp_sensor region_secondary_nets diff --git a/src/pdn/test/repair_channel_inf_loop.ok b/src/pdn/test/repair_channel_inf_loop.ok new file mode 100644 index 00000000000..ba0d580bf64 --- /dev/null +++ b/src/pdn/test/repair_channel_inf_loop.ok @@ -0,0 +1,13 @@ +[INFO ODB-0227] LEF file: repair_channel_inf_loop/tech_macro.lef, created 7 layers, 3 vias, 1 library cells +[INFO ODB-0127] Reading DEF file: repair_channel_inf_loop/floorplan.def +[INFO ODB-0128] Design: test +[INFO ODB-0130] Created 5 pins. +[INFO ODB-0131] Created 1 components and 3 component-terminals. +[INFO ODB-0132] Created 2 special nets and 2 connections. +[INFO ODB-0133] Created 4 nets and 0 connections. +[INFO ODB-0134] Finished DEF file: repair_channel_inf_loop/floorplan.def +[INFO PDN-0001] Inserting grid: Core +[WARNING PDN-0178] Remaining channel (0.0000, -1.3150) - (2621.0800, 112.3150) on M1 for nets: GND, VDD +[WARNING PDN-0178] Remaining channel (0.0000, 112.3150) - (1812.5800, 1028.0650) on M1 for nets: GND, VDD +[ERROR PDN-0179] Unable to repair all channels. +PDN-0179 diff --git a/src/pdn/test/repair_channel_inf_loop.tcl b/src/pdn/test/repair_channel_inf_loop.tcl new file mode 100644 index 00000000000..636918f0661 --- /dev/null +++ b/src/pdn/test/repair_channel_inf_loop.tcl @@ -0,0 +1,20 @@ +# Check for repair channels with straps in same direction and reject +# this avoids the infinate loop reported in: https://github.com/The-OpenROAD-Project/OpenROAD/issues/5905 + +read_lef repair_channel_inf_loop/tech_macro.lef +read_def repair_channel_inf_loop/floorplan.def + +set_voltage_domain -power VDD -ground GND + +define_pdn_grid -name "Core" + +add_pdn_stripe -followpins -layer M1 -width 2.630 + +add_pdn_stripe -layer M3 -width 11.280 -pitch 225.600 -spacing 16.920 -offset 113.550 +add_pdn_stripe -layer M4 -width 11.280 -pitch 526.400 -spacing 16.920 -offset 375.625 + +add_pdn_connect -layers {M3 M4} +add_pdn_connect -layers {M1 M3} + +catch {pdngen} err +puts $err diff --git a/src/pdn/test/repair_channel_inf_loop/floorplan.def b/src/pdn/test/repair_channel_inf_loop/floorplan.def new file mode 100644 index 00000000000..e6f75944f06 --- /dev/null +++ b/src/pdn/test/repair_channel_inf_loop/floorplan.def @@ -0,0 +1,146 @@ +VERSION 5.8 ; +DIVIDERCHAR "/" ; +BUSBITCHARS "[]" ; +DESIGN test ; +UNITS DISTANCE MICRONS 1000 ; +DIEAREA ( 0 0 ) ( 2621190 1028475 ) ; +ROW ROW_0 CORE 0 0 N DO 3404 BY 1 STEP 770 0 ; +ROW ROW_1 CORE 0 9250 FS DO 3404 BY 1 STEP 770 0 ; +ROW ROW_2 CORE 0 18500 N DO 3404 BY 1 STEP 770 0 ; +ROW ROW_3 CORE 0 27750 FS DO 3404 BY 1 STEP 770 0 ; +ROW ROW_4 CORE 0 37000 N DO 3404 BY 1 STEP 770 0 ; +ROW ROW_5 CORE 0 46250 FS DO 3404 BY 1 STEP 770 0 ; +ROW ROW_6 CORE 0 55500 N DO 3404 BY 1 STEP 770 0 ; +ROW ROW_7 CORE 0 64750 FS DO 3404 BY 1 STEP 770 0 ; +ROW ROW_8 CORE 0 74000 N DO 3404 BY 1 STEP 770 0 ; +ROW ROW_9 CORE 0 83250 FS DO 3404 BY 1 STEP 770 0 ; +ROW ROW_11_1 CORE 0 101750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_12_1 CORE 0 111000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_13_1 CORE 0 120250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_14_1 CORE 0 129500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_15_1 CORE 0 138750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_16_1 CORE 0 148000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_17_1 CORE 0 157250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_18_1 CORE 0 166500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_19_1 CORE 0 175750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_20_1 CORE 0 185000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_21_1 CORE 0 194250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_22_1 CORE 0 203500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_23_1 CORE 0 212750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_24_1 CORE 0 222000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_25_1 CORE 0 231250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_26_1 CORE 0 240500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_27_1 CORE 0 249750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_28_1 CORE 0 259000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_29_1 CORE 0 268250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_30_1 CORE 0 277500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_31_1 CORE 0 286750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_32_1 CORE 0 296000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_33_1 CORE 0 305250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_34_1 CORE 0 314500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_35_1 CORE 0 323750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_36_1 CORE 0 333000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_37_1 CORE 0 342250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_38_1 CORE 0 351500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_39_1 CORE 0 360750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_40_1 CORE 0 370000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_41_1 CORE 0 379250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_42_1 CORE 0 388500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_43_1 CORE 0 397750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_44_1 CORE 0 407000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_45_1 CORE 0 416250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_46_1 CORE 0 425500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_47_1 CORE 0 434750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_48_1 CORE 0 444000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_49_1 CORE 0 453250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_50_1 CORE 0 462500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_51_1 CORE 0 471750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_52_1 CORE 0 481000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_53_1 CORE 0 490250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_54_1 CORE 0 499500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_55_1 CORE 0 508750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_56_1 CORE 0 518000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_57_1 CORE 0 527250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_58_1 CORE 0 536500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_59_1 CORE 0 545750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_60_1 CORE 0 555000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_61_1 CORE 0 564250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_62_1 CORE 0 573500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_63_1 CORE 0 582750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_64_1 CORE 0 592000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_65_1 CORE 0 601250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_66_1 CORE 0 610500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_67_1 CORE 0 619750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_68_1 CORE 0 629000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_69_1 CORE 0 638250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_70_1 CORE 0 647500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_71_1 CORE 0 656750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_72_1 CORE 0 666000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_73_1 CORE 0 675250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_74_1 CORE 0 684500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_75_1 CORE 0 693750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_76_1 CORE 0 703000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_77_1 CORE 0 712250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_78_1 CORE 0 721500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_79_1 CORE 0 730750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_80_1 CORE 0 740000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_81_1 CORE 0 749250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_82_1 CORE 0 758500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_83_1 CORE 0 767750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_84_1 CORE 0 777000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_85_1 CORE 0 786250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_86_1 CORE 0 795500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_87_1 CORE 0 804750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_88_1 CORE 0 814000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_89_1 CORE 0 823250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_90_1 CORE 0 832500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_91_1 CORE 0 841750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_92_1 CORE 0 851000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_93_1 CORE 0 860250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_94_1 CORE 0 869500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_95_1 CORE 0 878750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_96_1 CORE 0 888000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_97_1 CORE 0 897250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_98_1 CORE 0 906500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_99_1 CORE 0 915750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_100_1 CORE 0 925000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_101_1 CORE 0 934250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_102_1 CORE 0 943500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_103_1 CORE 0 952750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_104_1 CORE 0 962000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_105_1 CORE 0 971250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_106_1 CORE 0 980500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_107_1 CORE 0 989750 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_108_1 CORE 0 999000 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_109_1 CORE 0 1008250 FS DO 2354 BY 1 STEP 770 0 ; +ROW ROW_110_1 CORE 0 1017500 N DO 2354 BY 1 STEP 770 0 ; +ROW ROW_10_1 CORE 0 92500 N DO 2354 BY 1 STEP 770 0 ; +TRACKS X 385 DO 3404 STEP 770 LAYER M1 ; +TRACKS Y 770 DO 1335 STEP 770 LAYER M1 ; +TRACKS X 385 DO 3404 STEP 770 LAYER M2 ; +TRACKS Y 770 DO 1335 STEP 770 LAYER M2 ; +TRACKS X 385 DO 3404 STEP 770 LAYER M3 ; +TRACKS Y 770 DO 1335 STEP 770 LAYER M3 ; +TRACKS X 4240 DO 679 STEP 3855 LAYER M4 ; +TRACKS Y 3855 DO 266 STEP 3855 LAYER M4 ; +COMPONENTS 1 ; + - instance CELL + FIXED ( 1822035 104845 ) N ; +END COMPONENTS +PINS 5 ; + - cd + NET cd + DIRECTION INPUT + USE SIGNAL ; + - cp + NET cp + DIRECTION INPUT + USE SIGNAL ; + - d + NET d + DIRECTION INPUT + USE SIGNAL ; + - q1 + NET q + DIRECTION OUTPUT + USE SIGNAL ; + - q2 + NET q + DIRECTION OUTPUT + USE SIGNAL ; +END PINS +SPECIALNETS 2 ; + - GND ( instance GND_0 ) + USE GROUND ; + - VDD ( instance VDD_0 ) + USE POWER ; +END SPECIALNETS +NETS 4 ; + - cd ( PIN cd ) + USE SIGNAL ; + - cp ( PIN cp ) + USE SIGNAL ; + - d ( PIN d ) + USE SIGNAL ; + - q ( PIN q2 ) ( PIN q1 ) + USE SIGNAL ; +END NETS +END DESIGN diff --git a/src/pdn/test/repair_channel_inf_loop/tech_macro.lef b/src/pdn/test/repair_channel_inf_loop/tech_macro.lef new file mode 100644 index 00000000000..acd6339d17f --- /dev/null +++ b/src/pdn/test/repair_channel_inf_loop/tech_macro.lef @@ -0,0 +1,212 @@ +VERSION 5.7 ; +BUSBITCHARS "[]" ; +DIVIDERCHAR "/" ; + +PROPERTYDEFINITIONS + LAYER LEF58_TYPE STRING ; + LAYER LEF58_ENCLOSURE STRING ; + LAYER LEF58_VOLTAGESPACING STRING ; + LAYER LEF58_SPACING STRING ; + LAYER LEF58_WIDTH STRING ; + LAYER LEF58_ARRAYSPACING STRING ; +END PROPERTYDEFINITIONS + +UNITS + DATABASE MICRONS 1000 ; +END UNITS +MANUFACTURINGGRID 0.005 ; +USEMINSPACING OBS OFF ; + +LAYER M1 + TYPE ROUTING ; + DIRECTION HORIZONTAL ; + PITCH 0.770 0.770 ; + WIDTH 0.395 ; + OFFSET 0.385 0.000 ; + AREA 0.230 ; + SPACING 0.340 ; + SPACING 0.340 LENGTHTHRESHOLD 1.880 RANGE 0.565 18.800 ; + SPACING 0.415 RANGE 0.565 18.800 USELENGTHTHRESHOLD ; + SPACING 1.130 RANGE 18.800 18800.000 ; + SPACING 0.340 RANGE 0.000 18.800 INFLUENCE 0.340 ; + SPACING 1.130 RANGE 18.800 18800.000 INFLUENCE 0.340 ; + MINIMUMCUT 2 WIDTH 0.300 FROMABOVE ; + MINWIDTH 0.300 ; + MINENCLOSEDAREA 0.375 ; +END M1 + +LAYER V1 + TYPE CUT ; + SPACING 0.415 ; + WIDTH 0.355 ; + ENCLOSURE BELOW 0.095 0.020 ; + ENCLOSURE ABOVE 0.095 0.010 ; +END V1 + +LAYER M2 + TYPE ROUTING ; + DIRECTION VERTICAL ; + PITCH 0.770 0.770 ; + WIDTH 0.375 ; + OFFSET 0.385 0.000 ; + AREA 0.270 ; + SPACING 0.395 ; + SPACING 0.395 LENGTHTHRESHOLD 1.880 RANGE 0.735 18.800 ; + SPACING 0.450 RANGE 0.735 18.800 USELENGTHTHRESHOLD ; + SPACING 1.130 RANGE 18.800 18800.000 ; + SPACING 0.395 RANGE 0.000 18.800 INFLUENCE 0.395 ; + SPACING 1.130 RANGE 18.800 18800.000 INFLUENCE 0.395 ; + MINIMUMCUT 2 WIDTH 0.300 FROMBELOW ; + MINIMUMCUT 2 WIDTH 0.375 FROMABOVE ; + MINENCLOSEDAREA 0.500 ; +END M2 + +LAYER V2 + TYPE CUT ; + SPACING 0.415 ; + WIDTH 0.355 ; + ENCLOSURE BELOW 0.095 0.010 ; + ENCLOSURE ABOVE 0.095 0.010 ; +END V2 + +LAYER M3 + TYPE ROUTING ; + DIRECTION HORIZONTAL ; + PITCH 0.770 0.770 ; + WIDTH 0.375 ; + OFFSET 0.385 0.000 ; + AREA 0.270 ; + SPACING 0.395 ; + SPACING 0.395 LENGTHTHRESHOLD 1.880 RANGE 0.735 18.800 ; + SPACING 0.450 RANGE 0.735 18.800 USELENGTHTHRESHOLD ; + SPACING 1.130 RANGE 18.800 18800.000 ; + SPACING 0.395 RANGE 0.000 18.800 INFLUENCE 0.395 ; + SPACING 1.130 RANGE 18.800 18800.000 INFLUENCE 0.395 ; + MINIMUMCUT 2 WIDTH 0.375 FROMBELOW ; + MINIMUMCUT 2 WIDTH 0.375 FROMABOVE ; + MINIMUMCUT 3 WIDTH 3.950 FROMABOVE ; + MINENCLOSEDAREA 0.500 ; +END M3 + +LAYER V3 + TYPE CUT ; + SPACING 0.525 ; + WIDTH 0.525 ; + ENCLOSURE BELOW 0.245 0.190 ; + ENCLOSURE ABOVE 1.270 1.270 WIDTH 3.760 ; + ENCLOSURE ABOVE 2.115 2.115 WIDTH 7.520 ; + ENCLOSURE ABOVE 3.150 3.150 WIDTH 13.160 ; + ENCLOSURE ABOVE 4.090 4.090 WIDTH 52.640 ; + ENCLOSURE ABOVE 0.675 1.130 ; +END V3 + +LAYER M4 + TYPE ROUTING ; + DIRECTION VERTICAL ; + PITCH 3.855 3.855 ; + WIDTH 1.880 ; + OFFSET 0.385 0.000 ; + AREA 5.395 ; + SPACING 1.880 ; + SPACING 3.760 RANGE 13.160 26.320 ; + SPACING 7.520 RANGE 26.320 52.640 ; + SPACING 15.040 RANGE 52.640 105.280 ; + SPACING 20.680 RANGE 105.280 161.680 ; + SPACING 26.320 RANGE 161.680 18800.000 ; + MINIMUMCUT 2 WIDTH 0.375 FROMBELOW ; + MINIMUMCUT 3 WIDTH 3.950 FROMBELOW ; + MINSTEP 0.470 MAXEDGES 0.000 ; +END M4 + +VIA M2_M1_VH_via DEFAULT + LAYER M2 ; + RECT -0.190 -0.275 0.190 0.275 ; + LAYER M1 ; + RECT -0.275 -0.195 0.275 0.195 ; + LAYER V1 ; + RECT -0.180 -0.180 0.180 0.180 ; + RESISTANCE 2.630 ; +END M2_M1_VH_via + +VIA M3_M2_HV_via DEFAULT + LAYER M3 ; + RECT -0.275 -0.190 0.275 0.190 ; + LAYER M2 ; + RECT -0.190 -0.275 0.190 0.275 ; + LAYER V2 ; + RECT -0.180 -0.180 0.180 0.180 ; + RESISTANCE 2.630 ; +END M3_M2_HV_via + +VIA M4_M3_CUT1 + LAYER V3 ; + RECT -0.790 -0.265 -0.265 0.265 ; + LAYER M4 ; + RECT -1.920 -0.940 1.920 0.940 ; + LAYER M3 ; + RECT -1.035 -0.450 1.035 0.450 ; + RESISTANCE 1.130 ; +END M4_M3_CUT1 + +SITE CORE + CLASS CORE ; + SYMMETRY Y ; + SIZE 0.770 BY 9.250 ; +END CORE + +MACRO CELL + CLASS BLOCK ; + ORIGIN 0.000 0.000 ; + FOREIGN CELL 0.000 0.000 ; + SIZE 788.230 BY 910.880 ; + SYMMETRY X Y R90 ; + PIN erase + DIRECTION INPUT ; + USE SIGNAL ; + PORT + LAYER M3 ; + RECT 0.000 294.990 1.880 296.120 ; + LAYER M2 ; + RECT 0.000 294.990 1.880 296.120 ; + END + END erase + PIN GND_0 + DIRECTION INOUT ; + USE GROUND ; + PORT + LAYER M3 ; + RECT 92.610 903.380 111.410 910.880 ; + LAYER M4 ; + RECT 97.310 903.380 106.710 910.880 ; + END + END GND_0 + PIN VDD_0 + DIRECTION INOUT ; + USE POWER ; + PORT + LAYER M3 ; + RECT 780.710 394.840 788.230 413.640 ; + LAYER M4 ; + RECT 780.710 399.540 788.230 408.940 ; + END + END VDD_0 + OBS + LAYER M1 ; + RECT 0.000 0.000 788.230 910.880 ; + LAYER M2 ; + RECT 0.000 0.000 788.230 910.880 ; + LAYER M3 ; + RECT 0.000 0.000 788.230 910.880 ; + LAYER M4 ; + RECT 0.000 0.000 788.230 910.880 ; + LAYER V1 ; + RECT 0.000 0.000 788.230 910.880 ; + LAYER V2 ; + RECT 0.000 0.000 788.230 910.880 ; + LAYER V3 ; + RECT 0.000 0.000 788.230 910.880 ; + END + +END CELL + +END LIBRARY diff --git a/src/ppl/include/ppl/IOPlacer.h b/src/ppl/include/ppl/IOPlacer.h index 76feb3b430a..777d8e62e97 100644 --- a/src/ppl/include/ppl/IOPlacer.h +++ b/src/ppl/include/ppl/IOPlacer.h @@ -125,7 +125,7 @@ class IOPlacer void init(odb::dbDatabase* db, Logger* logger); void clear(); void clearConstraints(); - void run(bool random_mode); + void runHungarianMatching(bool random_mode); void runAnnealing(bool random); void reportHPWL(); void printConfig(bool annealing = false); @@ -167,6 +167,8 @@ class IOPlacer int perturb_per_iter, float alpha); void checkPinPlacement(); + bool checkPinConstraints(); + bool checkMirroredPins(); void setRenderer(std::unique_ptr ioplacer_renderer); AbstractIOPlacerRenderer* getRenderer(); @@ -184,9 +186,8 @@ class IOPlacer void createTopLayerPinPattern(); void initNetlistAndCore(const std::set& hor_layer_idx, const std::set& ver_layer_idx); - void initIOLists(); - void initParms(); std::vector getValidSlots(int first, int last, bool top_layer); + std::vector findValidSlots(const Constraint& constraint, bool top_layer); void randomPlacement(); void randomPlacement(std::vector pin_indices, std::vector slot_indices, @@ -226,7 +227,6 @@ class IOPlacer void createSectionsPerEdge(Edge edge, const std::set& layers); void createSections(); void addGroupToFallback(const std::vector& pin_group, bool order); - void setupSections(int assigned_pins_count); bool assignPinsToSections(int assigned_pins_count); bool assignPinToSection(IOPin& io_pin, int idx, @@ -273,8 +273,6 @@ class IOPlacer int64_t computeIncrease(int min_dist, int64_t num_pins, int64_t curr_length); // db functions - void populateIOPlacer(const std::set& hor_layer_idx, - const std::set& ver_layer_idx); void findConstraintRegion(const Interval& interval, const Rect& constraint_box, Rect& region); @@ -294,7 +292,6 @@ class IOPlacer std::vector assignment_; int slots_per_section_ = 0; - float slots_increase_factor_ = 0; int top_layer_pins_count_ = 0; // set the offset on tracks as 15 to approximate the size of a GCell in global // router @@ -310,7 +307,6 @@ class IOPlacer Logger* logger_ = nullptr; std::unique_ptr parms_; - std::unique_ptr netlist_io_pins_; std::vector slots_; std::vector top_layer_slots_; std::vector
sections_; diff --git a/src/ppl/include/ppl/Parameters.h b/src/ppl/include/ppl/Parameters.h index 4352a47cb5c..3392713b3a6 100644 --- a/src/ppl/include/ppl/Parameters.h +++ b/src/ppl/include/ppl/Parameters.h @@ -45,12 +45,6 @@ class Parameters void setReportHPWL(bool report) { report_hpwl_ = report; } bool getReportHPWL() const { return report_hpwl_; } - void setNumSlots(int num_slots) { num_slots_ = num_slots; } - int getNumSlots() const { return num_slots_; } - - void setSlotsFactor(float factor) { slots_factor_ = factor; } - float getSlotsFactor() const { return slots_factor_; } - void setSlotsPerSection(float slots_per_section) { slots_per_section_ = slots_per_section; @@ -114,8 +108,6 @@ class Parameters private: bool report_hpwl_ = false; - int num_slots_ = -1; - float slots_factor_ = -1; int slots_per_section_ = 200; float horizontal_thickness_multiplier_ = 1; float vertical_thickness_multiplier_ = 1; diff --git a/src/ppl/src/HungarianMatching.cpp b/src/ppl/src/HungarianMatching.cpp index 06f64e6aec4..eed47fa221d 100644 --- a/src/ppl/src/HungarianMatching.cpp +++ b/src/ppl/src/HungarianMatching.cpp @@ -135,7 +135,7 @@ void HungarianMatching::getFinalAssignment(std::vector& assignment, || io_pin.isPlaced()) { continue; } - io_pin.setPos(slots_[slot_index].pos); + io_pin.setPosition(slots_[slot_index].pos); io_pin.setLayer(slots_[slot_index].layer); io_pin.setPlaced(); io_pin.setEdge(slots_[slot_index].edge); @@ -160,8 +160,8 @@ void HungarianMatching::assignMirroredPins(IOPin& io_pin, int mirrored_pin_idx = netlist_->getIoPinIdx(mirrored_term); IOPin& mirrored_pin = netlist_->getIoPin(mirrored_pin_idx); - odb::Point mirrored_pos = core_->getMirroredPosition(io_pin.getPos()); - mirrored_pin.setPos(mirrored_pos); + odb::Point mirrored_pos = core_->getMirroredPosition(io_pin.getPosition()); + mirrored_pin.setPosition(mirrored_pos); mirrored_pin.setLayer(io_pin.getLayer()); mirrored_pin.setEdge(getMirroredEdge(io_pin.getEdge())); mirrored_pin.setPlaced(); @@ -302,7 +302,7 @@ void HungarianMatching::getAssignmentForGroups(std::vector& assignment, for (int pin_idx : pins) { IOPin& io_pin = netlist_->getIoPin(pin_idx); - io_pin.setPos(slots_[slot_index + pin_cnt].pos); + io_pin.setPosition(slots_[slot_index + pin_cnt].pos); io_pin.setLayer(slots_[slot_index + pin_cnt].layer); io_pin.setEdge(slots_[slot_index + pin_cnt].edge); assignment.push_back(io_pin); diff --git a/src/ppl/src/IOPlacer.cpp b/src/ppl/src/IOPlacer.cpp index c3496cdd00c..9fd43896e65 100644 --- a/src/ppl/src/IOPlacer.cpp +++ b/src/ppl/src/IOPlacer.cpp @@ -60,7 +60,6 @@ IOPlacer::IOPlacer() : ioplacer_renderer_(nullptr) netlist_ = std::make_unique(); core_ = std::make_unique(); parms_ = std::make_unique(); - netlist_io_pins_ = std::make_unique(); top_grid_ = std::make_unique(); } @@ -127,23 +126,8 @@ std::string IOPlacer::getEdgeString(Edge edge) void IOPlacer::initNetlistAndCore(const std::set& hor_layer_idx, const std::set& ver_layer_idx) { - populateIOPlacer(hor_layer_idx, ver_layer_idx); -} - -void IOPlacer::initParms() -{ - slots_per_section_ = parms_->getSlotsPerSection(); - slots_increase_factor_ = 0.01f; - netlist_ = std::make_unique(); - netlist_io_pins_ = std::make_unique(); - - if (parms_->getNumSlots() > -1) { - slots_per_section_ = parms_->getNumSlots(); - } - - if (parms_->getSlotsFactor() > -1) { - slots_increase_factor_ = parms_->getSlotsFactor(); - } + initCore(hor_layer_idx, ver_layer_idx); + initNetlist(); } std::vector IOPlacer::getValidSlots(int first, int last, bool top_layer) @@ -161,43 +145,58 @@ std::vector IOPlacer::getValidSlots(int first, int last, bool top_layer) return valid_slots; } -void IOPlacer::randomPlacement() +std::vector IOPlacer::findValidSlots(const Constraint& constraint, + const bool top_layer) { - for (Constraint& constraint : constraints_) { + std::vector valid_slots; + if (top_layer) { + for (const Section& section : constraint.sections) { + std::vector constraint_slots + = getValidSlots(section.begin_slot, section.end_slot, top_layer); + valid_slots.insert( + valid_slots.end(), constraint_slots.begin(), constraint_slots.end()); + } + } else { int first_slot = constraint.sections.front().begin_slot; int last_slot = constraint.sections.back().end_slot; + valid_slots = getValidSlots(first_slot, last_slot, top_layer); + } + + return valid_slots; +} +void IOPlacer::randomPlacement() +{ + for (Constraint& constraint : constraints_) { bool top_layer = constraint.interval.getEdge() == Edge::invalid; - for (auto& io_group : netlist_io_pins_->getIOGroups()) { + for (auto& io_group : netlist_->getIOGroups()) { const PinSet& pin_list = constraint.pin_list; - IOPin& io_pin = netlist_io_pins_->getIoPin(io_group.pin_indices[0]); + IOPin& io_pin = netlist_->getIoPin(io_group.pin_indices[0]); if (io_pin.isPlaced() || io_pin.inFallback()) { continue; } if (std::find(pin_list.begin(), pin_list.end(), io_pin.getBTerm()) != pin_list.end()) { - std::vector valid_slots - = getValidSlots(first_slot, last_slot, top_layer); + std::vector valid_slots = findValidSlots(constraint, top_layer); randomPlacement( io_group.pin_indices, std::move(valid_slots), top_layer, true); } } - std::vector valid_slots - = getValidSlots(first_slot, last_slot, top_layer); + std::vector valid_slots = findValidSlots(constraint, top_layer); std::vector pin_indices; for (bool mirrored_pins : {true, false}) { - std::vector indices = findPinsForConstraint( - constraint, netlist_io_pins_.get(), mirrored_pins); + std::vector indices + = findPinsForConstraint(constraint, netlist_.get(), mirrored_pins); pin_indices.insert(pin_indices.end(), indices.begin(), indices.end()); } randomPlacement( std::move(pin_indices), std::move(valid_slots), top_layer, false); } - for (auto& io_group : netlist_io_pins_->getIOGroups()) { - IOPin& io_pin = netlist_io_pins_->getIoPin(io_group.pin_indices[0]); + for (auto& io_group : netlist_->getIOGroups()) { + IOPin& io_pin = netlist_->getIoPin(io_group.pin_indices[0]); if (io_pin.isPlaced() || io_pin.inFallback()) { continue; } @@ -209,8 +208,8 @@ void IOPlacer::randomPlacement() std::vector valid_slots = getValidSlots(0, slots_.size() - 1, false); std::vector pin_indices; - for (int i = 0; i < netlist_io_pins_->numIOPins(); i++) { - IOPin& io_pin = netlist_io_pins_->getIoPin(i); + for (int i = 0; i < netlist_->numIOPins(); i++) { + IOPin& io_pin = netlist_->getIoPin(i); if (!io_pin.isPlaced() && !io_pin.inFallback()) { pin_indices.push_back(i); } @@ -270,7 +269,7 @@ void IOPlacer::randomPlacement(std::vector pin_indices, std::vector& slots = top_layer ? top_layer_slots_ : slots_; - std::vector& io_pins = netlist_io_pins_->getIOPins(); + std::vector& io_pins = netlist_->getIOPins(); int io_idx = 0; for (bool assign_mirrored : {true, false}) { for (int pin_idx : pin_indices) { @@ -305,7 +304,7 @@ void IOPlacer::randomPlacement(std::vector pin_indices, slot_idx++; } } - io_pin.setPos(slots[slot_idx].pos); + io_pin.setPosition(slots[slot_idx].pos); io_pin.setPlaced(); io_pin.setEdge(slots[slot_idx].edge); slots[slot_idx].used = true; @@ -317,11 +316,12 @@ void IOPlacer::randomPlacement(std::vector pin_indices, if (assign_mirrored && mirrored_pins_.find(io_pin.getBTerm()) != mirrored_pins_.end()) { odb::dbBTerm* mirrored_term = mirrored_pins_[io_pin.getBTerm()]; - int mirrored_pin_idx = netlist_io_pins_->getIoPinIdx(mirrored_term); - IOPin& mirrored_pin = netlist_io_pins_->getIoPin(mirrored_pin_idx); + int mirrored_pin_idx = netlist_->getIoPinIdx(mirrored_term); + IOPin& mirrored_pin = netlist_->getIoPin(mirrored_pin_idx); - odb::Point mirrored_pos = core_->getMirroredPosition(io_pin.getPos()); - mirrored_pin.setPos(mirrored_pos); + odb::Point mirrored_pos + = core_->getMirroredPosition(io_pin.getPosition()); + mirrored_pin.setPosition(mirrored_pos); mirrored_pin.setLayer(slots[slot_idx].layer); mirrored_pin.setPlaced(); mirrored_pin.setEdge(slots[slot_idx].edge); @@ -354,7 +354,7 @@ int IOPlacer::placeFallbackPins(bool random) bool constrained_group = false; bool have_mirrored = false; for (const int pin_idx : group.first) { - const IOPin& pin = netlist_io_pins_->getIoPin(pin_idx); + const IOPin& pin = netlist_->getIoPin(pin_idx); if (pin.isMirrored()) { have_mirrored = true; break; @@ -362,7 +362,7 @@ int IOPlacer::placeFallbackPins(bool random) } int pin_idx = group.first[0]; - IOPin& io_pin = netlist_io_pins_->getIoPin(pin_idx); + IOPin& io_pin = netlist_->getIoPin(pin_idx); if (!random) { // check if group is constrained odb::dbBTerm* bterm = io_pin.getBTerm(); @@ -457,8 +457,8 @@ void IOPlacer::assignMirroredPins(IOPin& io_pin, int mirrored_pin_idx = netlist_->getIoPinIdx(mirrored_term); IOPin& mirrored_pin = netlist_->getIoPin(mirrored_pin_idx); - odb::Point mirrored_pos = core_->getMirroredPosition(io_pin.getPos()); - mirrored_pin.setPos(mirrored_pos); + odb::Point mirrored_pos = core_->getMirroredPosition(io_pin.getPosition()); + mirrored_pin.setPosition(mirrored_pos); mirrored_pin.setLayer(io_pin.getLayer()); mirrored_pin.setPlaced(); mirrored_pin.setEdge(getMirroredEdge(io_pin.getEdge())); @@ -568,9 +568,9 @@ void IOPlacer::placeFallbackGroup( for (int i = 0; i <= group_last; ++i) { const int pin_idx = group.first[reverse ? group_last - i : i]; - IOPin& io_pin = netlist_io_pins_->getIoPin(pin_idx); + IOPin& io_pin = netlist_->getIoPin(pin_idx); Slot& slot = slots_[place_slot]; - io_pin.setPos(slot.pos); + io_pin.setPosition(slot.pos); io_pin.setLayer(slot.layer); io_pin.setEdge(slot.edge); assignment_.push_back(io_pin); @@ -588,29 +588,6 @@ void IOPlacer::placeFallbackGroup( group.first.size()); } -void IOPlacer::initIOLists() -{ - netlist_io_pins_->reset(); - int idx = 0; - for (IOPin& io_pin : netlist_->getIOPins()) { - std::vector inst_pins_vector; - if (netlist_->numSinksOfIO(idx) != 0) { - netlist_->getSinksOfIO(idx, inst_pins_vector); - netlist_io_pins_->addIONet(io_pin, inst_pins_vector); - } else { - zero_sink_ios_.push_back(io_pin); - netlist_io_pins_->addIONet(io_pin, inst_pins_vector); - } - idx++; - } - - int group_idx = 0; - for (const auto& [pins, order] : pin_groups_) { - netlist_io_pins_->createIOGroup(pins, order, group_idx); - group_idx++; - } -} - bool IOPlacer::checkBlocked(Edge edge, int pos, int layer) { for (Interval blocked_interval : excluded_intervals_) { @@ -704,10 +681,10 @@ void IOPlacer::writePinPlacement(const char* file_name, const bool placed) std::vector edges_list = {Edge::bottom, Edge::right, Edge::top, Edge::left}; - if (!netlist_io_pins_->getIOPins().empty()) { + if (!netlist_->getIOPins().empty()) { for (const Edge& edge : edges_list) { out << "#Edge: " << getEdgeString(edge) << "\n"; - for (const IOPin& io_pin : netlist_io_pins_->getIOPins()) { + for (const IOPin& io_pin : netlist_->getIOPins()) { if (io_pin.getEdge() == edge) { const int layer = io_pin.getLayer(); odb::dbTechLayer* tech_layer = getTech()->findRoutingLayer(layer); @@ -958,8 +935,8 @@ void IOPlacer::defineSlots() findSlotsForTopLayer(); - int regular_pin_count = static_cast(netlist_io_pins_->getIOPins().size()) - - top_layer_pins_count_; + int regular_pin_count + = static_cast(netlist_->getIOPins().size()) - top_layer_pins_count_; if (regular_pin_count > slots_.size()) { int min_dist = std::numeric_limits::min(); for (int layer_idx : ver_layers_) { @@ -1043,6 +1020,7 @@ std::vector
IOPlacer::createSectionsPerConstraint( ? hor_layers_ : ver_layers_; + bool first_layer = true; for (int layer : layers) { std::vector::iterator it = std::find_if(slots_.begin(), slots_.end(), [&](const Slot& s) { @@ -1071,10 +1049,13 @@ std::vector
IOPlacer::createSectionsPerConstraint( || s.layer != layer); }); int constraint_end = it - slots_.begin() - 1; - constraint.first_slot = constraint_begin; + if (first_layer) { + constraint.first_slot = constraint_begin; + } constraint.last_slot = constraint_end; findSections(constraint_begin, constraint_end, edge, sections); + first_layer = false; } } else { sections = findSectionsForTopLayer(constraint.box); @@ -1119,7 +1100,10 @@ int IOPlacer::updateSection(Section& section, std::vector& slots) slot_idx++) { new_slots_count += (slots[slot_idx].isAvailable()) ? 1 : 0; } + // reset the num_slots and used_slots considering that all the other used + // slots of the section don't exist, since they can't be used anymore section.num_slots = new_slots_count; + section.used_slots = 0; return new_slots_count; } @@ -1145,11 +1129,11 @@ std::vector
IOPlacer::assignConstrainedPinsToSections( assignConstrainedGroupsToSections( constraint, constraint.sections, mirrored_pins_cnt, mirrored_only); - std::vector pin_indices = findPinsForConstraint( - constraint, netlist_io_pins_.get(), mirrored_only); + std::vector pin_indices + = findPinsForConstraint(constraint, netlist_.get(), mirrored_only); for (int idx : pin_indices) { - IOPin& io_pin = netlist_io_pins_->getIoPin(idx); + IOPin& io_pin = netlist_->getIoPin(idx); if (mirrored_pins_.find(io_pin.getBTerm()) != mirrored_pins_.end() && !io_pin.isAssignedToSection()) { mirrored_pins_cnt++; @@ -1165,9 +1149,9 @@ void IOPlacer::assignConstrainedGroupsToSections(Constraint& constraint, int& mirrored_pins_cnt, bool mirrored_only) { - for (auto& io_group : netlist_io_pins_->getIOGroups()) { + for (auto& io_group : netlist_->getIOGroups()) { const PinSet& pin_list = constraint.pin_list; - IOPin& io_pin = netlist_io_pins_->getIoPin(io_group.pin_indices[0]); + IOPin& io_pin = netlist_->getIoPin(io_group.pin_indices[0]); if (std::find(pin_list.begin(), pin_list.end(), io_pin.getBTerm()) != pin_list.end()) { @@ -1175,7 +1159,7 @@ void IOPlacer::assignConstrainedGroupsToSections(Constraint& constraint, continue; } for (int pin_idx : io_group.pin_indices) { - IOPin& io_pin = netlist_io_pins_->getIoPin(pin_idx); + IOPin& io_pin = netlist_->getIoPin(pin_idx); if (mirrored_pins_.find(io_pin.getBTerm()) != mirrored_pins_.end() && mirrored_only) { mirrored_pins_cnt++; @@ -1189,7 +1173,7 @@ void IOPlacer::assignConstrainedGroupsToSections(Constraint& constraint, bool IOPlacer::groupHasMirroredPin(const std::vector& group) { for (int pin_idx : group) { - IOPin& io_pin = netlist_io_pins_->getIoPin(pin_idx); + IOPin& io_pin = netlist_->getIoPin(pin_idx); if (mirrored_pins_.find(io_pin.getBTerm()) != mirrored_pins_.end()) { return true; } @@ -1202,7 +1186,7 @@ int IOPlacer::assignGroupsToSections(int& mirrored_pins_cnt) { int total_pins_assigned = 0; - for (auto& io_group : netlist_io_pins_->getIOGroups()) { + for (auto& io_group : netlist_->getIOGroups()) { int before_assignment = total_pins_assigned; total_pins_assigned += assignGroupToSection( io_group.pin_indices, sections_, io_group.order); @@ -1210,7 +1194,7 @@ int IOPlacer::assignGroupsToSections(int& mirrored_pins_cnt) // check if group was assigned here, and not during constrained groups if (total_pins_assigned > before_assignment) { for (int pin_idx : io_group.pin_indices) { - IOPin& io_pin = netlist_io_pins_->getIoPin(pin_idx); + IOPin& io_pin = netlist_->getIoPin(pin_idx); if (mirrored_pins_.find(io_pin.getBTerm()) != mirrored_pins_.end()) { mirrored_pins_cnt++; } @@ -1225,7 +1209,7 @@ int IOPlacer::assignGroupToSection(const std::vector& io_group, std::vector
& sections, bool order) { - Netlist* net = netlist_io_pins_.get(); + Netlist* net = netlist_.get(); int group_size = io_group.size(); bool group_assigned = false; int total_pins_assigned = 0; @@ -1312,12 +1296,12 @@ void IOPlacer::addGroupToFallback(const std::vector& pin_group, bool order) { fallback_pins_.groups.emplace_back(pin_group, order); for (int pin_idx : pin_group) { - IOPin& io_pin = netlist_io_pins_->getIoPin(pin_idx); + IOPin& io_pin = netlist_->getIoPin(pin_idx); io_pin.setFallback(); if (mirrored_pins_.find(io_pin.getBTerm()) != mirrored_pins_.end()) { odb::dbBTerm* mirrored_term = mirrored_pins_[io_pin.getBTerm()]; - int mirrored_pin_idx = netlist_io_pins_->getIoPinIdx(mirrored_term); - IOPin& mirrored_pin = netlist_io_pins_->getIoPin(mirrored_pin_idx); + int mirrored_pin_idx = netlist_->getIoPinIdx(mirrored_term); + IOPin& mirrored_pin = netlist_->getIoPin(mirrored_pin_idx); mirrored_pin.setFallback(); } } @@ -1325,7 +1309,7 @@ void IOPlacer::addGroupToFallback(const std::vector& pin_group, bool order) bool IOPlacer::assignPinsToSections(int assigned_pins_count) { - Netlist* net = netlist_io_pins_.get(); + Netlist* net = netlist_.get(); std::vector
& sections = sections_; createSections(); @@ -1386,7 +1370,7 @@ bool IOPlacer::assignPinToSection(IOPin& io_pin, && !io_pin.inFallback()) { std::vector dst(sections.size()); for (int i = 0; i < sections.size(); i++) { - dst[i] = netlist_io_pins_->computeIONetHPWL(idx, sections[i].pos); + dst[i] = netlist_->computeIONetHPWL(idx, sections[i].pos); } for (auto i : sortIndexes(dst)) { if (sections[i].used_slots < sections[i].num_slots) { @@ -1409,8 +1393,8 @@ bool IOPlacer::assignPinToSection(IOPin& io_pin, void IOPlacer::assignMirroredPin(IOPin& io_pin) { odb::dbBTerm* mirrored_term = mirrored_pins_[io_pin.getBTerm()]; - int mirrored_pin_idx = netlist_io_pins_->getIoPinIdx(mirrored_term); - IOPin& mirrored_pin = netlist_io_pins_->getIoPin(mirrored_pin_idx); + int mirrored_pin_idx = netlist_->getIoPinIdx(mirrored_term); + IOPin& mirrored_pin = netlist_->getIoPin(mirrored_pin_idx); // Mark mirrored pin as assigned to section to prevent assigning it to // another section that is not aligned with his pair mirrored_pin.assignToSection(); @@ -1428,48 +1412,17 @@ void IOPlacer::printConfig(bool annealing) logger_->info(PPL, 3, "Number of I/O w/sink {}", - netlist_io_pins_->numIOPins() - zero_sink_ios_.size()); + netlist_->numIOPins() - zero_sink_ios_.size()); logger_->info(PPL, 4, "Number of I/O w/o sink {}", zero_sink_ios_.size()); + if (!netlist_->getIOGroups().empty()) { + logger_->info( + PPL, 6, "Number of I/O Groups {}", netlist_->getIOGroups().size()); + } if (!annealing) { logger_->info(PPL, 5, "Slots per section {}", slots_per_section_); - logger_->info( - PPL, 6, "Slots increase factor {:.1}", slots_increase_factor_); } } -void IOPlacer::setupSections(int assigned_pins_count) -{ - bool all_assigned; - int i = 0; - - do { - logger_->info(PPL, 10, "Tentative {} to set up sections.", i++); - printConfig(); - - all_assigned = assignPinsToSections(assigned_pins_count); - - slots_per_section_ *= (1 + slots_increase_factor_); - if (sections_.size() > MAX_SECTIONS_RECOMMENDED) { - logger_->warn(PPL, - 36, - "Number of sections is {}" - " while the maximum recommended value is {}" - " this may negatively affect performance.", - sections_.size(), - MAX_SECTIONS_RECOMMENDED); - } - if (slots_per_section_ > MAX_SLOTS_RECOMMENDED) { - logger_->warn(PPL, - 37, - "Number of slots per sections is {}" - " while the maximum recommended value is {}" - " this may negatively affect performance.", - slots_per_section_, - MAX_SLOTS_RECOMMENDED); - } - } while (!all_assigned); -} - void IOPlacer::updateOrientation(IOPin& pin) { const int x = pin.getX(); @@ -1756,7 +1709,7 @@ void IOPlacer::getPinsFromDirectionConstraint(Constraint& constraint) { if (constraint.direction != Direction::invalid && constraint.pin_list.empty()) { - for (const IOPin& io_pin : netlist_io_pins_->getIOPins()) { + for (const IOPin& io_pin : netlist_->getIOPins()) { if (io_pin.getDirection() == constraint.direction) { constraint.pin_list.insert(io_pin.getBTerm()); } @@ -1815,13 +1768,13 @@ std::vector IOPlacer::findPinsForConstraint(const Constraint& constraint, void IOPlacer::initMirroredPins(bool annealing) { - for (IOPin& io_pin : netlist_io_pins_->getIOPins()) { + for (IOPin& io_pin : netlist_->getIOPins()) { if (mirrored_pins_.find(io_pin.getBTerm()) != mirrored_pins_.end()) { - int pin_idx = netlist_io_pins_->getIoPinIdx(io_pin.getBTerm()); + int pin_idx = netlist_->getIoPinIdx(io_pin.getBTerm()); io_pin.setMirrored(); odb::dbBTerm* mirrored_term = mirrored_pins_[io_pin.getBTerm()]; - int mirrored_pin_idx = netlist_io_pins_->getIoPinIdx(mirrored_term); - IOPin& mirrored_pin = netlist_io_pins_->getIoPin(mirrored_pin_idx); + int mirrored_pin_idx = netlist_->getIoPinIdx(mirrored_term); + IOPin& mirrored_pin = netlist_->getIoPin(mirrored_pin_idx); mirrored_pin.setMirrored(); io_pin.setMirrorPinIdx(mirrored_pin_idx); mirrored_pin.setMirrorPinIdx(pin_idx); @@ -1875,10 +1828,12 @@ void IOPlacer::initConstraints(bool annealing) } for (odb::dbBTerm* term : constraint.pin_list) { - int pin_idx = netlist_io_pins_->getIoPinIdx(term); - IOPin& io_pin = netlist_io_pins_->getIoPin(pin_idx); + int pin_idx = netlist_->getIoPinIdx(term); + IOPin& io_pin = netlist_->getIoPin(pin_idx); io_pin.setConstraintIdx(constraint_idx); + io_pin.setInConstraint(); constraint.pin_indices.push_back(pin_idx); + constraint.mirrored_pins_count += io_pin.isMirrored() ? 1 : 0; if (io_pin.getGroupIdx() != -1) { constraint.pin_groups.insert(io_pin.getGroupIdx()); } @@ -1918,7 +1873,7 @@ void IOPlacer::checkPinsInMultipleConstraints() { std::string pins_in_mult_constraints; if (!constraints_.empty()) { - for (IOPin& io_pin : netlist_io_pins_->getIOPins()) { + for (IOPin& io_pin : netlist_->getIOPins()) { int constraint_cnt = 0; for (Constraint& constraint : constraints_) { const PinSet& pin_list = constraint.pin_list; @@ -1947,7 +1902,7 @@ void IOPlacer::checkPinsInMultipleGroups() { std::string pins_in_mult_groups; if (!pin_groups_.empty()) { - for (IOPin& io_pin : netlist_io_pins_->getIOPins()) { + for (IOPin& io_pin : netlist_->getIOPins()) { int group_cnt = 0; for (PinGroup& group : pin_groups_) { const PinList& pin_list = group.pins; @@ -2047,7 +2002,7 @@ void IOPlacer::findPinAssignment(std::vector
& sections, if (!section.pin_indices.empty()) { if (section.edge == Edge::invalid) { HungarianMatching hg(section, - netlist_io_pins_.get(), + netlist_.get(), core_.get(), top_layer_slots_, logger_, @@ -2055,7 +2010,7 @@ void IOPlacer::findPinAssignment(std::vector
& sections, hg_vec.push_back(hg); } else { HungarianMatching hg( - section, netlist_io_pins_.get(), core_.get(), slots_, logger_, db_); + section, netlist_.get(), core_.get(), slots_, logger_, db_); hg_vec.push_back(hg); } } @@ -2101,14 +2056,14 @@ void IOPlacer::updateSlots() } } -void IOPlacer::run(bool random_mode) +void IOPlacer::runHungarianMatching(bool random_mode) { - initParms(); + slots_per_section_ = parms_->getSlotsPerSection(); initNetlistAndCore(hor_layers_, ver_layers_); getBlockedRegionsFromMacros(); - initIOLists(); + // initIOLists(); defineSlots(); initMirroredPins(); @@ -2120,9 +2075,10 @@ void IOPlacer::run(bool random_mode) } else { int constrained_pins_cnt = 0; int mirrored_pins_cnt = 0; + printConfig(); // add groups to fallback - for (const auto& io_group : netlist_io_pins_->getIOGroups()) { + for (const auto& io_group : netlist_->getIOGroups()) { if (io_group.pin_indices.size() > slots_per_section_) { debugPrint(logger_, utl::PPL, @@ -2176,7 +2132,7 @@ void IOPlacer::run(bool random_mode) } constrained_pins_cnt += placeFallbackPins(false); - setupSections(constrained_pins_cnt); + assignPinsToSections(constrained_pins_cnt); findPinAssignment(sections_, false); } @@ -2247,19 +2203,17 @@ void IOPlacer::setAnnealingDebugNoPauseMode(const bool no_pause_mode) void IOPlacer::runAnnealing(bool random) { - initParms(); - + slots_per_section_ = parms_->getSlotsPerSection(); initNetlistAndCore(hor_layers_, ver_layers_); getBlockedRegionsFromMacros(); - initIOLists(); defineSlots(); initMirroredPins(true); initConstraints(true); ppl::SimulatedAnnealing annealing( - netlist_io_pins_.get(), core_.get(), slots_, constraints_, logger_, db_); + netlist_.get(), core_.get(), slots_, constraints_, logger_, db_); if (isAnnealingDebugOn()) { annealing.setDebugOn(std::move(ioplacer_renderer_)); @@ -2289,7 +2243,7 @@ void IOPlacer::checkPinPlacement() bool invalid = false; std::map> layer_positions_map; - for (const IOPin& pin : netlist_io_pins_->getIOPins()) { + for (const IOPin& pin : netlist_->getIOPins()) { int layer = pin.getLayer(); if (layer_positions_map[layer].empty()) { @@ -2313,14 +2267,88 @@ void IOPlacer::checkPinPlacement() } } + invalid = invalid || checkPinConstraints() || checkMirroredPins(); if (invalid) { logger_->error(PPL, 107, "Invalid pin placement."); } } +bool IOPlacer::checkPinConstraints() +{ + bool invalid = false; + + for (const IOPin& pin : netlist_->getIOPins()) { + if (pin.isInConstraint()) { + const int constraint_idx = pin.getConstraintIdx(); + const Constraint& constraint = constraints_[constraint_idx]; + const Interval& constraint_interval = constraint.interval; + if (pin.getEdge() != constraint_interval.getEdge()) { + logger_->warn(PPL, + 92, + "Pin {} is not placed in its constraint edge.", + pin.getName()); + invalid = true; + } + + if (constraint_interval.getEdge() != Edge::invalid) { + const int constraint_begin = constraint_interval.getBegin(); + const int constraint_end = constraint_interval.getEnd(); + const int pin_coord + = constraint_interval.getEdge() == Edge::bottom + || constraint_interval.getEdge() == Edge::top + ? pin.getPosition().getX() + : pin.getPosition().getY(); + if (pin_coord < constraint_begin || pin_coord > constraint_end) { + logger_->warn(PPL, + 102, + "Pin {} is not placed in its constraint interval.", + pin.getName()); + invalid = true; + } + } else { + if (!constraint.box.overlaps(pin.getPosition())) { + logger_->warn( + PPL, + 105, + "Pin {} is not placed in the upper layer grid region {}. {}", + pin.getName(), + constraint.box, + pin.getPosition()); + invalid = true; + } + } + } + } + + return invalid; +} + +bool IOPlacer::checkMirroredPins() +{ + bool invalid = false; + + for (const IOPin& pin : netlist_->getIOPins()) { + if (pin.isMirrored()) { + int mirrored_pin_idx = pin.getMirrorPinIdx(); + const IOPin& mirrored_pin = netlist_->getIoPin(mirrored_pin_idx); + if (pin.getPosition().getX() != mirrored_pin.getPosition().getX() + && pin.getPosition().getY() != mirrored_pin.getPosition().getY()) { + logger_->warn(PPL, + 103, + "Pins {} and {} are not mirroring each other.", + pin.getName(), + mirrored_pin.getName()); + invalid = true; + } + } + } + + return invalid; +} + void IOPlacer::reportHPWL() { - int64 total_hpwl = computeIONetsHPWL(netlist_io_pins_.get()); + int64 total_hpwl = computeIONetsHPWL(netlist_.get()); logger_->metric("design__io__hpwl", total_hpwl); logger_->info(PPL, 12, @@ -2543,14 +2571,6 @@ Interval IOPlacer::getIntervalFromPin(IOPin& io_pin, const Rect& die_boundary) return Interval(edge, begin, end, layer); } -// db functions -void IOPlacer::populateIOPlacer(const std::set& hor_layer_idx, - const std::set& ver_layer_idx) -{ - initCore(hor_layer_idx, ver_layer_idx); - initNetlist(); -} - void IOPlacer::initCore(const std::set& hor_layer_idxs, const std::set& ver_layer_idxs) { @@ -2743,19 +2763,23 @@ std::vector
IOPlacer::findSectionsForTopLayer(const odb::Rect& region) std::vector
sections; for (int x = top_grid_->llx(); x < top_grid_->urx(); x += top_grid_->x_step) { - std::vector& slots = top_layer_slots_; - std::vector::iterator it - = std::find_if(slots.begin(), slots.end(), [&](Slot s) { - return (s.pos.x() >= x && s.pos.x() >= lb_x && s.pos.y() >= lb_y); - }); - int edge_begin = it - slots.begin(); - int edge_x = slots[edge_begin].pos.x(); - - it = std::find_if(slots.begin() + edge_begin, slots.end(), [&](Slot s) { - return s.pos.x() != edge_x || s.pos.x() >= ub_x || s.pos.y() >= ub_y; - }); - int edge_end = it - slots.begin() - 1; - + if (x < lb_x || x > ub_x) { + continue; + } + std::vector::iterator it = std::find_if( + top_layer_slots_.begin(), top_layer_slots_.end(), [&](Slot s) { + return (s.pos.x() >= x && s.pos.x() >= lb_x && s.pos.y() >= lb_y); + }); + int edge_begin = it - top_layer_slots_.begin(); + int edge_x = top_layer_slots_[edge_begin].pos.x(); + + it = std::find_if(top_layer_slots_.begin() + edge_begin, + top_layer_slots_.end(), + [&](Slot s) { + return s.pos.x() != edge_x || s.pos.x() >= ub_x + || s.pos.y() >= ub_y; + }); + int edge_end = it - top_layer_slots_.begin() - 1; int end_slot = 0; while (end_slot < edge_end) { @@ -2765,13 +2789,13 @@ std::vector
IOPlacer::findSectionsForTopLayer(const odb::Rect& region) end_slot = edge_end; } for (int i = edge_begin; i <= end_slot; ++i) { - if (slots[i].blocked) { + if (top_layer_slots_[i].blocked) { blocked_slots++; } } int half_length_pt = edge_begin + (end_slot - edge_begin) / 2; Section n_sec; - n_sec.pos = slots.at(half_length_pt).pos; + n_sec.pos = top_layer_slots_.at(half_length_pt).pos; n_sec.num_slots = end_slot - edge_begin - blocked_slots + 1; n_sec.begin_slot = edge_begin; n_sec.end_slot = end_slot; @@ -2851,6 +2875,9 @@ void IOPlacer::initNetlist() } netlist_->addIONet(io_pin, inst_pins); + if (inst_pins.empty()) { + zero_sink_ios_.push_back(io_pin); + } } int group_idx = 0; @@ -2897,16 +2924,15 @@ void IOPlacer::commitConstraintsToDB() { for (Constraint& constraint : constraints_) { for (odb::dbBTerm* bterm : constraint.pin_list) { - int pin_idx = netlist_io_pins_->getIoPinIdx(bterm); - IOPin& io_pin = netlist_io_pins_->getIoPin(pin_idx); + int pin_idx = netlist_->getIoPinIdx(bterm); + IOPin& io_pin = netlist_->getIoPin(pin_idx); Rect constraint_region; const Interval& interval = constraint.interval; findConstraintRegion(interval, constraint.box, constraint_region); bterm->setConstraintRegion(constraint_region); if (io_pin.isMirrored()) { - IOPin& mirrored_pin - = netlist_io_pins_->getIoPin(io_pin.getMirrorPinIdx()); + IOPin& mirrored_pin = netlist_->getIoPin(io_pin.getMirrorPinIdx()); odb::dbBTerm* mirrored_bterm = getBlock()->findBTerm(mirrored_pin.getName().c_str()); Edge mirrored_edge = getMirroredEdge(interval.getEdge()); diff --git a/src/ppl/src/IOPlacer.i b/src/ppl/src/IOPlacer.i index e088c97bd7e..c0ec67e276d 100644 --- a/src/ppl/src/IOPlacer.i +++ b/src/ppl/src/IOPlacer.i @@ -125,18 +125,6 @@ tclSetStdSeq(Tcl_Obj *const source, namespace ppl { -void -set_num_slots(int numSlots) -{ - getIOPlacer()->getParameters()->setNumSlots(numSlots); -} - -void -set_slots_factor(float factor) -{ - getIOPlacer()->getParameters()->setSlotsFactor(factor); -} - void set_slots_per_section(int slots_per_section) { @@ -230,9 +218,9 @@ add_pin_group(PinList *pin_list, bool order) } void -run_io_placement(bool randomMode) +run_hungarian_matching(bool randomMode) { - getIOPlacer()->run(randomMode); + getIOPlacer()->runHungarianMatching(randomMode); } void diff --git a/src/ppl/src/IOPlacer.tcl b/src/ppl/src/IOPlacer.tcl index b821ffb52ea..62f04de8b94 100644 --- a/src/ppl/src/IOPlacer.tcl +++ b/src/ppl/src/IOPlacer.tcl @@ -644,7 +644,7 @@ proc place_pins { args } { if { [info exists flags(-annealing)] } { ppl::run_annealing [info exists flags(-random)] } else { - ppl::run_io_placement [info exists flags(-random)] + ppl::run_hungarian_matching [info exists flags(-random)] } } diff --git a/src/ppl/src/Netlist.h b/src/ppl/src/Netlist.h index f3a9d064a8f..02b24da7307 100644 --- a/src/ppl/src/Netlist.h +++ b/src/ppl/src/Netlist.h @@ -103,8 +103,8 @@ class IOPin odb::Point getPosition() const { return pos_; } void setX(const int x) { pos_.setX(x); } void setY(const int y) { pos_.setY(y); } - void setPos(const odb::Point& pos) { pos_ = pos; } - void setPos(const int x, const int y) { pos_ = odb::Point(x, y); } + void setPosition(const odb::Point& pos) { pos_ = pos; } + void setPosition(const int x, const int y) { pos_ = odb::Point(x, y); } void setLowerBound(const int x, const int y) { lower_bound_ = odb::Point(x, y); @@ -114,7 +114,6 @@ class IOPin upper_bound_ = odb::Point(x, y); }; std::string getName() const { return bterm_->getName(); } - odb::Point getPos() const { return pos_; } int getX() const { return pos_.getX(); } int getY() const { return pos_.getY(); } Direction getDirection() const { return direction_; } diff --git a/src/ppl/src/SimulatedAnnealing.cpp b/src/ppl/src/SimulatedAnnealing.cpp index 4fde74fe533..ec564539c92 100644 --- a/src/ppl/src/SimulatedAnnealing.cpp +++ b/src/ppl/src/SimulatedAnnealing.cpp @@ -86,17 +86,18 @@ void SimulatedAnnealing::run(float init_temperature, const int64 cost = pre_cost + getDeltaCost(prev_cost); const int delta_cost = cost - pre_cost; - debugPrint( - logger_, - utl::PPL, - "annealing", - 2, - "iteration: {}; temperature: {}; assignment cost: {}um; delta " - "cost: {}um", - iter, - temperature, - block->dbuToMicrons(cost), - block->dbuToMicrons(delta_cost)); + debugPrint(logger_, + utl::PPL, + "annealing", + 2, + "iteration: {}; perturb: {}; temperature: {}; assignment " + "cost: {}um; delta " + "cost: {}um", + iter, + perturb, + temperature, + block->dbuToMicrons(cost), + block->dbuToMicrons(delta_cost)); const float rand_float = distribution(generator_); const float accept_prob = std::exp((-1) * delta_cost / temperature); @@ -148,7 +149,7 @@ void SimulatedAnnealing::getAssignment(std::vector& assignment) IOPin& io_pin = netlist_->getIoPin(i); Slot& slot = slots_[pin_assignment_[i]]; - io_pin.setPos(slot.pos); + io_pin.setPosition(slot.pos); io_pin.setLayer(slot.layer); io_pin.setPlaced(); io_pin.setEdge(slot.edge); @@ -410,7 +411,10 @@ int SimulatedAnnealing::swapPins() = constraints_[constraint_idx].pin_indices; // if there is only one pin in the constraint, do not swap and fallback to // move a pin to a free slot - if (pin_indices.size() == 1) { + const int pin_count = pin_indices.size(); + const int mirrored_pins_count + = constraints_[constraint_idx].mirrored_pins_count; + if (pin_count == 1 || (pin_count - mirrored_pins_count) <= 1) { return move_fail_; } distribution = boost::random::uniform_int_distribution( @@ -796,15 +800,13 @@ void SimulatedAnnealing::getSlotsRange(const IOPin& io_pin, const Constraint& constraint = constraints_[pin_constraint_idx]; first_slot = constraint.first_slot; last_slot = constraint.last_slot; - } - - if (io_pin.isMirrored()) { + } else if (io_pin.isMirrored()) { const IOPin& mirrored_pin = netlist_->getIoPin(io_pin.getMirrorPinIdx()); const int mirrored_constraint_idx = mirrored_pin.getConstraintIdx(); if (mirrored_constraint_idx != -1) { const Constraint& constraint = constraints_[mirrored_constraint_idx]; - first_slot = getMirroredSlotIdx(constraint.first_slot); - last_slot = getMirroredSlotIdx(constraint.last_slot); + getMirroredSlotRange( + constraint.first_slot, constraint.last_slot, first_slot, last_slot); if (first_slot > last_slot) { std::swap(first_slot, last_slot); } @@ -859,6 +861,72 @@ int SimulatedAnnealing::getMirroredSlotIdx(int slot_idx) const return mirrored_idx; } +void SimulatedAnnealing::getMirroredSlotRange(const int slot_idx1, + const int slot_idx2, + int& mirrored_slot1, + int& mirrored_slot2) const +{ + const Slot& slot1 = slots_[slot_idx1]; + const Slot& slot2 = slots_[slot_idx2]; + if (slot1.edge != slot2.edge) { + logger_->error( + utl::PPL, 36, "Constraint cannot have positions in different edges."); + } + const Edge edge = slot1.edge; + const odb::Point& mirrored_pos1 = core_->getMirroredPosition(slot1.pos); + const odb::Point& mirrored_pos2 = core_->getMirroredPosition(slot2.pos); + + // find the approximated mirrored position of the original slot range + // endpoints. this is only necessary because when using multiple layers, the + // mirrored position of the original slots endpoints are not in the beginning + // of the mirrored range. + if (slot1.edge == Edge::bottom || slot1.edge == Edge::right) { + for (int i = slots_.size() - 1; i >= 0; i--) { + const Slot& slot = slots_[i]; + if ((edge == Edge::bottom && slot.pos.getX() >= mirrored_pos1.getX() + && slot.pos.getY() == mirrored_pos1.getY()) + || (edge == Edge::right && slot.pos.getX() == mirrored_pos1.getX() + && slot.pos.getY() >= mirrored_pos1.getY())) { + mirrored_slot1 = i; + break; + } + } + + for (int i = 0; i < slots_.size(); i++) { + const Slot& slot = slots_[i]; + if ((edge == Edge::bottom && slot.pos.getX() <= mirrored_pos2.getX() + && slot.pos.getY() == mirrored_pos2.getY()) + || (edge == Edge::right && slot.pos.getX() == mirrored_pos2.getX() + && slot.pos.getY() <= mirrored_pos2.getY())) { + mirrored_slot2 = i; + break; + } + } + } else { + for (int i = 0; i < slots_.size(); i++) { + const Slot& slot = slots_[i]; + if ((edge == Edge::top && slot.pos.getX() >= mirrored_pos1.getX() + && slot.pos.getY() == mirrored_pos1.getY()) + || (edge == Edge::left && slot.pos.getX() == mirrored_pos1.getX() + && slot.pos.getY() >= mirrored_pos1.getY())) { + mirrored_slot1 = i; + break; + } + } + + for (int i = slots_.size() - 1; i >= 0; i--) { + const Slot& slot = slots_[i]; + if ((edge == Edge::top && slot.pos.getX() <= mirrored_pos2.getX() + && slot.pos.getY() == mirrored_pos2.getY()) + || (edge == Edge::left && slot.pos.getX() == mirrored_pos2.getX() + && slot.pos.getY() <= mirrored_pos2.getY())) { + mirrored_slot2 = i; + break; + } + } + } +} + void SimulatedAnnealing::updateSlotsFromGroup( const std::vector& prev_slots_, bool block) diff --git a/src/ppl/src/SimulatedAnnealing.h b/src/ppl/src/SimulatedAnnealing.h index cd1d3bf486a..b64d990a837 100644 --- a/src/ppl/src/SimulatedAnnealing.h +++ b/src/ppl/src/SimulatedAnnealing.h @@ -121,6 +121,10 @@ class SimulatedAnnealing int getSlotIdxByPosition(const odb::Point& position, int layer) const; bool isFreeForMirrored(int slot_idx, int& mirrored_idx) const; int getMirroredSlotIdx(int slot_idx) const; + void getMirroredSlotRange(int slot_idx1, + int slot_idx2, + int& mirrored_slot1, + int& mirrored_slot2) const; void updateSlotsFromGroup(const std::vector& prev_slots_, bool block); int computeGroupPrevCost(int group_idx); void updateGroupSlots(const std::vector& pin_indices, int& new_slot); diff --git a/src/ppl/src/Slots.h b/src/ppl/src/Slots.h index dfb0b9afa36..b56d38cb9e1 100644 --- a/src/ppl/src/Slots.h +++ b/src/ppl/src/Slots.h @@ -141,6 +141,7 @@ struct Constraint float pins_per_slots; int first_slot = 0; int last_slot = 0; + int mirrored_pins_count = 0; }; template diff --git a/src/ppl/test/add_constraint1.ok b/src/ppl/test/add_constraint1.ok index 66f85f4f051..ec50cd45058 100644 --- a/src/ppl/test/add_constraint1.ok +++ b/src/ppl/test/add_constraint1.ok @@ -4,13 +4,11 @@ [INFO ODB-0131] Created 88 components and 422 component-terminals. [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 1859.88 um. No differences found. diff --git a/src/ppl/test/add_constraint10.ok b/src/ppl/test/add_constraint10.ok index 0725c143724..52f31f110aa 100644 --- a/src/ppl/test/add_constraint10.ok +++ b/src/ppl/test/add_constraint10.ok @@ -4,13 +4,11 @@ [INFO ODB-0131] Created 88 components and 422 component-terminals. [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 2264.07 um. No differences found. diff --git a/src/ppl/test/add_constraint11.ok b/src/ppl/test/add_constraint11.ok index f2d84cd7478..8341c38787a 100644 --- a/src/ppl/test/add_constraint11.ok +++ b/src/ppl/test/add_constraint11.ok @@ -5,13 +5,12 @@ [INFO ODB-0133] Created 54 nets and 88 connections. [INFO PPL-0044] Pin group: [ resp_msg[0] resp_msg[1] clk resp_val resp_rdy ... ] Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 1 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 1684.43 um. No differences found. diff --git a/src/ppl/test/add_constraint12.ok b/src/ppl/test/add_constraint12.ok index e9d3684dc23..75cfc466630 100644 --- a/src/ppl/test/add_constraint12.ok +++ b/src/ppl/test/add_constraint12.ok @@ -6,13 +6,12 @@ [INFO PPL-0044] Pin group: [ resp_msg[3] resp_msg[2] resp_msg[14] req_val ] [INFO PPL-0044] Pin group: [ req_rdy req_msg[10] req_msg[11] req_msg[12] req_msg[13] ... ] Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 2 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 1792.16 um. No differences found. diff --git a/src/ppl/test/add_constraint13.ok b/src/ppl/test/add_constraint13.ok index 1c41668eb9b..3e742e1cb8f 100644 --- a/src/ppl/test/add_constraint13.ok +++ b/src/ppl/test/add_constraint13.ok @@ -6,13 +6,12 @@ [INFO PPL-0044] Pin group: [ resp_msg[3] resp_msg[2] resp_msg[14] req_val ] [INFO PPL-0044] Pin group: [ req_rdy req_msg[10] req_msg[11] req_msg[12] req_msg[13] ... ] Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 2 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 1701.97 um. No differences found. diff --git a/src/ppl/test/add_constraint14.ok b/src/ppl/test/add_constraint14.ok index f2d84cd7478..8341c38787a 100644 --- a/src/ppl/test/add_constraint14.ok +++ b/src/ppl/test/add_constraint14.ok @@ -5,13 +5,12 @@ [INFO ODB-0133] Created 54 nets and 88 connections. [INFO PPL-0044] Pin group: [ resp_msg[0] resp_msg[1] clk resp_val resp_rdy ... ] Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 1 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 1684.43 um. No differences found. diff --git a/src/ppl/test/add_constraint15.ok b/src/ppl/test/add_constraint15.ok index 77efb737bb7..c0683e81520 100644 --- a/src/ppl/test/add_constraint15.ok +++ b/src/ppl/test/add_constraint15.ok @@ -5,13 +5,12 @@ [INFO ODB-0133] Created 54 nets and 88 connections. [INFO PPL-0044] Pin group: [ req_msg[0] req_msg[1] req_msg[2] req_msg[3] req_msg[4] ... ] Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 1008 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 1 [INFO PPL-0005] Slots per section 50 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 3142.75 um. No differences found. diff --git a/src/ppl/test/add_constraint16.ok b/src/ppl/test/add_constraint16.ok index 46905d7395c..494531dcbfd 100644 --- a/src/ppl/test/add_constraint16.ok +++ b/src/ppl/test/add_constraint16.ok @@ -6,13 +6,12 @@ [INFO PPL-0044] Pin group: [ req_msg[0] req_msg[1] req_msg[2] req_msg[3] req_msg[4] ... ] [INFO PPL-0044] Pin group: [ resp_msg[0] resp_msg[1] resp_msg[2] resp_msg[3] resp_msg[4] ... ] Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 1008 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 2 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 4029.59 um. No differences found. diff --git a/src/ppl/test/add_constraint2.ok b/src/ppl/test/add_constraint2.ok index d60ac3a3ea9..8369ed9172a 100644 --- a/src/ppl/test/add_constraint2.ok +++ b/src/ppl/test/add_constraint2.ok @@ -4,13 +4,11 @@ [INFO ODB-0131] Created 88 components and 422 component-terminals. [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 2367.05 um. No differences found. diff --git a/src/ppl/test/add_constraint3.ok b/src/ppl/test/add_constraint3.ok index d55f72fcdd4..8ec19637c92 100644 --- a/src/ppl/test/add_constraint3.ok +++ b/src/ppl/test/add_constraint3.ok @@ -4,13 +4,11 @@ [INFO ODB-0131] Created 88 components and 422 component-terminals. [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 2137.10 um. No differences found. diff --git a/src/ppl/test/add_constraint4.ok b/src/ppl/test/add_constraint4.ok index 221f8414705..545ced0db10 100644 --- a/src/ppl/test/add_constraint4.ok +++ b/src/ppl/test/add_constraint4.ok @@ -4,13 +4,11 @@ [INFO ODB-0131] Created 88 components and 422 component-terminals. [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 2077.04 um. No differences found. diff --git a/src/ppl/test/add_constraint8.ok b/src/ppl/test/add_constraint8.ok index 6bbda8c8c25..1535c65be97 100644 --- a/src/ppl/test/add_constraint8.ok +++ b/src/ppl/test/add_constraint8.ok @@ -5,13 +5,11 @@ [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. Using 2 tracks default min distance between IO pins. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 1228 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 4461.19 um. No differences found. diff --git a/src/ppl/test/add_constraint9.ok b/src/ppl/test/add_constraint9.ok index 40e08f0ce1d..6a1c38fe494 100644 --- a/src/ppl/test/add_constraint9.ok +++ b/src/ppl/test/add_constraint9.ok @@ -4,13 +4,11 @@ [INFO ODB-0131] Created 88 components and 422 component-terminals. [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 987.97 um. No differences found. diff --git a/src/ppl/test/add_constraint_debug.ok b/src/ppl/test/add_constraint_debug.ok index 506fb00a6fe..9f339f10960 100644 --- a/src/ppl/test/add_constraint_debug.ok +++ b/src/ppl/test/add_constraint_debug.ok @@ -8,13 +8,12 @@ [DEBUG PPL-pin_groups] Restrict pins [ resp_msg[15] resp_msg[14] resp_msg[13] resp_msg[12] resp_msg[11] resp_msg[10] resp_msg[9] resp_msg[8] resp_msg[7] resp_msg[6] resp_msg[5] resp_msg[4] resp_msg[3] resp_msg[2] resp_msg[1] resp_msg[0] ] to region 0.00u-100.13u at the BOTTOM edge. [DEBUG PPL-pin_groups] Pin group: [ resp_msg[0] resp_msg[1] resp_msg[2] resp_msg[3] resp_msg[4] resp_msg[5] resp_msg[6] resp_msg[7] resp_msg[8] resp_msg[9] resp_msg[10] resp_msg[11] resp_msg[12] resp_msg[13] resp_msg[14] resp_msg[15] ] Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 1008 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 2 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 4029.59 um. No differences found. diff --git a/src/ppl/test/annealing2.ok b/src/ppl/test/annealing2.ok index 924c89dbb21..1ecc8744eea 100644 --- a/src/ppl/test/annealing2.ok +++ b/src/ppl/test/annealing2.ok @@ -11,5 +11,6 @@ Using 2 tracks default min distance between IO pins. [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 2 [INFO PPL-0012] I/O nets HPWL: 1960.63 um. No differences found. diff --git a/src/ppl/test/annealing_constraint6.ok b/src/ppl/test/annealing_constraint6.ok index 0a704178dd9..15b9baf77c8 100644 --- a/src/ppl/test/annealing_constraint6.ok +++ b/src/ppl/test/annealing_constraint6.ok @@ -10,5 +10,6 @@ Found 0 macro blocks. [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 2 [INFO PPL-0012] I/O nets HPWL: 4475.54 um. No differences found. diff --git a/src/ppl/test/annealing_constraint7.ok b/src/ppl/test/annealing_constraint7.ok index 8897a4e3dda..fcd65a07349 100644 --- a/src/ppl/test/annealing_constraint7.ok +++ b/src/ppl/test/annealing_constraint7.ok @@ -10,5 +10,6 @@ Found 0 macro blocks. [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 2 [INFO PPL-0012] I/O nets HPWL: 4088.62 um. No differences found. diff --git a/src/ppl/test/annealing_large_groups1.ok b/src/ppl/test/annealing_large_groups1.ok index f43a75ce648..9172f51790f 100644 --- a/src/ppl/test/annealing_large_groups1.ok +++ b/src/ppl/test/annealing_large_groups1.ok @@ -10,5 +10,6 @@ Found 0 macro blocks. [INFO PPL-0002] Number of I/O 400 [INFO PPL-0003] Number of I/O w/sink 400 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 2 [INFO PPL-0012] I/O nets HPWL: 17121.63 um. No differences found. diff --git a/src/ppl/test/annealing_large_groups2.ok b/src/ppl/test/annealing_large_groups2.ok index 6b7fcf24184..3084c20dfc8 100644 --- a/src/ppl/test/annealing_large_groups2.ok +++ b/src/ppl/test/annealing_large_groups2.ok @@ -9,5 +9,6 @@ Found 0 macro blocks. [INFO PPL-0002] Number of I/O 400 [INFO PPL-0003] Number of I/O w/sink 400 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 1 [INFO PPL-0012] I/O nets HPWL: 17114.00 um. No differences found. diff --git a/src/ppl/test/annealing_mirrored4.ok b/src/ppl/test/annealing_mirrored4.ok index a8a80b2354c..7757c541bd8 100644 --- a/src/ppl/test/annealing_mirrored4.ok +++ b/src/ppl/test/annealing_mirrored4.ok @@ -9,5 +9,6 @@ Found 0 macro blocks. [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 1 [INFO PPL-0012] I/O nets HPWL: 5091.84 um. No differences found. diff --git a/src/ppl/test/annealing_mirrored5.ok b/src/ppl/test/annealing_mirrored5.ok index b20acbfc3ba..94f087d078f 100644 --- a/src/ppl/test/annealing_mirrored5.ok +++ b/src/ppl/test/annealing_mirrored5.ok @@ -9,5 +9,6 @@ Found 0 macro blocks. [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 1 [INFO PPL-0012] I/O nets HPWL: 2487.34 um. No differences found. diff --git a/src/ppl/test/cells_not_placed.ok b/src/ppl/test/cells_not_placed.ok index f15b72209b0..8f877723591 100644 --- a/src/ppl/test/cells_not_placed.ok +++ b/src/ppl/test/cells_not_placed.ok @@ -5,13 +5,11 @@ [INFO ODB-0133] Created 54 nets and 164 connections. Found 0 macro blocks. Using 2 tracks default min distance between IO pins. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 1228 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 2875.50 um. No differences found. diff --git a/src/ppl/test/exclude1.ok b/src/ppl/test/exclude1.ok index 63b79baa56c..467fddfd402 100644 --- a/src/ppl/test/exclude1.ok +++ b/src/ppl/test/exclude1.ok @@ -4,13 +4,11 @@ [INFO ODB-0131] Created 88 components and 422 component-terminals. [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 1138.67 um. No differences found. diff --git a/src/ppl/test/exclude2.ok b/src/ppl/test/exclude2.ok index e498c6967a1..549217706b7 100644 --- a/src/ppl/test/exclude2.ok +++ b/src/ppl/test/exclude2.ok @@ -4,13 +4,11 @@ [INFO ODB-0131] Created 88 components and 422 component-terminals. [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 1174.14 um. No differences found. diff --git a/src/ppl/test/exclude3.ok b/src/ppl/test/exclude3.ok index bff76931274..3fe9d0b12f3 100644 --- a/src/ppl/test/exclude3.ok +++ b/src/ppl/test/exclude3.ok @@ -4,13 +4,11 @@ [INFO ODB-0131] Created 88 components and 422 component-terminals. [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 1101.65 um. No differences found. diff --git a/src/ppl/test/gcd.ok b/src/ppl/test/gcd.ok index 2ee53646c64..d0932930642 100644 --- a/src/ppl/test/gcd.ok +++ b/src/ppl/test/gcd.ok @@ -4,13 +4,11 @@ [INFO ODB-0131] Created 88 components and 422 component-terminals. [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 754.58 um. No differences found. diff --git a/src/ppl/test/group_pins1.ok b/src/ppl/test/group_pins1.ok index 0cbef1edcca..345fc59766e 100644 --- a/src/ppl/test/group_pins1.ok +++ b/src/ppl/test/group_pins1.ok @@ -6,13 +6,12 @@ Found 0 macro blocks. [INFO PPL-0044] Pin group: [ resp_val resp_rdy req_rdy ] [INFO PPL-0044] Pin group: [ req_msg[15] req_msg[14] resp_msg[15] resp_msg[14] ] -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 2 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 1052.16 um. No differences found. diff --git a/src/ppl/test/group_pins10.ok b/src/ppl/test/group_pins10.ok index af6a21f55f4..107d90eb8a9 100644 --- a/src/ppl/test/group_pins10.ok +++ b/src/ppl/test/group_pins10.ok @@ -7,13 +7,12 @@ [INFO PPL-0044] Pin group: [ clk ] Found 0 macro blocks. Using 2 tracks default min distance between IO pins. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 1228 [INFO PPL-0002] Number of I/O 103 [INFO PPL-0003] Number of I/O w/sink 103 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 2 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 4545.02 um. No differences found. diff --git a/src/ppl/test/group_pins2.ok b/src/ppl/test/group_pins2.ok index b52e0cc273a..4fcdd81dac6 100644 --- a/src/ppl/test/group_pins2.ok +++ b/src/ppl/test/group_pins2.ok @@ -5,13 +5,12 @@ [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. [INFO PPL-0044] Pin group: [ clk req_msg[31] req_msg[30] req_msg[29] req_msg[28] ... ] -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 1 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 1513.35 um. No differences found. diff --git a/src/ppl/test/group_pins3.ok b/src/ppl/test/group_pins3.ok index 0d1945e20ac..5e300f6b755 100644 --- a/src/ppl/test/group_pins3.ok +++ b/src/ppl/test/group_pins3.ok @@ -8,13 +8,12 @@ Found 0 macro blocks. [INFO PPL-0044] Pin group: [ req_msg[24] req_msg[25] req_msg[26] req_msg[27] req_msg[28] ... ] [INFO PPL-0044] Pin group: [ clk req_rdy req_val reset resp_msg[0] ... ] [INFO PPL-0044] Pin group: [ resp_rdy resp_val resp_msg[1] resp_msg[2] resp_msg[3] ... ] -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 552 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 4 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 2442.02 um. No differences found. diff --git a/src/ppl/test/group_pins4.ok b/src/ppl/test/group_pins4.ok index 113fea1ce1c..06c88d31f98 100644 --- a/src/ppl/test/group_pins4.ok +++ b/src/ppl/test/group_pins4.ok @@ -8,13 +8,12 @@ Found 0 macro blocks. [INFO PPL-0044] Pin group: [ req_msg[24] req_msg[25] req_msg[26] req_msg[27] req_msg[28] ... ] [INFO PPL-0044] Pin group: [ clk req_rdy req_val reset resp_msg[0] ... ] [INFO PPL-0044] Pin group: [ resp_rdy resp_val resp_msg[1] resp_msg[2] resp_msg[3] ... ] -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 552 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 4 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 2455.38 um. No differences found. diff --git a/src/ppl/test/group_pins5.ok b/src/ppl/test/group_pins5.ok index 7afcbed5a8e..12530deb96d 100644 --- a/src/ppl/test/group_pins5.ok +++ b/src/ppl/test/group_pins5.ok @@ -8,13 +8,12 @@ Found 0 macro blocks. [INFO PPL-0044] Pin group: [ req_msg[24] req_msg[25] req_msg[26] req_msg[27] req_msg[28] ... ] [INFO PPL-0044] Pin group: [ clk req_rdy req_val reset resp_msg[0] ... ] [INFO PPL-0044] Pin group: [ resp_rdy resp_val resp_msg[1] resp_msg[2] resp_msg[3] ... ] -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 1248 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 4 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 2430.76 um. No differences found. diff --git a/src/ppl/test/group_pins6.ok b/src/ppl/test/group_pins6.ok index 1d36507a962..f73a1041958 100644 --- a/src/ppl/test/group_pins6.ok +++ b/src/ppl/test/group_pins6.ok @@ -8,13 +8,12 @@ Found 0 macro blocks. [INFO PPL-0044] Pin group: [ req_msg[24] req_msg[25] req_msg[26] req_msg[27] req_msg[28] ... ] [INFO PPL-0044] Pin group: [ clk req_rdy req_val reset resp_msg[0] ... ] [INFO PPL-0044] Pin group: [ resp_rdy resp_val resp_msg[1] resp_msg[2] resp_msg[3] ... ] -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 1248 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 4 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 2447.86 um. No differences found. diff --git a/src/ppl/test/group_pins7.ok b/src/ppl/test/group_pins7.ok index 7afcbed5a8e..12530deb96d 100644 --- a/src/ppl/test/group_pins7.ok +++ b/src/ppl/test/group_pins7.ok @@ -8,13 +8,12 @@ Found 0 macro blocks. [INFO PPL-0044] Pin group: [ req_msg[24] req_msg[25] req_msg[26] req_msg[27] req_msg[28] ... ] [INFO PPL-0044] Pin group: [ clk req_rdy req_val reset resp_msg[0] ... ] [INFO PPL-0044] Pin group: [ resp_rdy resp_val resp_msg[1] resp_msg[2] resp_msg[3] ... ] -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 1248 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 4 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 2430.76 um. No differences found. diff --git a/src/ppl/test/group_pins8.ok b/src/ppl/test/group_pins8.ok index c31c225df7f..42fcc9593a9 100644 --- a/src/ppl/test/group_pins8.ok +++ b/src/ppl/test/group_pins8.ok @@ -6,13 +6,12 @@ [INFO PPL-0044] Pin group: [ resp_val resp_rdy req_rdy ] [INFO PPL-0044] Pin group: [ req_msg[15] req_msg[14] resp_msg[15] resp_msg[14] ] Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 2 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 1052.16 um. No differences found. diff --git a/src/ppl/test/group_pins9.ok b/src/ppl/test/group_pins9.ok index 463e63cb3dc..044b0a9e21d 100644 --- a/src/ppl/test/group_pins9.ok +++ b/src/ppl/test/group_pins9.ok @@ -6,13 +6,12 @@ [INFO PPL-0044] Pin group: [ resp_val resp_rdy req_rdy ] [INFO PPL-0044] Pin group: [ req_msg[15] req_msg[14] resp_msg[15] resp_msg[14] ] Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 2 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 1052.72 um. No differences found. diff --git a/src/ppl/test/group_pins_warn1.ok b/src/ppl/test/group_pins_warn1.ok index 25258dc76ef..38c752a0e55 100644 --- a/src/ppl/test/group_pins_warn1.ok +++ b/src/ppl/test/group_pins_warn1.ok @@ -7,13 +7,12 @@ Found 0 macro blocks. [INFO PPL-0044] Pin group: [ resp_val resp_rdy req_rdy ] [WARNING PPL-0043] Pin resp_msg[141] not found in group 1. [INFO PPL-0044] Pin group: [ req_msg[15] req_msg[14] resp_msg[15] ] -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 2 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 998.27 um. No differences found. diff --git a/src/ppl/test/large_groups1.ok b/src/ppl/test/large_groups1.ok index 4f695a33c32..40e2ed3eecf 100644 --- a/src/ppl/test/large_groups1.ok +++ b/src/ppl/test/large_groups1.ok @@ -6,14 +6,13 @@ [INFO PPL-0044] Pin group: [ pin0 pin1 pin2 pin3 pin4 ... ] [INFO PPL-0044] Pin group: [ pin256 pin257 pin258 pin259 pin260 ... ] Found 0 macro blocks. -[INFO PPL-0100] Group of size 256 placed during fallback mode. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 400 [INFO PPL-0003] Number of I/O w/sink 400 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 2 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 +[INFO PPL-0100] Group of size 256 placed during fallback mode. [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 22453.78 um. No differences found. diff --git a/src/ppl/test/large_groups2.ok b/src/ppl/test/large_groups2.ok index 24d8d938f06..2d3fb081453 100644 --- a/src/ppl/test/large_groups2.ok +++ b/src/ppl/test/large_groups2.ok @@ -5,14 +5,13 @@ [INFO ODB-0133] Created 1 nets and 1 connections. [INFO PPL-0044] Pin group: [ pin0 pin1 pin2 pin3 pin4 ... ] Found 0 macro blocks. -[INFO PPL-0100] Group of size 400 placed during fallback mode. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 400 [INFO PPL-0003] Number of I/O w/sink 400 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 1 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 +[INFO PPL-0100] Group of size 400 placed during fallback mode. [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 29640.88 um. No differences found. diff --git a/src/ppl/test/large_groups3.ok b/src/ppl/test/large_groups3.ok index 57693308c25..13cd23ecf2e 100644 --- a/src/ppl/test/large_groups3.ok +++ b/src/ppl/test/large_groups3.ok @@ -6,6 +6,12 @@ [INFO PPL-0044] Pin group: [ pin0 pin1 pin2 pin3 pin4 ... ] [INFO PPL-0044] Pin group: [ pin300 pin301 pin302 pin303 pin304 ... ] Found 0 macro blocks. +[INFO PPL-0001] Number of slots 1754 +[INFO PPL-0002] Number of I/O 400 +[INFO PPL-0003] Number of I/O w/sink 400 +[INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 2 +[INFO PPL-0005] Slots per section 200 [INFO PPL-0100] Group of size 300 placed during fallback mode. [WARNING PPL-0078] Not enough available positions (36) in section (47.215, 100.8)-(14.915, 100.8) at edge TOP to place the pin group of size 71. [WARNING PPL-0078] Not enough available positions (35) in section (85.215, 100.8)-(47.405, 100.8) at edge TOP to place the pin group of size 71. diff --git a/src/ppl/test/large_groups4.ok b/src/ppl/test/large_groups4.ok index 6d0eae7769d..7c089d9db3e 100644 --- a/src/ppl/test/large_groups4.ok +++ b/src/ppl/test/large_groups4.ok @@ -6,14 +6,13 @@ [INFO PPL-0044] Pin group: [ pin0 pin1 pin2 pin3 pin4 ... ] [INFO PPL-0044] Pin group: [ pin300 pin301 pin302 pin303 pin304 ... ] Found 0 macro blocks. -[INFO PPL-0100] Group of size 300 placed during fallback mode. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 1754 [INFO PPL-0002] Number of I/O 400 [INFO PPL-0003] Number of I/O w/sink 400 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 2 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 +[INFO PPL-0100] Group of size 300 placed during fallback mode. [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 25867.56 um. No differences found. diff --git a/src/ppl/test/macro_not_placed.ok b/src/ppl/test/macro_not_placed.ok index 50c19b07514..24c0a61ff50 100644 --- a/src/ppl/test/macro_not_placed.ok +++ b/src/ppl/test/macro_not_placed.ok @@ -10,12 +10,10 @@ [WARNING PPL-0015] Macro macro_nop_0_ is not placed. Found 0 macro blocks. Using 2 tracks default min distance between IO pins. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 1016 [INFO PPL-0002] Number of I/O 52 [INFO PPL-0003] Number of I/O w/sink 52 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 8198.32 um. diff --git a/src/ppl/test/min_dist_in_tracks1.ok b/src/ppl/test/min_dist_in_tracks1.ok index 2ee53646c64..d0932930642 100644 --- a/src/ppl/test/min_dist_in_tracks1.ok +++ b/src/ppl/test/min_dist_in_tracks1.ok @@ -4,13 +4,11 @@ [INFO ODB-0131] Created 88 components and 422 component-terminals. [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 754.58 um. No differences found. diff --git a/src/ppl/test/min_dist_in_tracks2.ok b/src/ppl/test/min_dist_in_tracks2.ok index 8318d6b45e1..ff3edd5dcfe 100644 --- a/src/ppl/test/min_dist_in_tracks2.ok +++ b/src/ppl/test/min_dist_in_tracks2.ok @@ -4,13 +4,11 @@ [INFO ODB-0131] Created 88 components and 422 component-terminals. [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 832 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 849.38 um. No differences found. diff --git a/src/ppl/test/multi_layers.ok b/src/ppl/test/multi_layers.ok index 1d881158220..dfb5e674742 100644 --- a/src/ppl/test/multi_layers.ok +++ b/src/ppl/test/multi_layers.ok @@ -4,13 +4,11 @@ [INFO ODB-0131] Created 88 components and 422 component-terminals. [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 3930 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 751.32 um. No differences found. diff --git a/src/ppl/test/multiple_calls.ok b/src/ppl/test/multiple_calls.ok index 2c37cd37364..ad830b0b9f5 100644 --- a/src/ppl/test/multiple_calls.ok +++ b/src/ppl/test/multiple_calls.ok @@ -4,23 +4,19 @@ [INFO ODB-0131] Created 88 components and 422 component-terminals. [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 754.58 um. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 754.58 um. No differences found. diff --git a/src/ppl/test/no_instance_pins.ok b/src/ppl/test/no_instance_pins.ok index 06b373de719..efc9d08cdad 100644 --- a/src/ppl/test/no_instance_pins.ok +++ b/src/ppl/test/no_instance_pins.ok @@ -3,13 +3,11 @@ [INFO ODB-0130] Created 10 pins. [INFO ODB-0133] Created 10 nets and 0 connections. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 10 [INFO PPL-0003] Number of I/O w/sink 0 [INFO PPL-0004] Number of I/O w/o sink 10 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 0.00 um. No differences found. diff --git a/src/ppl/test/on_grid.ok b/src/ppl/test/on_grid.ok index 378d827921d..f2572eb2bb1 100644 --- a/src/ppl/test/on_grid.ok +++ b/src/ppl/test/on_grid.ok @@ -6,13 +6,11 @@ [INFO ODB-0133] Created 54 nets and 143 connections. Found 0 macro blocks. Using 2 tracks default min distance between IO pins. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 1016 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 6307.26 um. No differences found. diff --git a/src/ppl/test/pin_extension.ok b/src/ppl/test/pin_extension.ok index 2ee53646c64..d0932930642 100644 --- a/src/ppl/test/pin_extension.ok +++ b/src/ppl/test/pin_extension.ok @@ -4,13 +4,11 @@ [INFO ODB-0131] Created 88 components and 422 component-terminals. [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 754.58 um. No differences found. diff --git a/src/ppl/test/pin_length.ok b/src/ppl/test/pin_length.ok index 2ee53646c64..d0932930642 100644 --- a/src/ppl/test/pin_length.ok +++ b/src/ppl/test/pin_length.ok @@ -4,13 +4,11 @@ [INFO ODB-0131] Created 88 components and 422 component-terminals. [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 754.58 um. No differences found. diff --git a/src/ppl/test/pin_length_error.ok b/src/ppl/test/pin_length_error.ok index 896b4dcc743..a4b650325d5 100644 --- a/src/ppl/test/pin_length_error.ok +++ b/src/ppl/test/pin_length_error.ok @@ -6,13 +6,11 @@ [INFO ODB-0133] Created 54 nets and 143 connections. Found 0 macro blocks. Using 2 tracks default min distance between IO pins. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 1016 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [ERROR PPL-0079] Pin req_msg[19] area 0.0140um^2 is lesser than the minimum required area 0.0676um^2. PPL-0079 diff --git a/src/ppl/test/pin_thick_multiplier.ok b/src/ppl/test/pin_thick_multiplier.ok index 1af711ed2cb..b88e92826da 100644 --- a/src/ppl/test/pin_thick_multiplier.ok +++ b/src/ppl/test/pin_thick_multiplier.ok @@ -4,13 +4,11 @@ [INFO ODB-0131] Created 88 components and 422 component-terminals. [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2486 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 754.96 um. No differences found. diff --git a/src/ppl/test/place_pin1.ok b/src/ppl/test/place_pin1.ok index aa8f9c32692..a5db3ce094f 100644 --- a/src/ppl/test/place_pin1.ok +++ b/src/ppl/test/place_pin1.ok @@ -5,13 +5,11 @@ [INFO ODB-0133] Created 54 nets and 88 connections. [INFO PPL-0070] Pin clk placed at (40.00um, 30.00um). Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 53 [INFO PPL-0003] Number of I/O w/sink 53 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 627.33 um. No differences found. diff --git a/src/ppl/test/place_pin2.ok b/src/ppl/test/place_pin2.ok index a7cc520aa66..a38d0bf4618 100644 --- a/src/ppl/test/place_pin2.ok +++ b/src/ppl/test/place_pin2.ok @@ -7,13 +7,11 @@ [INFO PPL-0070] Pin resp_val placed at (12.00um, 50.00um). [INFO PPL-0070] Pin req_msg[0] placed at (25.00um, 70.00um). Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 51 [INFO PPL-0003] Number of I/O w/sink 51 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 603.14 um. No differences found. diff --git a/src/ppl/test/place_pin3.ok b/src/ppl/test/place_pin3.ok index 9d11e64135f..743cf0ef83b 100644 --- a/src/ppl/test/place_pin3.ok +++ b/src/ppl/test/place_pin3.ok @@ -5,13 +5,11 @@ [INFO ODB-0133] Created 54 nets and 88 connections. [INFO PPL-0070] Pin clk placed at (0.80um, 29.67um). Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 53 [INFO PPL-0003] Number of I/O w/sink 53 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 627.33 um. No differences found. diff --git a/src/ppl/test/place_pin4.ok b/src/ppl/test/place_pin4.ok index 899c58ac262..de07e7c5032 100644 --- a/src/ppl/test/place_pin4.ok +++ b/src/ppl/test/place_pin4.ok @@ -7,13 +7,11 @@ [INFO PPL-0070] Pin resp_val placed at (12.13um, 1.00um). [INFO PPL-0070] Pin req_msg[0] placed at (25.70um, 98.80um). Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 51 [INFO PPL-0003] Number of I/O w/sink 51 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 603.14 um. No differences found. diff --git a/src/ppl/test/place_pin5.ok b/src/ppl/test/place_pin5.ok index b5c84bbabdf..19ed3702c65 100644 --- a/src/ppl/test/place_pin5.ok +++ b/src/ppl/test/place_pin5.ok @@ -7,13 +7,11 @@ [INFO PPL-0070] Pin resp_val placed at (0.80um, 32.87um). [INFO PPL-0070] Pin req_val placed at (0.80um, 26.47um). Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0002] Number of I/O 51 [INFO PPL-0003] Number of I/O w/sink 51 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 603.57 um. No differences found. diff --git a/src/ppl/test/ppl_aux.py b/src/ppl/test/ppl_aux.py index 0b5a775660b..4a215a26b08 100644 --- a/src/ppl/test/ppl_aux.py +++ b/src/ppl/test/ppl_aux.py @@ -230,7 +230,7 @@ def place_pins( design.getIOPlacer().addPinGroup(pin_list, False) group_idx += 1 - design.getIOPlacer().run(random) + design.getIOPlacer().runHungarianMatching(random) def place_pin( diff --git a/src/ppl/test/random5.defok b/src/ppl/test/random5.defok index 3bab6c24ec6..a3ba210ce7e 100644 --- a/src/ppl/test/random5.defok +++ b/src/ppl/test/random5.defok @@ -118,7 +118,7 @@ PINS 54 ; - clk + NET clk + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 153600 163200 ) N ; + + PLACED ( 153600 9600 ) N ; - req_msg[0] + NET req_msg[0] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal3 ( -70 -70 ) ( 70 70 ) @@ -250,7 +250,7 @@ PINS 54 ; - req_rdy + NET req_rdy + DIRECTION OUTPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 38400 38400 ) N ; + + PLACED ( 38400 9600 ) N ; - req_val + NET req_val + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) @@ -258,7 +258,7 @@ PINS 54 ; - reset + NET reset + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 124800 134400 ) N ; + + PLACED ( 124800 9600 ) N ; - resp_msg[0] + NET resp_msg[0] + DIRECTION OUTPUT + USE SIGNAL + PORT + LAYER metal3 ( -70 -70 ) ( 70 70 ) @@ -326,11 +326,11 @@ PINS 54 ; - resp_rdy + NET resp_rdy + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 96000 105600 ) N ; + + PLACED ( 96000 9600 ) N ; - resp_val + NET resp_val + DIRECTION OUTPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 67200 67200 ) N ; + + PLACED ( 67200 9600 ) N ; END PINS NETS 54 ; - clk ( PIN clk ) ( _858_ CK ) ( _859_ CK ) ( _860_ CK ) ( _861_ CK ) ( _862_ CK ) ( _863_ CK ) diff --git a/src/ppl/test/random6.defok b/src/ppl/test/random6.defok index 497a5f176c9..9ad3718ec42 100644 --- a/src/ppl/test/random6.defok +++ b/src/ppl/test/random6.defok @@ -118,135 +118,135 @@ PINS 54 ; - clk + NET clk + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 153600 96000 ) N ; + + PLACED ( 144000 124800 ) N ; - req_msg[0] + NET req_msg[0] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 9600 76800 ) N ; + + PLACED ( 9600 67200 ) N ; - req_msg[10] + NET req_msg[10] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 48000 182400 ) N ; + + PLACED ( 48000 124800 ) N ; - req_msg[11] + NET req_msg[11] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 153600 28800 ) N ; + + PLACED ( 144000 67200 ) N ; - req_msg[12] + NET req_msg[12] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 48000 48000 ) N ; + + PLACED ( 48000 9600 ) N ; - req_msg[13] + NET req_msg[13] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 38400 105600 ) N ; + + PLACED ( 38400 67200 ) N ; - req_msg[14] + NET req_msg[14] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 96000 28800 ) N ; + + PLACED ( 86400 124800 ) N ; - req_msg[15] + NET req_msg[15] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 153600 163200 ) N ; + + PLACED ( 153600 9600 ) N ; - req_msg[16] + NET req_msg[16] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 144000 19200 ) N ; + + PLACED ( 134400 67200 ) N ; - req_msg[17] + NET req_msg[17] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 86400 19200 ) N ; + + PLACED ( 76800 124800 ) N ; - req_msg[18] + NET req_msg[18] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 57600 192000 ) N ; + + PLACED ( 57600 124800 ) N ; - req_msg[19] + NET req_msg[19] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 28800 163200 ) N ; + + PLACED ( 28800 124800 ) N ; - req_msg[1] + NET req_msg[1] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 105600 182400 ) N ; + + PLACED ( 105600 67200 ) N ; - req_msg[20] + NET req_msg[20] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 163200 38400 ) N ; + + PLACED ( 153600 67200 ) N ; - req_msg[21] + NET req_msg[21] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 115200 57600 ) N ; + + PLACED ( 105600 124800 ) N ; - req_msg[22] + NET req_msg[22] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 57600 124800 ) N ; + + PLACED ( 57600 67200 ) N ; - req_msg[23] + NET req_msg[23] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 144000 86400 ) N ; + + PLACED ( 134400 124800 ) N ; - req_msg[24] + NET req_msg[24] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 163200 172800 ) N ; + + PLACED ( 163200 9600 ) N ; - req_msg[25] + NET req_msg[25] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 172800 115200 ) N ; + + PLACED ( 163200 124800 ) N ; - req_msg[26] + NET req_msg[26] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 38400 172800 ) N ; + + PLACED ( 38400 124800 ) N ; - req_msg[27] + NET req_msg[27] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 105600 115200 ) N ; + + PLACED ( 105600 9600 ) N ; - req_msg[28] + NET req_msg[28] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 67200 134400 ) N ; + + PLACED ( 67200 67200 ) N ; - req_msg[29] + NET req_msg[29] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 19200 19200 ) N ; + + PLACED ( 19200 9600 ) N ; - req_msg[2] + NET req_msg[2] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 134400 144000 ) N ; + + PLACED ( 134400 9600 ) N ; - req_msg[30] + NET req_msg[30] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 76800 76800 ) N ; + + PLACED ( 76800 9600 ) N ; - req_msg[31] + NET req_msg[31] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 57600 57600 ) N ; + + PLACED ( 57600 9600 ) N ; - req_msg[3] + NET req_msg[3] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 86400 86400 ) N ; + + PLACED ( 86400 9600 ) N ; - req_msg[4] + NET req_msg[4] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 96000 105600 ) N ; + + PLACED ( 96000 9600 ) N ; - req_msg[5] + NET req_msg[5] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 172800 182400 ) N ; + + PLACED ( 172800 9600 ) N ; - req_msg[6] + NET req_msg[6] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 115200 124800 ) N ; + + PLACED ( 115200 9600 ) N ; - req_msg[7] + NET req_msg[7] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 182400 57600 ) N ; + + PLACED ( 172800 67200 ) N ; - req_msg[8] + NET req_msg[8] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 105600 48000 ) N ; + + PLACED ( 96000 124800 ) N ; - req_msg[9] + NET req_msg[9] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 124800 67200 ) N ; + + PLACED ( 115200 124800 ) N ; - req_rdy + NET req_rdy + DIRECTION OUTPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) @@ -254,83 +254,83 @@ PINS 54 ; - req_val + NET req_val + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 134400 9600 ) N ; + + PLACED ( 124800 67200 ) N ; - reset + NET reset + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 86400 153600 ) N ; + + PLACED ( 86400 67200 ) N ; - resp_msg[0] + NET resp_msg[0] + DIRECTION OUTPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 172800 48000 ) N ; + + PLACED ( 163200 67200 ) N ; - resp_msg[10] + NET resp_msg[10] + DIRECTION OUTPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 9600 144000 ) N ; + + PLACED ( 9600 124800 ) N ; - resp_msg[11] + NET resp_msg[11] + DIRECTION OUTPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 67200 67200 ) N ; + + PLACED ( 67200 9600 ) N ; - resp_msg[12] + NET resp_msg[12] + DIRECTION OUTPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 115200 192000 ) N ; + + PLACED ( 115200 67200 ) N ; - resp_msg[13] + NET resp_msg[13] + DIRECTION OUTPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 48000 115200 ) N ; + + PLACED ( 48000 67200 ) N ; - resp_msg[14] + NET resp_msg[14] + DIRECTION OUTPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 76800 144000 ) N ; + + PLACED ( 76800 67200 ) N ; - resp_msg[15] + NET resp_msg[15] + DIRECTION OUTPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 19200 153600 ) N ; + + PLACED ( 19200 124800 ) N ; - resp_msg[1] + NET resp_msg[1] + DIRECTION OUTPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 38400 38400 ) N ; + + PLACED ( 38400 9600 ) N ; - resp_msg[2] + NET resp_msg[2] + DIRECTION OUTPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 124800 134400 ) N ; + + PLACED ( 124800 9600 ) N ; - resp_msg[3] + NET resp_msg[3] + DIRECTION OUTPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 134400 76800 ) N ; + + PLACED ( 124800 124800 ) N ; - resp_msg[4] + NET resp_msg[4] + DIRECTION OUTPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 96000 172800 ) N ; + + PLACED ( 96000 67200 ) N ; - resp_msg[5] + NET resp_msg[5] + DIRECTION OUTPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 163200 105600 ) N ; + + PLACED ( 153600 124800 ) N ; - resp_msg[6] + NET resp_msg[6] + DIRECTION OUTPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 28800 96000 ) N ; + + PLACED ( 28800 67200 ) N ; - resp_msg[7] + NET resp_msg[7] + DIRECTION OUTPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 182400 124800 ) N ; + + PLACED ( 172800 124800 ) N ; - resp_msg[8] + NET resp_msg[8] + DIRECTION OUTPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 28800 28800 ) N ; + + PLACED ( 28800 9600 ) N ; - resp_msg[9] + NET resp_msg[9] + DIRECTION OUTPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 19200 86400 ) N ; + + PLACED ( 19200 67200 ) N ; - resp_rdy + NET resp_rdy + DIRECTION INPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 144000 153600 ) N ; + + PLACED ( 144000 9600 ) N ; - resp_val + NET resp_val + DIRECTION OUTPUT + USE SIGNAL + PORT + LAYER metal10 ( -1600 -2500 ) ( 1600 2500 ) - + PLACED ( 76800 9600 ) N ; + + PLACED ( 67200 124800 ) N ; END PINS NETS 54 ; - clk ( PIN clk ) ( _858_ CK ) ( _859_ CK ) ( _860_ CK ) ( _861_ CK ) ( _862_ CK ) ( _863_ CK ) diff --git a/src/ppl/test/top_layer1.ok b/src/ppl/test/top_layer1.ok index a800440b9ca..2c7e2fe7337 100644 --- a/src/ppl/test/top_layer1.ok +++ b/src/ppl/test/top_layer1.ok @@ -7,14 +7,12 @@ [INFO ODB-0133] Created 54 nets and 155 connections. Found 1 macro blocks. Using 2 tracks default min distance between IO pins. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 1016 [INFO PPL-0062] Number of top layer slots 900 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 7573.08 um. No differences found. diff --git a/src/ppl/test/top_layer2.ok b/src/ppl/test/top_layer2.ok index c2e7e7f8e44..f8c52739f16 100644 --- a/src/ppl/test/top_layer2.ok +++ b/src/ppl/test/top_layer2.ok @@ -7,14 +7,12 @@ [INFO ODB-0133] Created 54 nets and 155 connections. Found 1 macro blocks. Using 2 tracks default min distance between IO pins. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 1016 [INFO PPL-0062] Number of top layer slots 900 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 8196.93 um. No differences found. diff --git a/src/ppl/test/top_layer3.ok b/src/ppl/test/top_layer3.ok index 440e9de5622..e49bfff5894 100644 --- a/src/ppl/test/top_layer3.ok +++ b/src/ppl/test/top_layer3.ok @@ -4,14 +4,12 @@ [INFO ODB-0131] Created 88 components and 422 component-terminals. [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0062] Number of top layer slots 361 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 946.95 um. No differences found. diff --git a/src/ppl/test/top_layer4.ok b/src/ppl/test/top_layer4.ok index 839da520ff3..98df54a4b3a 100644 --- a/src/ppl/test/top_layer4.ok +++ b/src/ppl/test/top_layer4.ok @@ -4,14 +4,12 @@ [INFO ODB-0131] Created 88 components and 422 component-terminals. [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0062] Number of top layer slots 441 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 336.27 um. No differences found. diff --git a/src/ppl/test/top_layer5.ok b/src/ppl/test/top_layer5.ok index 94300bff7d8..f22b7410663 100644 --- a/src/ppl/test/top_layer5.ok +++ b/src/ppl/test/top_layer5.ok @@ -4,14 +4,12 @@ [INFO ODB-0131] Created 88 components and 422 component-terminals. [INFO ODB-0133] Created 54 nets and 88 connections. Found 0 macro blocks. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 2494 [INFO PPL-0062] Number of top layer slots 441 [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 363.87 um. No differences found. diff --git a/src/ppl/test/write_pin_placement1.ok b/src/ppl/test/write_pin_placement1.ok index 470cc5046b7..044855c61b0 100644 --- a/src/ppl/test/write_pin_placement1.ok +++ b/src/ppl/test/write_pin_placement1.ok @@ -10,6 +10,7 @@ Found 0 macro blocks. [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 2 [INFO PPL-0012] I/O nets HPWL: 4475.54 um. [INFO PPL-0070] Pin clk placed at (42.27um, 0.04um). [INFO PPL-0070] Pin req_msg[31] placed at (59.76um, 0.04um). diff --git a/src/ppl/test/write_pin_placement2.ok b/src/ppl/test/write_pin_placement2.ok index 77bdff543c8..de0364f679d 100644 --- a/src/ppl/test/write_pin_placement2.ok +++ b/src/ppl/test/write_pin_placement2.ok @@ -10,6 +10,7 @@ Found 0 macro blocks. [INFO PPL-0002] Number of I/O 400 [INFO PPL-0003] Number of I/O w/sink 400 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 2 [INFO PPL-0012] I/O nets HPWL: 17121.63 um. [INFO PPL-0070] Pin pin0 placed at (0.04um, 27.09um). [INFO PPL-0070] Pin pin1 placed at (0.04um, 27.23um). diff --git a/src/ppl/test/write_pin_placement3.ok b/src/ppl/test/write_pin_placement3.ok index f02bcf92e8f..931ae1df273 100644 --- a/src/ppl/test/write_pin_placement3.ok +++ b/src/ppl/test/write_pin_placement3.ok @@ -9,6 +9,7 @@ Found 0 macro blocks. [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 1 [INFO PPL-0012] I/O nets HPWL: 2487.34 um. [INFO PPL-0070] Pin clk placed at (60.33um, 0.04um). [INFO PPL-0070] Pin req_msg[29] placed at (44.37um, 0.04um). diff --git a/src/ppl/test/write_pin_placement4.ok b/src/ppl/test/write_pin_placement4.ok index e81079542ea..44d5fb989e8 100644 --- a/src/ppl/test/write_pin_placement4.ok +++ b/src/ppl/test/write_pin_placement4.ok @@ -9,6 +9,7 @@ Found 0 macro blocks. [INFO PPL-0002] Number of I/O 54 [INFO PPL-0003] Number of I/O w/sink 54 [INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0006] Number of I/O Groups 1 [INFO PPL-0012] I/O nets HPWL: 2452.71 um. [INFO PPL-0070] Pin clk placed at (60.33um, 0.04um). [INFO PPL-0070] Pin req_msg[29] placed at (44.37um, 0.04um). diff --git a/test/aes_nangate45.metrics_limits b/test/aes_nangate45.metrics_limits index 3ab59a58526..5aaddd38a36 100644 --- a/test/aes_nangate45.metrics_limits +++ b/test/aes_nangate45.metrics_limits @@ -17,7 +17,7 @@ ,"DRT::tns_max" : "-153.5526667018758" ,"DRT::clock_skew" : "0.11664569640351011" ,"DRT::max_slew_slack" : "0" - ,"DRT::max_capacitance_slack" : "-7.017648689667465" + ,"DRT::max_capacitance_slack" : "-8.924107839569885" ,"DRT::max_fanout_slack" : "0" ,"DRT::clock_period" : "0.8109" ,"DRT::ANT::errors" : "0" diff --git a/test/gcd_sky130hd.metrics_limits b/test/gcd_sky130hd.metrics_limits index 001f0280168..dadeda56fb5 100644 --- a/test/gcd_sky130hd.metrics_limits +++ b/test/gcd_sky130hd.metrics_limits @@ -15,7 +15,7 @@ ,"DRT::worst_slack_min" : "0.04123748526040111" ,"DRT::worst_slack_max" : "-0.9788220249158479" ,"DRT::tns_max" : "-14.967746254967835" - ,"DRT::clock_skew" : "0.016702240063753447" + ,"DRT::clock_skew" : "0.022114710688639166" ,"DRT::max_slew_slack" : "0" ,"DRT::max_capacitance_slack" : "0" ,"DRT::max_fanout_slack" : "0" diff --git a/test/ibex_sky130hd.metrics_limits b/test/ibex_sky130hd.metrics_limits index f66fe5b207e..cc5a1161628 100644 --- a/test/ibex_sky130hd.metrics_limits +++ b/test/ibex_sky130hd.metrics_limits @@ -17,7 +17,7 @@ ,"DRT::tns_max" : "-2581.9787879263245" ,"DRT::clock_skew" : "3.2802812061774143" ,"DRT::max_slew_slack" : "-29.41488981246948" - ,"DRT::max_capacitance_slack" : "-0.7871386861943243" + ,"DRT::max_capacitance_slack" : "-3.0871108026580094" ,"DRT::max_fanout_slack" : "0" ,"DRT::clock_period" : "15.155" ,"DRT::ANT::errors" : "0" diff --git a/test/jpeg_sky130hd.metrics_limits b/test/jpeg_sky130hd.metrics_limits index e6f4f0f4c73..58ccffcc2dd 100644 --- a/test/jpeg_sky130hd.metrics_limits +++ b/test/jpeg_sky130hd.metrics_limits @@ -16,7 +16,7 @@ ,"DRT::worst_slack_max" : "-1.4207932121850533" ,"DRT::tns_max" : "-3671.24784844656" ,"DRT::clock_skew" : "0.7347320293467481" - ,"DRT::max_slew_slack" : "-9.180682897567749" + ,"DRT::max_slew_slack" : "-23.959243298" ,"DRT::max_capacitance_slack" : "-8.406745480008647" ,"DRT::max_fanout_slack" : "0" ,"DRT::clock_period" : "8.0" diff --git a/test/upf_aes.ok b/test/upf_aes.ok index 5a71dd23bd7..51a6c1848d6 100644 --- a/test/upf_aes.ok +++ b/test/upf_aes.ok @@ -4,13 +4,11 @@ [INFO IFP-0001] Added 497 rows of 2944 site unithd. Found 0 macro blocks. Using 2 tracks default min distance between IO pins. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 4948 [INFO PPL-0002] Number of I/O 394 [INFO PPL-0003] Number of I/O w/sink 391 [INFO PPL-0004] Number of I/O w/o sink 3 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 291688.28 um. [INFO GPL-0002] DBU: 1000 diff --git a/test/upf_test.ok b/test/upf_test.ok index fd3f201be27..5f66a79dfaf 100644 --- a/test/upf_test.ok +++ b/test/upf_test.ok @@ -4,13 +4,11 @@ [INFO IFP-0001] Added 39 rows of 235 site unithd. Found 0 macro blocks. Using 2 tracks default min distance between IO pins. -[INFO PPL-0010] Tentative 0 to set up sections. [INFO PPL-0001] Number of slots 406 [INFO PPL-0002] Number of I/O 7 [INFO PPL-0003] Number of I/O w/sink 7 [INFO PPL-0004] Number of I/O w/o sink 0 [INFO PPL-0005] Slots per section 200 -[INFO PPL-0006] Slots increase factor 0.01 [INFO PPL-0008] Successfully assigned pins to sections. [INFO PPL-0012] I/O nets HPWL: 410.02 um. [INFO GPL-0002] DBU: 1000