diff --git a/src/ppl/include/ppl/IOPlacer.h b/src/ppl/include/ppl/IOPlacer.h index fce98612daa..d1bdef8cff8 100644 --- a/src/ppl/include/ppl/IOPlacer.h +++ b/src/ppl/include/ppl/IOPlacer.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -218,6 +219,32 @@ class IOPlacer bool checkBlocked(Edge edge, odb::Line, const odb::Point& pos, int layer); std::vector findBlockedIntervals(const odb::Rect& die_area, const odb::Rect& box); + struct PinSize + { + int half_width = 0; + int height = 0; + }; + // a shape blocking pins, with the spacing rules it carries + struct BlockingShape + { + odb::Rect rect; + int min_spacing = 0; + int effective_width = 0; + }; + PinSize computePinSize(int layer, bool vertical_pin); + int computeLayerSpacing(int layer, int shape_width, int parallel_length); + odb::Rect padShapeForPin(const odb::Rect& box, + int layer, + bool vertical_pin, + int min_spacing = 0, + int effective_width = 0); + void excludeBoundaryShape(const odb::Rect& box, + odb::dbTechLayer* tech_layer, + const odb::Rect& die_area, + int min_spacing = 0, + int effective_width = 0); + void getBlockedRegions(); + void getBlockedRegionsFromPDN(); void getBlockedRegionsFromMacros(); void getBlockedRegionsFromDbObstructions(); Edge getMirroredEdge(const Edge& edge); @@ -261,7 +288,14 @@ class IOPlacer std::vector excluded_intervals_; std::vector constraints_; FallbackPins fallback_pins_; + // fixed pin shapes padded by the pin size and spacing, per layer std::map> layer_fixed_pins_shapes_; + // padded boundary shapes blocking polygon die slots, per layer + std::map> layer_blocked_shapes_; + std::map, PinSize> pin_size_cache_; + std::map, int> spacing_cache_; + // width of the pin being placed by place_pin, for the spacing rules + int manual_pin_width_ = 0; utl::Logger* logger_ = nullptr; std::unique_ptr validator_; diff --git a/src/ppl/src/Core.cpp b/src/ppl/src/Core.cpp index 6dfdf0385d9..c359515a303 100644 --- a/src/ppl/src/Core.cpp +++ b/src/ppl/src/Core.cpp @@ -22,7 +22,7 @@ int Core::getPerimeter() const return (x + y) * 2; } -std::vector Core::getDieAreaEdges() +const std::vector& Core::getDieAreaEdges() const { return die_area_edges_; } diff --git a/src/ppl/src/Core.h b/src/ppl/src/Core.h index af2889301b0..ccf67e59fdb 100644 --- a/src/ppl/src/Core.h +++ b/src/ppl/src/Core.h @@ -52,14 +52,14 @@ class Core const LayerToVector& getInitTracksY() const { return init_tracks_y_; } const LayerToVector& getNumTracksX() const { return num_tracks_x_; } const LayerToVector& getNumTracksY() const { return num_tracks_y_; } - std::map getMinAreaX() const { return min_area_x_; } - std::map getMinAreaY() const { return min_area_y_; } - std::map getMinWidthX() const { return min_width_x_; } - std::map getMinWidthY() const { return min_width_y_; } + const std::map& getMinAreaX() const { return min_area_x_; } + const std::map& getMinAreaY() const { return min_area_y_; } + const std::map& getMinWidthX() const { return min_width_x_; } + const std::map& getMinWidthY() const { return min_width_y_; } int getDatabaseUnit() const { return database_unit_; } int getPerimeter() const; odb::Point getMirroredPosition(const odb::Point& position) const; - std::vector getDieAreaEdges(); + const std::vector& getDieAreaEdges() const; private: odb::Rect boundary_; diff --git a/src/ppl/src/HungarianMatching.cpp b/src/ppl/src/HungarianMatching.cpp index 3166304309d..8123fccc7b8 100644 --- a/src/ppl/src/HungarianMatching.cpp +++ b/src/ppl/src/HungarianMatching.cpp @@ -59,6 +59,7 @@ void HungarianMatching::createMatrix() for (int idx : pin_indices_) { IOPin& io_pin = netlist_->getIoPin(idx); if (!io_pin.isInGroup()) { + const bool has_mirror = io_pin.getBTerm()->hasMirroredBTerm(); bool is_mirrored = false; std::vector larger_costs; int slot_index = 0; @@ -73,7 +74,11 @@ void HungarianMatching::createMatrix() const int mirrored_cost = getMirroredPinCost(io_pin, slot_pos); const int hpwl = io_net_hpwl + mirrored_cost; larger_costs.push_back(std::max(io_net_hpwl, mirrored_cost)); - hungarian_matrix_[slot_index][pin_index] = hpwl; + // avoid slots whose mirrored slot cannot receive the mirrored pin + hungarian_matrix_[slot_index][pin_index] + = has_mirror && isMirroredSlotBlocked(slot_pos, slots_[i].layer) + ? hungarian_fail_ + : hpwl; is_mirrored = is_mirrored || mirrored_cost != 0; slot_index++; } @@ -82,6 +87,9 @@ void HungarianMatching::createMatrix() std::vector rank = getTieBreakRank(larger_costs); for (int idx = 0; idx < slot_index; idx++) { const int hpwl = hungarian_matrix_[idx][pin_index]; + if (hpwl == hungarian_fail_) { + continue; + } if ((hpwl >> 24) != 0) { logger_->critical(utl::PPL, 210, "Cost for pin exceeds 24 bits."); } @@ -161,7 +169,7 @@ void HungarianMatching::assignMirroredPins(IOPin& io_pin, mirrored_pin.setPlaced(); assignment.push_back(mirrored_pin); int slot_index = getSlotIdxByPosition(mirrored_pos, mirrored_pin.getLayer()); - if (slot_index < 0 || slots_[slot_index].used) { + if (slot_index < 0 || !slots_[slot_index].isAvailable()) { odb::dbTechLayer* layer = db_->getTech()->findRoutingLayer(mirrored_pin.getLayer()); logger_->error( @@ -348,6 +356,14 @@ void HungarianMatching::getAssignmentForGroups(std::vector& assignment, assignment_.clear(); } +bool HungarianMatching::isMirroredSlotBlocked(const odb::Point& pos, + int layer) const +{ + const int slot_index + = getSlotIdxByPosition(core_->getMirroredPosition(pos), layer); + return slot_index < 0 || !slots_[slot_index].isAvailable(); +} + int HungarianMatching::getSlotIdxByPosition(const odb::Point& position, int layer) const { diff --git a/src/ppl/src/HungarianMatching.h b/src/ppl/src/HungarianMatching.h index 2a40e1b746e..01516cc35c7 100644 --- a/src/ppl/src/HungarianMatching.h +++ b/src/ppl/src/HungarianMatching.h @@ -60,6 +60,7 @@ class HungarianMatching void createMatrixForGroups(); void assignMirroredPins(IOPin& io_pin, std::vector& assignment); int getSlotIdxByPosition(const odb::Point& position, int layer) const; + bool isMirroredSlotBlocked(const odb::Point& pos, int layer) const; bool groupHasMirroredPin(const std::vector& group); int getMirroredPinCost(IOPin& io_pin, const odb::Point& position); Edge getMirroredEdge(const Edge& edge); diff --git a/src/ppl/src/IOPlacer.cpp b/src/ppl/src/IOPlacer.cpp index b0b925998cc..36694430f52 100644 --- a/src/ppl/src/IOPlacer.cpp +++ b/src/ppl/src/IOPlacer.cpp @@ -24,6 +24,7 @@ #include "Slots.h" #include "odb/db.h" #include "odb/dbSet.h" +#include "odb/dbShape.h" #include "odb/dbTypes.h" #include "odb/geom.h" #include "ppl/Parameters.h" @@ -69,6 +70,9 @@ void IOPlacer::clear() top_layer_slots_.clear(); assignment_.clear(); excluded_intervals_.clear(); + layer_blocked_shapes_.clear(); + pin_size_cache_.clear(); + spacing_cache_.clear(); *parms_ = Parameters(); } @@ -286,7 +290,7 @@ void IOPlacer::assignMirroredPins(IOPin& io_pin, std::vector& assignment) assignment.push_back(mirrored_pin); int slot_index = getSlotIdxByPosition(mirrored_pos, mirrored_pin.getLayer(), slots_); - if (slot_index < 0 || slots_[slot_index].used) { + if (slot_index < 0 || !slots_[slot_index].isAvailable()) { odb::dbTechLayer* layer = db_->getTech()->findRoutingLayer(mirrored_pin.getLayer()); logger_->error( @@ -420,9 +424,22 @@ bool IOPlacer::checkBlocked(Edge edge, const odb::Point& pos, int layer) { - for (odb::Rect fixed_pin_shape : layer_fixed_pins_shapes_[layer]) { - if (fixed_pin_shape.intersects(pos)) { - return true; + const auto fixed_shapes = layer_fixed_pins_shapes_.find(layer); + if (fixed_shapes != layer_fixed_pins_shapes_.end()) { + for (const odb::Rect& padded_shape : fixed_shapes->second) { + if (padded_shape.intersects(pos)) { + return true; + } + } + } + if (edge == Edge::polygonEdge) { + const auto blocked_shapes = layer_blocked_shapes_.find(layer); + if (blocked_shapes != layer_blocked_shapes_.end()) { + for (const odb::Rect& padded_shape : blocked_shapes->second) { + if (padded_shape.intersects(pos)) { + return true; + } + } } } bool vertical_pin = (edge == Edge::polygonEdge) @@ -434,8 +451,11 @@ bool IOPlacer::checkBlocked(Edge edge, // the layer of the position if (blocked_interval.getLayer() == -1 || blocked_interval.getLayer() == layer) { - if ((blocked_interval.getEdge() == edge || edge == Edge::polygonEdge) - // Polygons need to be dealt with properly later + // polygon slots match intervals of any edge with the same orientation + const bool vertical_edge = blocked_interval.getEdge() == Edge::top + || blocked_interval.getEdge() == Edge::bottom; + if ((blocked_interval.getEdge() == edge + || (edge == Edge::polygonEdge && vertical_edge == vertical_pin)) && coord > blocked_interval.getBegin() && coord < blocked_interval.getEnd()) { return true; @@ -471,6 +491,197 @@ std::vector IOPlacer::findBlockedIntervals(const odb::Rect& die_area, return intervals; } +IOPlacer::PinSize IOPlacer::computePinSize(const int layer, + const bool vertical_pin) +{ + const auto cache_key = std::make_pair(layer, vertical_pin); + const auto cached = pin_size_cache_.find(cache_key); + if (cached != pin_size_cache_.end()) { + return cached->second; + } + odb::dbTechLayer* tech_layer = getTech()->findRoutingLayer(layer); + const std::map& min_widths + = vertical_pin ? core_->getMinWidthX() : core_->getMinWidthY(); + const std::map& min_areas + = vertical_pin ? core_->getMinAreaX() : core_->getMinAreaY(); + const float thickness_multiplier + = vertical_pin ? parms_->getVerticalThicknessMultiplier() + : parms_->getHorizontalThicknessMultiplier(); + // fall back to the tech layer values for layers not used by place_pins + const auto min_width_itr = min_widths.find(layer); + const int min_width = min_width_itr != min_widths.end() + ? min_width_itr->second + : tech_layer->getWidth(); + const auto min_area_itr = min_areas.find(layer); + const int min_area = min_area_itr != min_areas.end() ? min_area_itr->second + : tech_layer->getArea(); + PinSize pin_size; + pin_size.half_width = int(ceil(min_width / 2.0)) * thickness_multiplier; + pin_size.height = int(std::max(2.0 * pin_size.half_width, + ceil(min_area / (2.0 * pin_size.half_width)))); + const int user_length = vertical_pin ? parms_->getVerticalLength() + : parms_->getHorizontalLength(); + if (user_length != -1) { + pin_size.height = user_length; + } + const int mfg_grid = getTech()->getManufacturingGrid(); + if (mfg_grid > 0 && pin_size.height % mfg_grid != 0) { + pin_size.height + = mfg_grid * std::ceil(static_cast(pin_size.height) / mfg_grid); + } + pin_size_cache_[cache_key] = pin_size; + return pin_size; +} + +int IOPlacer::computeLayerSpacing(const int layer, + const int shape_width, + const int parallel_length) +{ + const auto cache_key = std::make_tuple(layer, shape_width, parallel_length); + const auto cached = spacing_cache_.find(cache_key); + if (cached != spacing_cache_.end()) { + return cached->second; + } + odb::dbTechLayer* tech_layer = getTech()->findRoutingLayer(layer); + // width-dependent rules require larger clearance to wide PDN shapes + int spacing = tech_layer->getSpacing(shape_width, parallel_length); + if (spacing == 0) { + spacing = tech_layer->getWidth(); + } + spacing_cache_[cache_key] = spacing; + return spacing; +} + +odb::Rect IOPlacer::padShapeForPin(const odb::Rect& box, + const int layer, + const bool vertical_pin, + const int min_spacing, + const int effective_width) +{ + const PinSize pin_size = computePinSize(layer, vertical_pin); + const int shape_width = std::max( + static_cast(std::min(box.dx(), box.dy())), effective_width); + const int pin_width = std::max(2 * pin_size.half_width, manual_pin_width_); + const int spacing + = std::max(computeLayerSpacing( + layer, std::max(shape_width, pin_width), pin_size.height), + min_spacing); + // pad by the pin footprint plus spacing: half width along the edge, the pin + // extension into the die on the other axis + const odb::Orientation2D edge_dir = vertical_pin + ? odb::Orientation2D::Horizontal + : odb::Orientation2D::Vertical; + return box.bloat(pin_size.half_width + spacing, edge_dir) + .bloat(pin_size.height + spacing, edge_dir.turn_90()); +} + +namespace { +bool touchesLine(const odb::Rect& rect, const odb::Line& line) +{ + const odb::Point pt0 = line.pt0(); + const odb::Point pt1 = line.pt1(); + if (pt0.getY() == pt1.getY()) { + return rect.yMin() <= pt0.getY() && pt0.getY() <= rect.yMax() + && rect.xMin() <= std::max(pt0.getX(), pt1.getX()) + && std::min(pt0.getX(), pt1.getX()) <= rect.xMax(); + } + return rect.xMin() <= pt0.getX() && pt0.getX() <= rect.xMax() + && rect.yMin() <= std::max(pt0.getY(), pt1.getY()) + && std::min(pt0.getY(), pt1.getY()) <= rect.yMax(); +} +} // namespace + +void IOPlacer::excludeBoundaryShape(const odb::Rect& box, + odb::dbTechLayer* tech_layer, + const odb::Rect& die_area, + const int min_spacing, + const int effective_width) +{ + const int layer = tech_layer->getRoutingLevel(); + // pins are only placed on routing layers + if (layer == 0) { + return; + } + // PPL-45/46 guarantee the layer sets agree with the preferred direction, so + // they only filter which layers have slots; empty sets mean standalone + // place_pin, where every layer participates + const bool vertical_pin + = tech_layer->getDirection() == odb::dbTechLayerDir::VERTICAL; + if (!ver_layers_.empty() || !hor_layers_.empty()) { + const std::set& layers = vertical_pin ? ver_layers_ : hor_layers_; + if (layers.find(layer) == layers.end()) { + return; + } + } + const odb::Rect padded_box + = padShapeForPin(box, layer, vertical_pin, min_spacing, effective_width); + if (!die_area.intersects(padded_box)) { + return; + } + const std::vector& die_edges = core_->getDieAreaEdges(); + if (die_edges.size() > 4) { + // polygon dies have slots on edges the bounding box cannot represent, so + // block their slots with the padded shape itself + for (const odb::Line& die_edge : die_edges) { + if (touchesLine(padded_box, die_edge)) { + layer_blocked_shapes_[layer].push_back(padded_box); + break; + } + } + return; + } + const odb::Rect intersect = die_area.intersect(padded_box); + for (const Interval& interval : findBlockedIntervals(die_area, intersect)) { + const bool vertical_edge + = interval.getEdge() == Edge::top || interval.getEdge() == Edge::bottom; + if (vertical_edge != vertical_pin) { + continue; + } + excludeInterval(Interval( + interval.getEdge(), interval.getBegin(), interval.getEnd(), layer)); + } +} + +void IOPlacer::getBlockedRegions() +{ + getBlockedRegionsFromMacros(); + getBlockedRegionsFromDbObstructions(); + getBlockedRegionsFromPDN(); +} + +void IOPlacer::getBlockedRegionsFromPDN() +{ + const odb::Rect die_area = getBlock()->getDieArea(); + + for (odb::dbNet* net : getBlock()->getNets()) { + if (!net->isSpecial()) { + continue; + } + for (odb::dbSWire* swire : net->getSWires()) { + for (odb::dbSBox* sbox : swire->getWires()) { + if (sbox->isVia()) { + // via landing pads can also reach the die boundary + std::vector via_shapes; + sbox->getViaBoxes(via_shapes); + for (const odb::dbShape& via_shape : via_shapes) { + odb::dbTechLayer* tech_layer = via_shape.getTechLayer(); + if (tech_layer == nullptr || tech_layer->getRoutingLevel() == 0) { + continue; + } + excludeBoundaryShape(via_shape.getBox(), tech_layer, die_area); + } + continue; + } + odb::dbTechLayer* tech_layer = sbox->getTechLayer(); + if (tech_layer == nullptr) { + continue; + } + excludeBoundaryShape(sbox->getBox(), tech_layer, die_area); + } + } + } +} + void IOPlacer::getBlockedRegionsFromMacros() { odb::Rect die_area = getBlock()->getDieArea(); @@ -492,17 +703,28 @@ void IOPlacer::getBlockedRegionsFromMacros() void IOPlacer::getBlockedRegionsFromDbObstructions() { - odb::Rect die_area = getBlock()->getDieArea(); + const odb::Rect die_area = getBlock()->getDieArea(); for (odb::dbObstruction* obstruction : getBlock()->getObstructions()) { - odb::dbBox* obstructBox = obstruction->getBBox(); - odb::Rect obstructArea = obstructBox->getBox(); - odb::Rect intersect = die_area.intersect(obstructArea); - - std::vector intervals = findBlockedIntervals(die_area, intersect); - for (Interval interval : intervals) { - excludeInterval(interval); + // system reserved obstructions only mark the outside of polygon dies + if (obstruction->isSystemReserved()) { + continue; } + odb::dbBox* obstruct_box = obstruction->getBBox(); + odb::dbTechLayer* tech_layer = obstruct_box->getTechLayer(); + if (tech_layer == nullptr) { + continue; + } + const int min_spacing + = obstruction->hasMinSpacing() ? obstruction->getMinSpacing() : 0; + const int effective_width = obstruction->hasEffectiveWidth() + ? obstruction->getEffectiveWidth() + : 0; + excludeBoundaryShape(obstruct_box->getBox(), + tech_layer, + die_area, + min_spacing, + effective_width); } } @@ -727,7 +949,7 @@ void IOPlacer::findSlots(const std::set& layers, } for (const odb::Point& pos : slots) { - bool blocked = checkBlocked(Edge::invalid, line, pos, layer); + bool blocked = checkBlocked(Edge::polygonEdge, line, pos, layer); slots_.push_back({blocked, false, pos, layer, Edge::polygonEdge, line}); } } @@ -812,15 +1034,7 @@ std::vector IOPlacer::findLayerSlots(const int layer, int init_tracks = layer_init_tracks[l]; int num_tracks = layer_num_tracks[l]; - float thickness_multiplier - = vertical_pin ? parms_->getVerticalThicknessMultiplier() - : parms_->getHorizontalThicknessMultiplier(); - - int half_width = vertical_pin - ? int(ceil(core_->getMinWidthX()[layer] / 2.0)) - : int(ceil(core_->getMinWidthY()[layer] / 2.0)); - - half_width *= thickness_multiplier; + const int half_width = computePinSize(layer, vertical_pin).half_width; int num_tracks_offset = std::ceil(static_cast(corner_avoidance_) / min_dst_pins); @@ -1663,27 +1877,16 @@ void IOPlacer::updatePinArea(IOPin& pin) if (pin.getOrientation() == Orientation::north || pin.getOrientation() == Orientation::south) { - float thickness_multiplier = parms_->getVerticalThicknessMultiplier(); - int half_width = int(ceil(core_->getMinWidthX()[pin.getLayer()] / 2.0)) - * thickness_multiplier; - int height = int(std::max( - 2.0 * half_width, - ceil(core_->getMinAreaX()[pin.getLayer()] / (2.0 * half_width)))); - required_min_area = core_->getMinAreaX()[pin.getLayer()]; + const PinSize pin_size = computePinSize(pin.getLayer(), true); + const int half_width = pin_size.half_width; + const int height = pin_size.height; + required_min_area = core_->getMinAreaX().at(pin.getLayer()); int ext = 0; - if (parms_->getVerticalLength() != -1) { - height = parms_->getVerticalLength(); - } - if (parms_->getVerticalLengthExtend() != -1) { ext = parms_->getVerticalLengthExtend(); } - if (height % mfg_grid != 0) { - height = mfg_grid * std::ceil(static_cast(height) / mfg_grid); - } - if (pin.getOrientation() == Orientation::north) { pin.setLowerBound(pin.getX() - half_width, pin.getY() - ext); pin.setUpperBound(pin.getX() + half_width, pin.getY() + height); @@ -1695,25 +1898,15 @@ void IOPlacer::updatePinArea(IOPin& pin) if (pin.getOrientation() == Orientation::west || pin.getOrientation() == Orientation::east) { - float thickness_multiplier = parms_->getHorizontalThicknessMultiplier(); - int half_width = int(ceil(core_->getMinWidthY()[pin.getLayer()] / 2.0)) - * thickness_multiplier; - int height = int(std::max( - 2.0 * half_width, - ceil(core_->getMinAreaY()[pin.getLayer()] / (2.0 * half_width)))); - required_min_area = core_->getMinAreaY()[pin.getLayer()]; + const PinSize pin_size = computePinSize(pin.getLayer(), false); + const int half_width = pin_size.half_width; + const int height = pin_size.height; + required_min_area = core_->getMinAreaY().at(pin.getLayer()); int ext = 0; if (parms_->getHorizontalLengthExtend() != -1) { ext = parms_->getHorizontalLengthExtend(); } - if (parms_->getHorizontalLength() != -1) { - height = parms_->getHorizontalLength(); - } - - if (height % mfg_grid != 0) { - height = mfg_grid * std::ceil(static_cast(height) / mfg_grid); - } if (pin.getOrientation() == Orientation::east) { pin.setLowerBound(pin.getX() - ext, pin.getY() - half_width); @@ -2268,7 +2461,7 @@ void IOPlacer::runHungarianMatching() slots_per_section_ = parms_->getSlotsPerSection(); initExcludedIntervals(); initNetlistAndCore(hor_layers_, ver_layers_); - getBlockedRegionsFromMacros(); + getBlockedRegions(); defineSlots(); @@ -2410,7 +2603,7 @@ void IOPlacer::runAnnealing() slots_per_section_ = parms_->getSlotsPerSection(); initExcludedIntervals(); initNetlistAndCore(hor_layers_, ver_layers_); - getBlockedRegionsFromMacros(); + getBlockedRegions(); defineSlots(); @@ -2628,6 +2821,20 @@ void IOPlacer::placePin(odb::dbBTerm* bterm, const int layer_level = layer->getRoutingLevel(); if (force_to_die_bound) { + // block boundary PDN shapes for the checks below, without persisting the + // intervals beyond this placement, padding them with the actual pin size + pin_size_cache_.clear(); + spacing_cache_.clear(); + const bool vertical_pin + = layer->getDirection() == odb::dbTechLayerDir::VERTICAL; + PinSize pin_size; + pin_size.half_width = (vertical_pin ? width : height) / 2; + pin_size.height = vertical_pin ? height : width; + pin_size_cache_[{layer_level, vertical_pin}] = pin_size; + manual_pin_width_ = std::min(width, height); + const size_t num_excluded_intervals = excluded_intervals_.size(); + getBlockedRegionsFromDbObstructions(); + getBlockedRegionsFromPDN(); movePinToTrack(pos, layer_level, width, height, die_boundary); Edge edge; odb::dbTrackGrid* track_grid = getBlock()->findTrackGrid(layer); @@ -2650,24 +2857,29 @@ void IOPlacer::placePin(odb::dbBTerm* bterm, // between pins // empty line created to comply with definition odb::Line empty_line; + // check the center and the extremities of the pin shape, so wide pins do + // not straddle a blocked region bool placed_at_blocked - = horizontal - ? checkBlocked(edge, - empty_line, - odb::Point(pos.x(), pos.y() - height / 2), - layer_level) - || checkBlocked(edge, - empty_line, - odb::Point(pos.x(), pos.y() + height / 2), - layer_level) - : checkBlocked(edge, - empty_line, - odb::Point(pos.x() - width / 2, pos.y()), - layer_level) - || checkBlocked(edge, - empty_line, - odb::Point(pos.x() + width / 2, pos.y()), - layer_level); + = checkBlocked(edge, empty_line, pos, layer_level) + || (horizontal + ? checkBlocked(edge, + empty_line, + odb::Point(pos.x(), pos.y() - height / 2), + layer_level) + || checkBlocked( + edge, + empty_line, + odb::Point(pos.x(), pos.y() + height / 2), + layer_level) + : checkBlocked(edge, + empty_line, + odb::Point(pos.x() - width / 2, pos.y()), + layer_level) + || checkBlocked( + edge, + empty_line, + odb::Point(pos.x() + width / 2, pos.y()), + layer_level)); bool sum = true; int offset_sum = 1; int offset_sub = 1; @@ -2685,31 +2897,42 @@ void IOPlacer::placePin(odb::dbBTerm* bterm, // check the whole pin shape to make sure no overlaps will happen // between pins + const odb::Point offset_pos = horizontal + ? odb::Point(pos.x(), pos.y() + offset) + : odb::Point(pos.x() + offset, pos.y()); placed_at_blocked - = horizontal - ? checkBlocked( - edge, - empty_line, - odb::Point(pos.x(), pos.y() - height / 2 + offset), - layer_level) - || checkBlocked( + = checkBlocked(edge, empty_line, offset_pos, layer_level) + || (horizontal + ? checkBlocked( edge, empty_line, - odb::Point(pos.x(), pos.y() + height / 2 + offset), + odb::Point(pos.x(), pos.y() - height / 2 + offset), layer_level) - : checkBlocked( - edge, - empty_line, - odb::Point(pos.x() - width / 2 + offset, pos.y()), - layer_level) - || checkBlocked( + || checkBlocked( + edge, + empty_line, + odb::Point(pos.x(), + pos.y() + height / 2 + offset), + layer_level) + : checkBlocked( edge, empty_line, - odb::Point(pos.x() + width / 2 + offset, pos.y()), - layer_level); + odb::Point(pos.x() - width / 2 + offset, pos.y()), + layer_level) + || checkBlocked( + edge, + empty_line, + odb::Point(pos.x() + width / 2 + offset, pos.y()), + layer_level)); } pos.addX(horizontal ? 0 : offset); pos.addY(horizontal ? offset : 0); + excluded_intervals_.erase( + excluded_intervals_.begin() + num_excluded_intervals, + excluded_intervals_.end()); + pin_size_cache_.clear(); + spacing_cache_.clear(); + manual_pin_width_ = 0; } odb::Point ll = odb::Point(pos.x() - width / 2, pos.y() - height / 2); @@ -2961,17 +3184,29 @@ void IOPlacer::findSlotsForTopLayer() void IOPlacer::filterObstructedSlotsForTopLayer() { - // Collect top_grid obstructions - std::vector obstructions; + if (top_grid_ == nullptr || top_grid_->layer == nullptr) { + return; + } + const int top_layer_level = top_grid_->layer->getRoutingLevel(); + + // Collect top_grid obstructions, with the spacing rules they carry + std::vector obstructions; // Get routing obstructions for (odb::dbObstruction* obstruction : getBlock()->getObstructions()) { + // system reserved obstructions only mark the outside of polygon dies + if (obstruction->isSystemReserved()) { + continue; + } odb::dbBox* box = obstruction->getBBox(); - if (top_grid_ != nullptr && top_grid_->layer != nullptr - && box->getTechLayer()->getRoutingLevel() - == top_grid_->layer->getRoutingLevel()) { - odb::Rect obstruction_rect = box->getBox(); - obstructions.push_back(obstruction_rect); + odb::dbTechLayer* tech_layer = box->getTechLayer(); + if (tech_layer != nullptr + && tech_layer->getRoutingLevel() == top_layer_level) { + obstructions.push_back( + {box->getBox(), + obstruction->hasMinSpacing() ? obstruction->getMinSpacing() : 0, + obstruction->hasEffectiveWidth() ? obstruction->getEffectiveWidth() + : 0}); } } @@ -2980,13 +3215,20 @@ void IOPlacer::filterObstructedSlotsForTopLayer() if (net->isSpecial()) { for (odb::dbSWire* swire : net->getSWires()) { for (odb::dbSBox* wire : swire->getWires()) { - if (!wire->isVia()) { - if (top_grid_ != nullptr && top_grid_->layer != nullptr - && wire->getTechLayer()->getRoutingLevel() - == top_grid_->layer->getRoutingLevel()) { - odb::Rect obstruction_rect = wire->getBox(); - obstructions.push_back(obstruction_rect); + if (wire->isVia()) { + // via landing pads also obstruct the top layer pins + std::vector via_shapes; + wire->getViaBoxes(via_shapes); + for (const odb::dbShape& via_shape : via_shapes) { + odb::dbTechLayer* tech_layer = via_shape.getTechLayer(); + if (tech_layer != nullptr + && tech_layer->getRoutingLevel() == top_layer_level) { + obstructions.push_back({via_shape.getBox(), 0, 0}); + } } + } else if (wire->getTechLayer()->getRoutingLevel() + == top_layer_level) { + obstructions.push_back({wire->getBox(), 0, 0}); } } } @@ -2998,11 +3240,13 @@ void IOPlacer::filterObstructedSlotsForTopLayer() for (odb::dbBPin* pin : term->getBPins()) { if (pin->getPlacementStatus().isFixed()) { for (odb::dbBox* box : pin->getBoxes()) { - if (top_grid_ != nullptr && top_grid_->layer != nullptr - && box->getTechLayer()->getRoutingLevel() - == top_grid_->layer->getRoutingLevel()) { - odb::Rect obstruction_rect = box->getBox(); - obstructions.push_back(obstruction_rect); + odb::dbTechLayer* tech_layer = box->getTechLayer(); + if (tech_layer != nullptr + && tech_layer->getRoutingLevel() == top_layer_level) { + obstructions.push_back( + {box->getBox(), + pin->hasMinSpacing() ? pin->getMinSpacing() : 0, + pin->hasEffectiveWidth() ? pin->getEffectiveWidth() : 0}); } } } @@ -3011,29 +3255,38 @@ void IOPlacer::filterObstructedSlotsForTopLayer() // check for slots that go beyond the die boundary odb::Rect die_area = getBlock()->getDieArea(); - if (top_grid_ != nullptr) { - for (auto& slot : top_layer_slots_) { - odb::Point& point = slot.pos; - if (point.x() - top_grid_->pin_width / 2 < die_area.xMin() - || point.y() - top_grid_->pin_height / 2 < die_area.yMin() - || point.x() + top_grid_->pin_width / 2 > die_area.xMax() - || point.y() + top_grid_->pin_height / 2 > die_area.yMax()) { - // mark slot as blocked since it extends beyond the die area - slot.blocked = true; - } + for (auto& slot : top_layer_slots_) { + odb::Point& point = slot.pos; + if (point.x() - top_grid_->pin_width / 2 < die_area.xMin() + || point.y() - top_grid_->pin_height / 2 < die_area.yMin() + || point.x() + top_grid_->pin_width / 2 > die_area.xMax() + || point.y() + top_grid_->pin_height / 2 > die_area.yMax()) { + // mark slot as blocked since it extends beyond the die area + slot.blocked = true; } } // check for slots that overlap with obstructions - for (odb::Rect& rect : obstructions) { + const int pin_min_dim = std::min(top_grid_->pin_width, top_grid_->pin_height); + const int pin_max_dim = std::max(top_grid_->pin_width, top_grid_->pin_height); + for (const BlockingShape& obstruction : obstructions) { + const odb::Rect& rect = obstruction.rect; + // floor the keepout at the spacing required by the obstruction + const int shape_width + = std::max(static_cast(std::min(rect.dx(), rect.dy())), + obstruction.effective_width); + const int spacing = std::max( + computeLayerSpacing( + top_layer_level, std::max(shape_width, pin_min_dim), pin_max_dim), + obstruction.min_spacing); + const int keepout = std::max(top_grid_->keepout, spacing); for (auto& slot : top_layer_slots_) { odb::Point& point = slot.pos; // mock slot with keepout - odb::Rect pin_rect( - point.x() - top_grid_->pin_width / 2 - top_grid_->keepout, - point.y() - top_grid_->pin_height / 2 - top_grid_->keepout, - point.x() + top_grid_->pin_width / 2 + top_grid_->keepout, - point.y() + top_grid_->pin_height / 2 + top_grid_->keepout); + odb::Rect pin_rect(point.x() - top_grid_->pin_width / 2 - keepout, + point.y() - top_grid_->pin_height / 2 - keepout, + point.x() + top_grid_->pin_width / 2 + keepout, + point.y() + top_grid_->pin_height / 2 + keepout); if (rect.intersects(pin_rect)) { // mark slot as blocked slot.blocked = true; } @@ -3102,6 +3355,10 @@ std::vector
IOPlacer::findSectionsForTopLayer(const odb::Rect& region) void IOPlacer::initNetlist() { netlist_->reset(); + layer_fixed_pins_shapes_.clear(); + layer_blocked_shapes_.clear(); + pin_size_cache_.clear(); + spacing_cache_.clear(); const odb::Rect& coreBoundary = core_->getBoundary(); int x_center = (coreBoundary.xMin() + coreBoundary.xMax()) / 2; int y_center = (coreBoundary.yMin() + coreBoundary.yMax()) / 2; @@ -3114,9 +3371,27 @@ void IOPlacer::initNetlist() bterm->getFirstPinLocation(x_pos, y_pos); if (bterm->getFirstPinPlacementStatus().isFixed()) { for (odb::dbBPin* bterm_pin : bterm->getBPins()) { + const int min_spacing + = bterm_pin->hasMinSpacing() ? bterm_pin->getMinSpacing() : 0; + const int effective_width = bterm_pin->hasEffectiveWidth() + ? bterm_pin->getEffectiveWidth() + : 0; for (odb::dbBox* bpin_box : bterm_pin->getBoxes()) { - int layer = bpin_box->getTechLayer()->getRoutingLevel(); - layer_fixed_pins_shapes_[layer].push_back(bpin_box->getBox()); + odb::dbTechLayer* tech_layer = bpin_box->getTechLayer(); + if (tech_layer == nullptr) { + continue; + } + const int layer = tech_layer->getRoutingLevel(); + // store the shapes padded, so the pins created near them keep the + // min spacing + const bool vertical_pin + = tech_layer->getDirection() == odb::dbTechLayerDir::VERTICAL; + layer_fixed_pins_shapes_[layer].push_back( + padShapeForPin(bpin_box->getBox(), + layer, + vertical_pin, + min_spacing, + effective_width)); } } continue; diff --git a/src/ppl/test/BUILD b/src/ppl/test/BUILD index 15771408c87..5663a386bfc 100644 --- a/src/ppl/test/BUILD +++ b/src/ppl/test/BUILD @@ -97,9 +97,20 @@ COMPULSORY_TESTS = [ "no_instance_pins", "no_pins", "no_tracks", + "obstruction_boundary", "on_grid", "partial_tracks", "partial_tracks_error", + "pdn_boundary_mirrored_pins", + "pdn_boundary_pg_pins", + "pdn_boundary_place_pin", + "pdn_boundary_stripes", + "pdn_boundary_stripes_length", + "pdn_boundary_stripes_no_pins", + "pdn_boundary_stripes_polygon", + "pdn_boundary_vias", + "pdn_near_boundary_stripes", + "pdn_near_boundary_stripes_length", "pin_extension", "pin_length", "pin_length_error", @@ -125,6 +136,7 @@ COMPULSORY_TESTS = [ "top_layer7", "top_layer_error", "top_layer_error2", + "top_layer_pdn_spacing", "write_pin_placement1", "write_pin_placement2", "write_pin_placement3", diff --git a/src/ppl/test/CMakeLists.txt b/src/ppl/test/CMakeLists.txt index abe56922f43..fccffc408a2 100644 --- a/src/ppl/test/CMakeLists.txt +++ b/src/ppl/test/CMakeLists.txt @@ -90,9 +90,20 @@ or_integration_tests( no_instance_pins no_pins no_tracks + obstruction_boundary on_grid partial_tracks partial_tracks_error + pdn_boundary_mirrored_pins + pdn_boundary_pg_pins + pdn_boundary_place_pin + pdn_boundary_stripes + pdn_boundary_stripes_length + pdn_boundary_stripes_no_pins + pdn_boundary_stripes_polygon + pdn_boundary_vias + pdn_near_boundary_stripes + pdn_near_boundary_stripes_length pin_extension pin_length pin_length_error @@ -118,6 +129,7 @@ or_integration_tests( top_layer7 top_layer_error top_layer_error2 + top_layer_pdn_spacing write_pin_placement1 write_pin_placement2 write_pin_placement3 diff --git a/src/ppl/test/gcd_placed.def b/src/ppl/test/gcd_placed.def new file mode 100644 index 00000000000..bea139a96f1 --- /dev/null +++ b/src/ppl/test/gcd_placed.def @@ -0,0 +1,1590 @@ +VERSION 5.6 ; +DIVIDERCHAR "/" ; +BUSBITCHARS "[]" ; +DESIGN gcd ; +UNITS DISTANCE MICRONS 2000 ; +DIEAREA ( 0 0 ) ( 296000 296000 ) ; + +ROW ROW_0 FreePDK45_38x28_10R_NP_162NW_34O 28000 28000 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_1 FreePDK45_38x28_10R_NP_162NW_34O 28000 30800 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_2 FreePDK45_38x28_10R_NP_162NW_34O 28000 33600 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_3 FreePDK45_38x28_10R_NP_162NW_34O 28000 36400 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_4 FreePDK45_38x28_10R_NP_162NW_34O 28000 39200 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_5 FreePDK45_38x28_10R_NP_162NW_34O 28000 42000 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_6 FreePDK45_38x28_10R_NP_162NW_34O 28000 44800 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_7 FreePDK45_38x28_10R_NP_162NW_34O 28000 47600 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_8 FreePDK45_38x28_10R_NP_162NW_34O 28000 50400 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_9 FreePDK45_38x28_10R_NP_162NW_34O 28000 53200 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_10 FreePDK45_38x28_10R_NP_162NW_34O 28000 56000 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_11 FreePDK45_38x28_10R_NP_162NW_34O 28000 58800 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_12 FreePDK45_38x28_10R_NP_162NW_34O 28000 61600 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_13 FreePDK45_38x28_10R_NP_162NW_34O 28000 64400 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_14 FreePDK45_38x28_10R_NP_162NW_34O 28000 67200 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_15 FreePDK45_38x28_10R_NP_162NW_34O 28000 70000 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_16 FreePDK45_38x28_10R_NP_162NW_34O 28000 72800 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_17 FreePDK45_38x28_10R_NP_162NW_34O 28000 75600 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_18 FreePDK45_38x28_10R_NP_162NW_34O 28000 78400 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_19 FreePDK45_38x28_10R_NP_162NW_34O 28000 81200 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_20 FreePDK45_38x28_10R_NP_162NW_34O 28000 84000 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_21 FreePDK45_38x28_10R_NP_162NW_34O 28000 86800 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_22 FreePDK45_38x28_10R_NP_162NW_34O 28000 89600 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_23 FreePDK45_38x28_10R_NP_162NW_34O 28000 92400 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_24 FreePDK45_38x28_10R_NP_162NW_34O 28000 95200 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_25 FreePDK45_38x28_10R_NP_162NW_34O 28000 98000 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_26 FreePDK45_38x28_10R_NP_162NW_34O 28000 100800 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_27 FreePDK45_38x28_10R_NP_162NW_34O 28000 103600 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_28 FreePDK45_38x28_10R_NP_162NW_34O 28000 106400 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_29 FreePDK45_38x28_10R_NP_162NW_34O 28000 109200 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_30 FreePDK45_38x28_10R_NP_162NW_34O 28000 112000 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_31 FreePDK45_38x28_10R_NP_162NW_34O 28000 114800 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_32 FreePDK45_38x28_10R_NP_162NW_34O 28000 117600 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_33 FreePDK45_38x28_10R_NP_162NW_34O 28000 120400 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_34 FreePDK45_38x28_10R_NP_162NW_34O 28000 123200 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_35 FreePDK45_38x28_10R_NP_162NW_34O 28000 126000 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_36 FreePDK45_38x28_10R_NP_162NW_34O 28000 128800 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_37 FreePDK45_38x28_10R_NP_162NW_34O 28000 131600 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_38 FreePDK45_38x28_10R_NP_162NW_34O 28000 134400 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_39 FreePDK45_38x28_10R_NP_162NW_34O 28000 137200 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_40 FreePDK45_38x28_10R_NP_162NW_34O 28000 140000 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_41 FreePDK45_38x28_10R_NP_162NW_34O 28000 142800 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_42 FreePDK45_38x28_10R_NP_162NW_34O 28000 145600 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_43 FreePDK45_38x28_10R_NP_162NW_34O 28000 148400 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_44 FreePDK45_38x28_10R_NP_162NW_34O 28000 151200 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_45 FreePDK45_38x28_10R_NP_162NW_34O 28000 154000 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_46 FreePDK45_38x28_10R_NP_162NW_34O 28000 156800 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_47 FreePDK45_38x28_10R_NP_162NW_34O 28000 159600 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_48 FreePDK45_38x28_10R_NP_162NW_34O 28000 162400 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_49 FreePDK45_38x28_10R_NP_162NW_34O 28000 165200 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_50 FreePDK45_38x28_10R_NP_162NW_34O 28000 168000 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_51 FreePDK45_38x28_10R_NP_162NW_34O 28000 170800 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_52 FreePDK45_38x28_10R_NP_162NW_34O 28000 173600 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_53 FreePDK45_38x28_10R_NP_162NW_34O 28000 176400 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_54 FreePDK45_38x28_10R_NP_162NW_34O 28000 179200 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_55 FreePDK45_38x28_10R_NP_162NW_34O 28000 182000 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_56 FreePDK45_38x28_10R_NP_162NW_34O 28000 184800 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_57 FreePDK45_38x28_10R_NP_162NW_34O 28000 187600 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_58 FreePDK45_38x28_10R_NP_162NW_34O 28000 190400 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_59 FreePDK45_38x28_10R_NP_162NW_34O 28000 193200 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_60 FreePDK45_38x28_10R_NP_162NW_34O 28000 196000 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_61 FreePDK45_38x28_10R_NP_162NW_34O 28000 198800 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_62 FreePDK45_38x28_10R_NP_162NW_34O 28000 201600 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_63 FreePDK45_38x28_10R_NP_162NW_34O 28000 204400 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_64 FreePDK45_38x28_10R_NP_162NW_34O 28000 207200 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_65 FreePDK45_38x28_10R_NP_162NW_34O 28000 210000 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_66 FreePDK45_38x28_10R_NP_162NW_34O 28000 212800 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_67 FreePDK45_38x28_10R_NP_162NW_34O 28000 215600 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_68 FreePDK45_38x28_10R_NP_162NW_34O 28000 218400 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_69 FreePDK45_38x28_10R_NP_162NW_34O 28000 221200 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_70 FreePDK45_38x28_10R_NP_162NW_34O 28000 224000 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_71 FreePDK45_38x28_10R_NP_162NW_34O 28000 226800 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_72 FreePDK45_38x28_10R_NP_162NW_34O 28000 229600 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_73 FreePDK45_38x28_10R_NP_162NW_34O 28000 232400 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_74 FreePDK45_38x28_10R_NP_162NW_34O 28000 235200 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_75 FreePDK45_38x28_10R_NP_162NW_34O 28000 238000 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_76 FreePDK45_38x28_10R_NP_162NW_34O 28000 240800 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_77 FreePDK45_38x28_10R_NP_162NW_34O 28000 243600 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_78 FreePDK45_38x28_10R_NP_162NW_34O 28000 246400 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_79 FreePDK45_38x28_10R_NP_162NW_34O 28000 249200 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_80 FreePDK45_38x28_10R_NP_162NW_34O 28000 252000 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_81 FreePDK45_38x28_10R_NP_162NW_34O 28000 254800 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_82 FreePDK45_38x28_10R_NP_162NW_34O 28000 257600 FS DO 631 BY 1 STEP 380 0 ; +ROW ROW_83 FreePDK45_38x28_10R_NP_162NW_34O 28000 260400 N DO 631 BY 1 STEP 380 0 ; +ROW ROW_84 FreePDK45_38x28_10R_NP_162NW_34O 28000 263200 FS DO 631 BY 1 STEP 380 0 ; + +TRACKS X 450 DO 778 STEP 380 LAYER metal1 ; +TRACKS Y 140 DO 1057 STEP 280 LAYER metal1 ; +TRACKS X 450 DO 778 STEP 380 LAYER metal2 ; +TRACKS Y 140 DO 1057 STEP 280 LAYER metal2 ; +TRACKS X 450 DO 778 STEP 380 LAYER metal3 ; +TRACKS Y 140 DO 1057 STEP 280 LAYER metal3 ; +TRACKS X 750 DO 528 STEP 560 LAYER metal4 ; +TRACKS Y 140 DO 529 STEP 560 LAYER metal4 ; +TRACKS X 750 DO 528 STEP 560 LAYER metal5 ; +TRACKS Y 700 DO 528 STEP 560 LAYER metal5 ; +TRACKS X 750 DO 528 STEP 560 LAYER metal6 ; +TRACKS Y 700 DO 528 STEP 560 LAYER metal6 ; +TRACKS X 750 DO 185 STEP 1600 LAYER metal7 ; +TRACKS Y 1260 DO 185 STEP 1600 LAYER metal7 ; +TRACKS X 1310 DO 185 STEP 1600 LAYER metal8 ; +TRACKS Y 1260 DO 185 STEP 1600 LAYER metal8 ; +TRACKS X 1310 DO 93 STEP 3200 LAYER metal9 ; +TRACKS Y 2540 DO 92 STEP 3200 LAYER metal9 ; +TRACKS X 4670 DO 92 STEP 3200 LAYER metal10 ; +TRACKS Y 2540 DO 92 STEP 3200 LAYER metal10 ; + +COMPONENTS 549 ; +- _276_ NOR2_X2 + PLACED ( 163459 169796 ) N ; +- _277_ BUF_X4 + PLACED ( 180268 141294 ) N ; +- _278_ INV_X1 + PLACED ( 137834 156379 ) N ; +- _279_ NOR2_X1 + PLACED ( 140171 157249 ) N ; +- _280_ INV_X1 + PLACED ( 142902 155299 ) N ; +- _281_ INV_X1 + PLACED ( 144203 170043 ) N ; +- _282_ NOR2_X1 + PLACED ( 144857 166751 ) N ; +- _283_ INV_X1 + PLACED ( 151146 165869 ) N ; +- _284_ NOR2_X1 + PLACED ( 149452 166185 ) N ; +- _285_ NOR2_X1 + PLACED ( 146268 164213 ) N ; +- _286_ INV_X1 + PLACED ( 141344 166114 ) N ; +- _287_ NOR2_X1 + PLACED ( 142108 164850 ) N ; +- _288_ INV_X1 + PLACED ( 142842 161353 ) N ; +- _289_ AND2_X1 + PLACED ( 145094 157658 ) N ; +- _290_ INV_X1 + PLACED ( 147442 140135 ) N ; +- _291_ NOR2_X1 + PLACED ( 145199 142141 ) N ; +- _292_ INV_X1 + PLACED ( 141635 141297 ) N ; +- _293_ AOI21_X1 + PLACED ( 143416 143287 ) N ; +- _294_ INV_X1 + PLACED ( 151623 141370 ) N ; +- _295_ NOR2_X1 + PLACED ( 150083 143934 ) N ; +- _296_ INV_X1 + PLACED ( 144246 146895 ) N ; +- _297_ NOR2_X1 + PLACED ( 144364 148006 ) N ; +- _298_ NOR2_X1 + PLACED ( 146381 149652 ) N ; +- _299_ AND2_X1 + PLACED ( 146234 152380 ) N ; +- _300_ INV_X16 + PLACED ( 178405 149687 ) N ; +- _301_ NOR2_X4 + PLACED ( 176694 151896 ) N ; +- _302_ INV_X16 + PLACED ( 177304 159626 ) N ; +- _303_ NOR3_X2 + PLACED ( 177718 155388 ) N ; +- _304_ AOI21_X1 + PLACED ( 176910 152141 ) N ; +- _305_ INV_X1 + PLACED ( 173510 148793 ) N ; +- _306_ INV_X32 + PLACED ( 166582 176236 ) N ; +- _307_ AND2_X4 + PLACED ( 178635 167263 ) N ; +- _308_ INV_X4 + PLACED ( 181042 165453 ) N ; +- _309_ INV_X32 + PLACED ( 175412 175431 ) N ; +- _310_ OAI211_X4 + PLACED ( 175963 168750 ) N ; +- _311_ NAND2_X4 + PLACED ( 179597 163944 ) N ; +- _312_ INV_X16 + PLACED ( 182637 160155 ) N ; +- _313_ NOR2_X1 + PLACED ( 179937 158831 ) N ; +- _314_ NOR3_X4 + PLACED ( 175035 155933 ) N ; +- _315_ NOR2_X2 + PLACED ( 171257 149336 ) N ; +- _316_ INV_X1 + PLACED ( 167460 150281 ) N ; +- _317_ NOR2_X1 + PLACED ( 166087 150677 ) N ; +- _318_ INV_X32 + PLACED ( 160960 135956 ) N ; +- _319_ NOR2_X4 + PLACED ( 163146 145597 ) N ; +- _320_ INV_X4 + PLACED ( 164092 155564 ) N ; +- _321_ NAND2_X1 + PLACED ( 160717 154111 ) N ; +- _322_ INV_X1 + PLACED ( 157065 154652 ) N ; +- _323_ OAI21_X4 + PLACED ( 157936 154058 ) N ; +- _324_ NOR4_X4 + PLACED ( 158443 149688 ) N ; +- _325_ NOR2_X1 + PLACED ( 161064 154756 ) N ; +- _326_ OAI21_X1 + PLACED ( 158032 154734 ) N ; +- _327_ INV_X1 + PLACED ( 156141 155920 ) N ; +- _328_ INV_X32 + PLACED ( 166362 141857 ) N ; +- _329_ NOR3_X2 + PLACED ( 164564 146835 ) N ; +- _330_ AOI21_X4 + PLACED ( 162508 146932 ) N ; +- _331_ OAI221_X4 + PLACED ( 156323 153280 ) N ; +- _332_ OAI211_X1 + PLACED ( 146078 154422 ) N ; +- _333_ AND2_X1 + PLACED ( 139305 158131 ) N ; +- _334_ INV_X1 + PLACED ( 142547 155776 ) N ; +- _335_ NAND2_X1 + PLACED ( 145102 166420 ) N ; +- _336_ NAND2_X1 + PLACED ( 149312 165581 ) N ; +- _337_ NAND2_X1 + PLACED ( 146799 163167 ) N ; +- _338_ INV_X1 + PLACED ( 145037 163169 ) N ; +- _339_ NAND3_X1 + PLACED ( 144093 162264 ) N ; +- _340_ NAND2_X1 + PLACED ( 140869 164878 ) N ; +- _341_ NAND2_X1 + PLACED ( 144601 160209 ) N ; +- _342_ INV_X1 + PLACED ( 144561 141861 ) N ; +- _343_ OAI211_X1 + PLACED ( 144298 142963 ) N ; +- _344_ NAND2_X1 + PLACED ( 146027 143383 ) N ; +- _345_ AOI211_X1 + PLACED ( 146033 148517 ) N ; +- _346_ NAND2_X1 + PLACED ( 151023 144167 ) N ; +- _347_ NAND2_X1 + PLACED ( 145950 147711 ) N ; +- _348_ OAI21_X1 + PLACED ( 148188 148096 ) N ; +- _349_ OR2_X1 + PLACED ( 147072 153120 ) N ; +- _350_ AOI21_X1 + PLACED ( 144338 156483 ) N ; +- _351_ AND4_X1 + PLACED ( 142446 154633 ) N ; +- _352_ AOI22_X1 + PLACED ( 143003 155653 ) N ; +- _353_ OR2_X1 + PLACED ( 144236 152358 ) N ; +- _354_ BUF_X4 + PLACED ( 155143 165489 ) N ; +- _355_ INV_X2 + PLACED ( 163508 169258 ) N ; +- _356_ BUF_X4 + PLACED ( 166040 164566 ) N ; +- _357_ AND3_X1 + PLACED ( 145322 156866 ) N ; +- _358_ OAI211_X4 + PLACED ( 148262 154817 ) N ; +- _359_ OAI21_X1 + PLACED ( 143913 157744 ) N ; +- _360_ OAI21_X1 + PLACED ( 147965 154151 ) N ; +- _361_ NAND3_X4 + PLACED ( 148874 157067 ) N ; +- _362_ NOR2_X1 + PLACED ( 166984 166952 ) N ; +- _363_ INV_X1 + PLACED ( 169987 164067 ) N ; +- _364_ NOR2_X4 + PLACED ( 154537 163392 ) N ; +- _365_ AOI221_X4 + PLACED ( 139235 160370 ) N ; +- _366_ AND2_X4 + PLACED ( 160983 163842 ) N ; +- _367_ BUF_X4 + PLACED ( 158505 143629 ) N ; +- _368_ OAI21_X1 + PLACED ( 142356 154439 ) N ; +- _369_ BUF_X4 + PLACED ( 154872 169563 ) N ; +- _370_ AOI22_X1 + PLACED ( 140067 157196 ) N ; +- _371_ NOR2_X2 + PLACED ( 149701 152063 ) N ; +- _372_ NAND3_X1 + PLACED ( 144344 154387 ) N ; +- _373_ OR2_X1 + PLACED ( 144151 157253 ) N ; +- _374_ AOI22_X1 + PLACED ( 144750 160221 ) N ; +- _375_ NAND2_X1 + PLACED ( 141316 162082 ) N ; +- _376_ XOR2_X1 + PLACED ( 137317 167267 ) N ; +- _377_ XNOR2_X1 + PLACED ( 138262 165752 ) N ; +- _378_ INV_X1 + PLACED ( 159311 170689 ) N ; +- _379_ BUF_X4 + PLACED ( 159277 171078 ) N ; +- _380_ NOR2_X1 + PLACED ( 142391 168185 ) N ; +- _381_ NAND2_X1 + PLACED ( 139412 168304 ) N ; +- _382_ AOI221_X4 + PLACED ( 141504 167620 ) N ; +- _383_ AOI21_X1 + PLACED ( 141147 166416 ) N ; +- _384_ INV_X1 + PLACED ( 147394 159992 ) N ; +- _385_ INV_X1 + PLACED ( 147631 157904 ) N ; +- _386_ OAI211_X1 + PLACED ( 146558 160413 ) N ; +- _387_ INV_X1 + PLACED ( 146978 163274 ) N ; +- _388_ AND4_X1 + PLACED ( 147377 163449 ) N ; +- _389_ AOI22_X1 + PLACED ( 147386 163778 ) N ; +- _390_ NOR2_X1 + PLACED ( 148928 161831 ) N ; +- _391_ NOR2_X1 + PLACED ( 146499 169932 ) N ; +- _392_ NAND2_X1 + PLACED ( 149787 166260 ) N ; +- _393_ AOI221_X4 + PLACED ( 142034 171843 ) N ; +- _394_ AOI21_X1 + PLACED ( 144760 171776 ) N ; +- _395_ OAI21_X1 + PLACED ( 148747 161657 ) N ; +- _396_ XOR2_X1 + PLACED ( 151063 170177 ) N ; +- _397_ XNOR2_X1 + PLACED ( 150185 168882 ) N ; +- _398_ NOR2_X1 + PLACED ( 151154 169916 ) N ; +- _399_ AOI221_X1 + PLACED ( 147764 169809 ) N ; +- _400_ BUF_X4 + PLACED ( 156102 163529 ) N ; +- _401_ OR3_X1 + PLACED ( 150420 166170 ) N ; +- _402_ AOI21_X1 + PLACED ( 148237 168967 ) N ; +- _403_ INV_X1 + PLACED ( 147651 148205 ) N ; +- _404_ OAI211_X1 + PLACED ( 147936 149242 ) N ; +- _405_ AOI21_X1 + PLACED ( 144675 146418 ) N ; +- _406_ AOI21_X1 + PLACED ( 145500 148517 ) N ; +- _407_ AND2_X1 + PLACED ( 146532 145425 ) N ; +- _408_ XNOR2_X1 + PLACED ( 149938 140373 ) N ; +- _409_ XNOR2_X1 + PLACED ( 147941 141733 ) N ; +- _410_ NOR2_X1 + PLACED ( 149941 141982 ) N ; +- _411_ AOI221_X1 + PLACED ( 144938 144112 ) N ; +- _412_ OR3_X1 + PLACED ( 149878 142940 ) N ; +- _413_ AOI21_X1 + PLACED ( 148832 140565 ) N ; +- _414_ OAI21_X1 + PLACED ( 149170 149748 ) N ; +- _415_ AND2_X1 + PLACED ( 146991 146893 ) N ; +- _416_ AND4_X1 + PLACED ( 149624 147455 ) N ; +- _417_ AOI22_X1 + PLACED ( 149620 148353 ) N ; +- _418_ OR2_X1 + PLACED ( 154532 144961 ) N ; +- _419_ NOR2_X1 + PLACED ( 156660 147099 ) N ; +- _420_ AOI221_X4 + PLACED ( 154680 145634 ) N ; +- _421_ OAI21_X1 + PLACED ( 154052 145638 ) N ; +- _422_ AOI21_X1 + PLACED ( 154587 148048 ) N ; +- _423_ AOI21_X1 + PLACED ( 143490 141523 ) N ; +- _424_ NOR2_X1 + PLACED ( 143322 140749 ) N ; +- _425_ NOR2_X1 + PLACED ( 144558 137449 ) N ; +- _426_ XNOR2_X1 + PLACED ( 147966 135910 ) N ; +- _427_ XNOR2_X1 + PLACED ( 149102 135908 ) N ; +- _428_ NOR2_X1 + PLACED ( 156489 140513 ) N ; +- _429_ AOI221_X2 + PLACED ( 158311 139432 ) N ; +- _430_ OR3_X1 + PLACED ( 151791 141960 ) N ; +- _431_ AOI21_X1 + PLACED ( 155330 140198 ) N ; +- _432_ XNOR2_X1 + PLACED ( 139301 141265 ) N ; +- _433_ XNOR2_X1 + PLACED ( 139680 141829 ) N ; +- _434_ AOI221_X2 + PLACED ( 138419 144918 ) N ; +- _435_ OR3_X1 + PLACED ( 146905 143865 ) N ; +- _436_ AOI22_X1 + PLACED ( 140861 143848 ) N ; +- _437_ NAND2_X1 + PLACED ( 168334 146258 ) N ; +- _438_ OAI221_X1 + PLACED ( 168014 147999 ) N ; +- _439_ NAND2_X1 + PLACED ( 165796 150060 ) N ; +- _440_ XOR2_X1 + PLACED ( 166201 154935 ) N ; +- _441_ XNOR2_X1 + PLACED ( 167248 152669 ) N ; +- _442_ AOI221_X2 + PLACED ( 167732 150220 ) N ; +- _443_ NAND2_X1 + PLACED ( 165388 153295 ) N ; +- _444_ AOI22_X1 + PLACED ( 165143 153366 ) N ; +- _445_ OAI21_X1 + PLACED ( 168073 146837 ) N ; +- _446_ NAND2_X1 + PLACED ( 167232 145373 ) N ; +- _447_ XNOR2_X1 + PLACED ( 163983 140826 ) N ; +- _448_ XNOR2_X1 + PLACED ( 163550 141210 ) N ; +- _449_ NOR2_X1 + PLACED ( 164672 142816 ) N ; +- _450_ AOI221_X1 + PLACED ( 157825 141903 ) N ; +- _451_ OR3_X1 + PLACED ( 163123 143152 ) N ; +- _452_ AOI21_X1 + PLACED ( 161279 140016 ) N ; +- _453_ XNOR2_X1 + PLACED ( 172224 148936 ) N ; +- _454_ XNOR2_X1 + PLACED ( 171783 151104 ) N ; +- _455_ AOI221_X2 + PLACED ( 167426 161477 ) N ; +- _456_ OR3_X1 + PLACED ( 168609 155174 ) N ; +- _457_ AOI22_X1 + PLACED ( 169257 154817 ) N ; +- _458_ AOI22_X1 + PLACED ( 180531 162116 ) N ; +- _459_ NOR2_X1 + PLACED ( 180122 158078 ) N ; +- _460_ XOR2_X1 + PLACED ( 181305 153070 ) N ; +- _461_ XNOR2_X1 + PLACED ( 182845 155207 ) N ; +- _462_ NOR2_X1 + PLACED ( 172346 147213 ) N ; +- _463_ AOI221_X1 + PLACED ( 170277 145112 ) N ; +- _464_ OR3_X1 + PLACED ( 173693 148591 ) N ; +- _465_ AOI21_X1 + PLACED ( 174597 148124 ) N ; +- _466_ XNOR2_X1 + PLACED ( 180500 161059 ) N ; +- _467_ XNOR2_X1 + PLACED ( 180201 163403 ) N ; +- _468_ AOI221_X4 + PLACED ( 171304 165331 ) N ; +- _469_ OR3_X1 + PLACED ( 174199 160554 ) N ; +- _470_ AOI22_X1 + PLACED ( 173854 161281 ) N ; +- _471_ XNOR2_X1 + PLACED ( 171148 169936 ) N ; +- _472_ INV_X1 + PLACED ( 177267 167950 ) N ; +- _473_ NOR2_X1 + PLACED ( 176776 168741 ) N ; +- _474_ XNOR2_X1 + PLACED ( 172225 168093 ) N ; +- _475_ AOI221_X4 + PLACED ( 169901 163180 ) N ; +- _476_ NAND3_X1 + PLACED ( 171250 166061 ) N ; +- _477_ AOI22_X1 + PLACED ( 171239 167266 ) N ; +- _478_ XOR2_X1 + PLACED ( 180619 171376 ) N ; +- _479_ AOI221_X4 + PLACED ( 171672 171394 ) N ; +- _480_ NAND3_X1 + PLACED ( 174735 168936 ) N ; +- _481_ AOI22_X1 + PLACED ( 175864 171219 ) N ; +- _482_ NOR2_X1 + PLACED ( 161902 167399 ) N ; +- _483_ NOR2_X1 + PLACED ( 177862 160495 ) N ; +- _484_ AND3_X1 + PLACED ( 175949 161665 ) N ; +- _485_ NAND3_X1 + PLACED ( 163492 158634 ) N ; +- _486_ NOR3_X1 + PLACED ( 149904 142092 ) N ; +- _487_ NAND2_X1 + PLACED ( 147416 143855 ) N ; +- _488_ NOR4_X1 + PLACED ( 149456 161089 ) N ; +- _489_ NAND3_X1 + PLACED ( 147399 163390 ) N ; +- _490_ NOR3_X1 + PLACED ( 160591 162024 ) N ; +- _491_ NAND3_X1 + PLACED ( 160471 165074 ) N ; +- _492_ AOI221_X4 + PLACED ( 160540 167021 ) N ; +- _493_ NAND3_X1 + PLACED ( 159685 171002 ) N ; +- _494_ AOI221_X1 + PLACED ( 158840 166951 ) N ; +- _495_ MUX2_X1 + PLACED ( 137592 176026 ) N ; +- _496_ NOR2_X4 + PLACED ( 163340 172510 ) N ; +- _497_ BUF_X8 + PLACED ( 160867 175057 ) N ; +- _498_ MUX2_X1 + PLACED ( 139004 175013 ) N ; +- _499_ MUX2_X1 + PLACED ( 133062 155759 ) N ; +- _500_ MUX2_X1 + PLACED ( 135253 158465 ) N ; +- _501_ MUX2_X1 + PLACED ( 133783 170875 ) N ; +- _502_ MUX2_X1 + PLACED ( 135540 170397 ) N ; +- _503_ MUX2_X1 + PLACED ( 153458 175187 ) N ; +- _504_ MUX2_X1 + PLACED ( 153325 174021 ) N ; +- _505_ MUX2_X1 + PLACED ( 153621 135731 ) N ; +- _506_ MUX2_X1 + PLACED ( 153611 136724 ) N ; +- _507_ MUX2_X1 + PLACED ( 135369 150022 ) N ; +- _508_ MUX2_X1 + PLACED ( 136900 148131 ) N ; +- _509_ MUX2_X1 + PLACED ( 140535 135244 ) N ; +- _510_ MUX2_X1 + PLACED ( 143054 135813 ) N ; +- _511_ MUX2_X1 + PLACED ( 135597 137726 ) N ; +- _512_ MUX2_X1 + PLACED ( 137423 137907 ) N ; +- _513_ MUX2_X1 + PLACED ( 134003 150876 ) N ; +- _514_ MUX2_X1 + PLACED ( 136292 152082 ) N ; +- _515_ MUX2_X1 + PLACED ( 161763 159075 ) N ; +- _516_ MUX2_X1 + PLACED ( 161772 160018 ) N ; +- _517_ MUX2_X1 + PLACED ( 169342 139311 ) N ; +- _518_ MUX2_X1 + PLACED ( 169371 139890 ) N ; +- _519_ MUX2_X1 + PLACED ( 176438 141367 ) N ; +- _520_ MUX2_X1 + PLACED ( 176788 142930 ) N ; +- _521_ MUX2_X1 + PLACED ( 181390 146065 ) N ; +- _522_ MUX2_X1 + PLACED ( 181809 148191 ) N ; +- _523_ MUX2_X1 + PLACED ( 176335 155069 ) N ; +- _524_ MUX2_X1 + PLACED ( 180700 155543 ) N ; +- _525_ MUX2_X1 + PLACED ( 166201 175489 ) N ; +- _526_ MUX2_X1 + PLACED ( 168332 174898 ) N ; +- _527_ MUX2_X1 + PLACED ( 181518 174155 ) N ; +- _528_ MUX2_X1 + PLACED ( 181932 171802 ) N ; +- _529_ AOI22_X1 + PLACED ( 162295 153169 ) N ; +- _530_ NOR2_X1 + PLACED ( 159869 154338 ) N ; +- _531_ XNOR2_X1 + PLACED ( 154856 155654 ) N ; +- _532_ XNOR2_X1 + PLACED ( 155555 158290 ) N ; +- _533_ AOI221_X2 + PLACED ( 151851 166951 ) N ; +- _534_ OR3_X1 + PLACED ( 156614 159485 ) N ; +- _535_ AOI22_X1 + PLACED ( 155103 159913 ) N ; +- _536_ DFF_X1 + PLACED ( 131624 156385 ) N ; +- _537_ DFF_X1 + PLACED ( 134480 166656 ) N ; +- _538_ DFF_X1 + PLACED ( 142314 173664 ) N ; +- _539_ DFF_X1 + PLACED ( 146668 172660 ) N ; +- _540_ DFF_X1 + PLACED ( 146175 136391 ) N ; +- _541_ DFF_X1 + PLACED ( 153151 147981 ) N ; +- _542_ DFF_X1 + PLACED ( 153557 136218 ) N ; +- _543_ DFF_X1 + PLACED ( 134329 143114 ) N ; +- _544_ DFF_X1 + PLACED ( 163857 156168 ) N ; +- _545_ DFF_X1 + PLACED ( 160895 138928 ) N ; +- _546_ DFF_X1 + PLACED ( 169189 153613 ) N ; +- _547_ DFF_X1 + PLACED ( 173765 146968 ) N ; +- _548_ DFF_X1 + PLACED ( 172615 160549 ) N ; +- _549_ DFF_X1 + PLACED ( 166591 170619 ) N ; +- _550_ DFF_X1 + PLACED ( 175841 174300 ) N ; +- _551_ DFF_X1 + PLACED ( 163387 167465 ) N ; +- _552_ DFF_X1 + PLACED ( 157326 170174 ) N ; +- _553_ DFF_X1 + PLACED ( 137812 175804 ) N ; +- _554_ DFF_X1 + PLACED ( 133294 160302 ) N ; +- _555_ DFF_X1 + PLACED ( 133946 170562 ) N ; +- _556_ DFF_X1 + PLACED ( 151835 174514 ) N ; +- _557_ DFF_X1 + PLACED ( 152271 135804 ) N ; +- _558_ DFF_X1 + PLACED ( 135081 147619 ) N ; +- _559_ DFF_X1 + PLACED ( 142592 134931 ) N ; +- _560_ DFF_X1 + PLACED ( 136683 137278 ) N ; +- _561_ DFF_X1 + PLACED ( 134360 152146 ) N ; +- _562_ DFF_X1 + PLACED ( 161468 160627 ) N ; +- _563_ DFF_X1 + PLACED ( 168070 137814 ) N ; +- _564_ DFF_X1 + PLACED ( 175780 143064 ) N ; +- _565_ DFF_X1 + PLACED ( 181346 149094 ) N ; +- _566_ DFF_X1 + PLACED ( 182441 155470 ) N ; +- _567_ DFF_X1 + PLACED ( 168706 175919 ) N ; +- _568_ DFF_X1 + PLACED ( 181870 170744 ) N ; +- _569_ DFF_X1 + PLACED ( 153572 159046 ) N ; +- PHY_1 TAPCELL_X1 + FIXED ( 148080 28000 ) FS + SOURCE DIST ; +- PHY_2 TAPCELL_X1 + FIXED ( 148080 30800 ) N + SOURCE DIST ; +- PHY_3 TAPCELL_X1 + FIXED ( 148080 33600 ) FS + SOURCE DIST ; +- PHY_4 TAPCELL_X1 + FIXED ( 148080 36400 ) N + SOURCE DIST ; +- PHY_5 TAPCELL_X1 + FIXED ( 148080 39200 ) FS + SOURCE DIST ; +- PHY_6 TAPCELL_X1 + FIXED ( 148080 42000 ) N + SOURCE DIST ; +- PHY_7 TAPCELL_X1 + FIXED ( 148080 44800 ) FS + SOURCE DIST ; +- PHY_8 TAPCELL_X1 + FIXED ( 148080 47600 ) N + SOURCE DIST ; +- PHY_9 TAPCELL_X1 + FIXED ( 148080 50400 ) FS + SOURCE DIST ; +- PHY_10 TAPCELL_X1 + FIXED ( 148080 53200 ) N + SOURCE DIST ; +- PHY_11 TAPCELL_X1 + FIXED ( 148080 56000 ) FS + SOURCE DIST ; +- PHY_12 TAPCELL_X1 + FIXED ( 148080 58800 ) N + SOURCE DIST ; +- PHY_13 TAPCELL_X1 + FIXED ( 148080 61600 ) FS + SOURCE DIST ; +- PHY_14 TAPCELL_X1 + FIXED ( 148080 64400 ) N + SOURCE DIST ; +- PHY_15 TAPCELL_X1 + FIXED ( 148080 67200 ) FS + SOURCE DIST ; +- PHY_16 TAPCELL_X1 + FIXED ( 148080 70000 ) N + SOURCE DIST ; +- PHY_17 TAPCELL_X1 + FIXED ( 148080 72800 ) FS + SOURCE DIST ; +- PHY_18 TAPCELL_X1 + FIXED ( 148080 75600 ) N + SOURCE DIST ; +- PHY_19 TAPCELL_X1 + FIXED ( 148080 78400 ) FS + SOURCE DIST ; +- PHY_20 TAPCELL_X1 + FIXED ( 148080 81200 ) N + SOURCE DIST ; +- PHY_21 TAPCELL_X1 + FIXED ( 148080 84000 ) FS + SOURCE DIST ; +- PHY_22 TAPCELL_X1 + FIXED ( 148080 86800 ) N + SOURCE DIST ; +- PHY_23 TAPCELL_X1 + FIXED ( 148080 89600 ) FS + SOURCE DIST ; +- PHY_24 TAPCELL_X1 + FIXED ( 148080 92400 ) N + SOURCE DIST ; +- PHY_25 TAPCELL_X1 + FIXED ( 148080 95200 ) FS + SOURCE DIST ; +- PHY_26 TAPCELL_X1 + FIXED ( 148080 98000 ) N + SOURCE DIST ; +- PHY_27 TAPCELL_X1 + FIXED ( 148080 100800 ) FS + SOURCE DIST ; +- PHY_28 TAPCELL_X1 + FIXED ( 148080 103600 ) N + SOURCE DIST ; +- PHY_29 TAPCELL_X1 + FIXED ( 148080 106400 ) FS + SOURCE DIST ; +- PHY_30 TAPCELL_X1 + FIXED ( 148080 109200 ) N + SOURCE DIST ; +- PHY_31 TAPCELL_X1 + FIXED ( 148080 112000 ) FS + SOURCE DIST ; +- PHY_32 TAPCELL_X1 + FIXED ( 148080 114800 ) N + SOURCE DIST ; +- PHY_33 TAPCELL_X1 + FIXED ( 148080 117600 ) FS + SOURCE DIST ; +- PHY_34 TAPCELL_X1 + FIXED ( 148080 120400 ) N + SOURCE DIST ; +- PHY_35 TAPCELL_X1 + FIXED ( 148080 123200 ) FS + SOURCE DIST ; +- PHY_36 TAPCELL_X1 + FIXED ( 148080 126000 ) N + SOURCE DIST ; +- PHY_37 TAPCELL_X1 + FIXED ( 148080 128800 ) FS + SOURCE DIST ; +- PHY_38 TAPCELL_X1 + FIXED ( 148080 131600 ) N + SOURCE DIST ; +- PHY_39 TAPCELL_X1 + FIXED ( 148080 134400 ) FS + SOURCE DIST ; +- PHY_40 TAPCELL_X1 + FIXED ( 148080 137200 ) N + SOURCE DIST ; +- PHY_41 TAPCELL_X1 + FIXED ( 148080 140000 ) FS + SOURCE DIST ; +- PHY_42 TAPCELL_X1 + FIXED ( 148080 142800 ) N + SOURCE DIST ; +- PHY_43 TAPCELL_X1 + FIXED ( 148080 145600 ) FS + SOURCE DIST ; +- PHY_44 TAPCELL_X1 + FIXED ( 148080 148400 ) N + SOURCE DIST ; +- PHY_45 TAPCELL_X1 + FIXED ( 148080 151200 ) FS + SOURCE DIST ; +- PHY_46 TAPCELL_X1 + FIXED ( 148080 154000 ) N + SOURCE DIST ; +- PHY_47 TAPCELL_X1 + FIXED ( 148080 156800 ) FS + SOURCE DIST ; +- PHY_48 TAPCELL_X1 + FIXED ( 148080 159600 ) N + SOURCE DIST ; +- PHY_49 TAPCELL_X1 + FIXED ( 148080 162400 ) FS + SOURCE DIST ; +- PHY_50 TAPCELL_X1 + FIXED ( 148080 165200 ) N + SOURCE DIST ; +- PHY_51 TAPCELL_X1 + FIXED ( 148080 168000 ) FS + SOURCE DIST ; +- PHY_52 TAPCELL_X1 + FIXED ( 148080 170800 ) N + SOURCE DIST ; +- PHY_53 TAPCELL_X1 + FIXED ( 148080 173600 ) FS + SOURCE DIST ; +- PHY_54 TAPCELL_X1 + FIXED ( 148080 176400 ) N + SOURCE DIST ; +- PHY_55 TAPCELL_X1 + FIXED ( 148080 179200 ) FS + SOURCE DIST ; +- PHY_56 TAPCELL_X1 + FIXED ( 148080 182000 ) N + SOURCE DIST ; +- PHY_57 TAPCELL_X1 + FIXED ( 148080 184800 ) FS + SOURCE DIST ; +- PHY_58 TAPCELL_X1 + FIXED ( 148080 187600 ) N + SOURCE DIST ; +- PHY_59 TAPCELL_X1 + FIXED ( 148080 190400 ) FS + SOURCE DIST ; +- PHY_60 TAPCELL_X1 + FIXED ( 148080 193200 ) N + SOURCE DIST ; +- PHY_61 TAPCELL_X1 + FIXED ( 148080 196000 ) FS + SOURCE DIST ; +- PHY_62 TAPCELL_X1 + FIXED ( 148080 198800 ) N + SOURCE DIST ; +- PHY_63 TAPCELL_X1 + FIXED ( 148080 201600 ) FS + SOURCE DIST ; +- PHY_64 TAPCELL_X1 + FIXED ( 148080 204400 ) N + SOURCE DIST ; +- PHY_65 TAPCELL_X1 + FIXED ( 148080 207200 ) FS + SOURCE DIST ; +- PHY_66 TAPCELL_X1 + FIXED ( 148080 210000 ) N + SOURCE DIST ; +- PHY_67 TAPCELL_X1 + FIXED ( 148080 212800 ) FS + SOURCE DIST ; +- PHY_68 TAPCELL_X1 + FIXED ( 148080 215600 ) N + SOURCE DIST ; +- PHY_69 TAPCELL_X1 + FIXED ( 148080 218400 ) FS + SOURCE DIST ; +- PHY_70 TAPCELL_X1 + FIXED ( 148080 221200 ) N + SOURCE DIST ; +- PHY_71 TAPCELL_X1 + FIXED ( 148080 224000 ) FS + SOURCE DIST ; +- PHY_72 TAPCELL_X1 + FIXED ( 148080 226800 ) N + SOURCE DIST ; +- PHY_73 TAPCELL_X1 + FIXED ( 148080 229600 ) FS + SOURCE DIST ; +- PHY_74 TAPCELL_X1 + FIXED ( 148080 232400 ) N + SOURCE DIST ; +- PHY_75 TAPCELL_X1 + FIXED ( 148080 235200 ) FS + SOURCE DIST ; +- PHY_76 TAPCELL_X1 + FIXED ( 148080 238000 ) N + SOURCE DIST ; +- PHY_77 TAPCELL_X1 + FIXED ( 148080 240800 ) FS + SOURCE DIST ; +- PHY_78 TAPCELL_X1 + FIXED ( 148080 243600 ) N + SOURCE DIST ; +- PHY_79 TAPCELL_X1 + FIXED ( 148080 246400 ) FS + SOURCE DIST ; +- PHY_80 TAPCELL_X1 + FIXED ( 148080 249200 ) N + SOURCE DIST ; +- PHY_81 TAPCELL_X1 + FIXED ( 148080 252000 ) FS + SOURCE DIST ; +- PHY_82 TAPCELL_X1 + FIXED ( 148080 254800 ) N + SOURCE DIST ; +- PHY_83 TAPCELL_X1 + FIXED ( 148080 257600 ) FS + SOURCE DIST ; +- PHY_84 TAPCELL_X1 + FIXED ( 148080 260400 ) N + SOURCE DIST ; +- PHY_85 TAPCELL_X1 + FIXED ( 148080 263200 ) FS + SOURCE DIST ; +- PHY_86 TAPCELL_X1 + FIXED ( 28000 28000 ) FS + SOURCE DIST ; +- PHY_87 TAPCELL_X1 + FIXED ( 267400 28000 ) S + SOURCE DIST ; +- PHY_88 TAPCELL_X1 + FIXED ( 28000 30800 ) N + SOURCE DIST ; +- PHY_89 TAPCELL_X1 + FIXED ( 267400 30800 ) FN + SOURCE DIST ; +- PHY_90 TAPCELL_X1 + FIXED ( 28000 33600 ) FS + SOURCE DIST ; +- PHY_91 TAPCELL_X1 + FIXED ( 267400 33600 ) S + SOURCE DIST ; +- PHY_92 TAPCELL_X1 + FIXED ( 28000 36400 ) N + SOURCE DIST ; +- PHY_93 TAPCELL_X1 + FIXED ( 267400 36400 ) FN + SOURCE DIST ; +- PHY_94 TAPCELL_X1 + FIXED ( 28000 39200 ) FS + SOURCE DIST ; +- PHY_95 TAPCELL_X1 + FIXED ( 267400 39200 ) S + SOURCE DIST ; +- PHY_96 TAPCELL_X1 + FIXED ( 28000 42000 ) N + SOURCE DIST ; +- PHY_97 TAPCELL_X1 + FIXED ( 267400 42000 ) FN + SOURCE DIST ; +- PHY_98 TAPCELL_X1 + FIXED ( 28000 44800 ) FS + SOURCE DIST ; +- PHY_99 TAPCELL_X1 + FIXED ( 267400 44800 ) S + SOURCE DIST ; +- PHY_100 TAPCELL_X1 + FIXED ( 28000 47600 ) N + SOURCE DIST ; +- PHY_101 TAPCELL_X1 + FIXED ( 267400 47600 ) FN + SOURCE DIST ; +- PHY_102 TAPCELL_X1 + FIXED ( 28000 50400 ) FS + SOURCE DIST ; +- PHY_103 TAPCELL_X1 + FIXED ( 267400 50400 ) S + SOURCE DIST ; +- PHY_104 TAPCELL_X1 + FIXED ( 28000 53200 ) N + SOURCE DIST ; +- PHY_105 TAPCELL_X1 + FIXED ( 267400 53200 ) FN + SOURCE DIST ; +- PHY_106 TAPCELL_X1 + FIXED ( 28000 56000 ) FS + SOURCE DIST ; +- PHY_107 TAPCELL_X1 + FIXED ( 267400 56000 ) S + SOURCE DIST ; +- PHY_108 TAPCELL_X1 + FIXED ( 28000 58800 ) N + SOURCE DIST ; +- PHY_109 TAPCELL_X1 + FIXED ( 267400 58800 ) FN + SOURCE DIST ; +- PHY_110 TAPCELL_X1 + FIXED ( 28000 61600 ) FS + SOURCE DIST ; +- PHY_111 TAPCELL_X1 + FIXED ( 267400 61600 ) S + SOURCE DIST ; +- PHY_112 TAPCELL_X1 + FIXED ( 28000 64400 ) N + SOURCE DIST ; +- PHY_113 TAPCELL_X1 + FIXED ( 267400 64400 ) FN + SOURCE DIST ; +- PHY_114 TAPCELL_X1 + FIXED ( 28000 67200 ) FS + SOURCE DIST ; +- PHY_115 TAPCELL_X1 + FIXED ( 267400 67200 ) S + SOURCE DIST ; +- PHY_116 TAPCELL_X1 + FIXED ( 28000 70000 ) N + SOURCE DIST ; +- PHY_117 TAPCELL_X1 + FIXED ( 267400 70000 ) FN + SOURCE DIST ; +- PHY_118 TAPCELL_X1 + FIXED ( 28000 72800 ) FS + SOURCE DIST ; +- PHY_119 TAPCELL_X1 + FIXED ( 267400 72800 ) S + SOURCE DIST ; +- PHY_120 TAPCELL_X1 + FIXED ( 28000 75600 ) N + SOURCE DIST ; +- PHY_121 TAPCELL_X1 + FIXED ( 267400 75600 ) FN + SOURCE DIST ; +- PHY_122 TAPCELL_X1 + FIXED ( 28000 78400 ) FS + SOURCE DIST ; +- PHY_123 TAPCELL_X1 + FIXED ( 267400 78400 ) S + SOURCE DIST ; +- PHY_124 TAPCELL_X1 + FIXED ( 28000 81200 ) N + SOURCE DIST ; +- PHY_125 TAPCELL_X1 + FIXED ( 267400 81200 ) FN + SOURCE DIST ; +- PHY_126 TAPCELL_X1 + FIXED ( 28000 84000 ) FS + SOURCE DIST ; +- PHY_127 TAPCELL_X1 + FIXED ( 267400 84000 ) S + SOURCE DIST ; +- PHY_128 TAPCELL_X1 + FIXED ( 28000 86800 ) N + SOURCE DIST ; +- PHY_129 TAPCELL_X1 + FIXED ( 267400 86800 ) FN + SOURCE DIST ; +- PHY_130 TAPCELL_X1 + FIXED ( 28000 89600 ) FS + SOURCE DIST ; +- PHY_131 TAPCELL_X1 + FIXED ( 267400 89600 ) S + SOURCE DIST ; +- PHY_132 TAPCELL_X1 + FIXED ( 28000 92400 ) N + SOURCE DIST ; +- PHY_133 TAPCELL_X1 + FIXED ( 267400 92400 ) FN + SOURCE DIST ; +- PHY_134 TAPCELL_X1 + FIXED ( 28000 95200 ) FS + SOURCE DIST ; +- PHY_135 TAPCELL_X1 + FIXED ( 267400 95200 ) S + SOURCE DIST ; +- PHY_136 TAPCELL_X1 + FIXED ( 28000 98000 ) N + SOURCE DIST ; +- PHY_137 TAPCELL_X1 + FIXED ( 267400 98000 ) FN + SOURCE DIST ; +- PHY_138 TAPCELL_X1 + FIXED ( 28000 100800 ) FS + SOURCE DIST ; +- PHY_139 TAPCELL_X1 + FIXED ( 267400 100800 ) S + SOURCE DIST ; +- PHY_140 TAPCELL_X1 + FIXED ( 28000 103600 ) N + SOURCE DIST ; +- PHY_141 TAPCELL_X1 + FIXED ( 267400 103600 ) FN + SOURCE DIST ; +- PHY_142 TAPCELL_X1 + FIXED ( 28000 106400 ) FS + SOURCE DIST ; +- PHY_143 TAPCELL_X1 + FIXED ( 267400 106400 ) S + SOURCE DIST ; +- PHY_144 TAPCELL_X1 + FIXED ( 28000 109200 ) N + SOURCE DIST ; +- PHY_145 TAPCELL_X1 + FIXED ( 267400 109200 ) FN + SOURCE DIST ; +- PHY_146 TAPCELL_X1 + FIXED ( 28000 112000 ) FS + SOURCE DIST ; +- PHY_147 TAPCELL_X1 + FIXED ( 267400 112000 ) S + SOURCE DIST ; +- PHY_148 TAPCELL_X1 + FIXED ( 28000 114800 ) N + SOURCE DIST ; +- PHY_149 TAPCELL_X1 + FIXED ( 267400 114800 ) FN + SOURCE DIST ; +- PHY_150 TAPCELL_X1 + FIXED ( 28000 117600 ) FS + SOURCE DIST ; +- PHY_151 TAPCELL_X1 + FIXED ( 267400 117600 ) S + SOURCE DIST ; +- PHY_152 TAPCELL_X1 + FIXED ( 28000 120400 ) N + SOURCE DIST ; +- PHY_153 TAPCELL_X1 + FIXED ( 267400 120400 ) FN + SOURCE DIST ; +- PHY_154 TAPCELL_X1 + FIXED ( 28000 123200 ) FS + SOURCE DIST ; +- PHY_155 TAPCELL_X1 + FIXED ( 267400 123200 ) S + SOURCE DIST ; +- PHY_156 TAPCELL_X1 + FIXED ( 28000 126000 ) N + SOURCE DIST ; +- PHY_157 TAPCELL_X1 + FIXED ( 267400 126000 ) FN + SOURCE DIST ; +- PHY_158 TAPCELL_X1 + FIXED ( 28000 128800 ) FS + SOURCE DIST ; +- PHY_159 TAPCELL_X1 + FIXED ( 267400 128800 ) S + SOURCE DIST ; +- PHY_160 TAPCELL_X1 + FIXED ( 28000 131600 ) N + SOURCE DIST ; +- PHY_161 TAPCELL_X1 + FIXED ( 267400 131600 ) FN + SOURCE DIST ; +- PHY_162 TAPCELL_X1 + FIXED ( 28000 134400 ) FS + SOURCE DIST ; +- PHY_163 TAPCELL_X1 + FIXED ( 267400 134400 ) S + SOURCE DIST ; +- PHY_164 TAPCELL_X1 + FIXED ( 28000 137200 ) N + SOURCE DIST ; +- PHY_165 TAPCELL_X1 + FIXED ( 267400 137200 ) FN + SOURCE DIST ; +- PHY_166 TAPCELL_X1 + FIXED ( 28000 140000 ) FS + SOURCE DIST ; +- PHY_167 TAPCELL_X1 + FIXED ( 267400 140000 ) S + SOURCE DIST ; +- PHY_168 TAPCELL_X1 + FIXED ( 28000 142800 ) N + SOURCE DIST ; +- PHY_169 TAPCELL_X1 + FIXED ( 267400 142800 ) FN + SOURCE DIST ; +- PHY_170 TAPCELL_X1 + FIXED ( 28000 145600 ) FS + SOURCE DIST ; +- PHY_171 TAPCELL_X1 + FIXED ( 267400 145600 ) S + SOURCE DIST ; +- PHY_172 TAPCELL_X1 + FIXED ( 28000 148400 ) N + SOURCE DIST ; +- PHY_173 TAPCELL_X1 + FIXED ( 267400 148400 ) FN + SOURCE DIST ; +- PHY_174 TAPCELL_X1 + FIXED ( 28000 151200 ) FS + SOURCE DIST ; +- PHY_175 TAPCELL_X1 + FIXED ( 267400 151200 ) S + SOURCE DIST ; +- PHY_176 TAPCELL_X1 + FIXED ( 28000 154000 ) N + SOURCE DIST ; +- PHY_177 TAPCELL_X1 + FIXED ( 267400 154000 ) FN + SOURCE DIST ; +- PHY_178 TAPCELL_X1 + FIXED ( 28000 156800 ) FS + SOURCE DIST ; +- PHY_179 TAPCELL_X1 + FIXED ( 267400 156800 ) S + SOURCE DIST ; +- PHY_180 TAPCELL_X1 + FIXED ( 28000 159600 ) N + SOURCE DIST ; +- PHY_181 TAPCELL_X1 + FIXED ( 267400 159600 ) FN + SOURCE DIST ; +- PHY_182 TAPCELL_X1 + FIXED ( 28000 162400 ) FS + SOURCE DIST ; +- PHY_183 TAPCELL_X1 + FIXED ( 267400 162400 ) S + SOURCE DIST ; +- PHY_184 TAPCELL_X1 + FIXED ( 28000 165200 ) N + SOURCE DIST ; +- PHY_185 TAPCELL_X1 + FIXED ( 267400 165200 ) FN + SOURCE DIST ; +- PHY_186 TAPCELL_X1 + FIXED ( 28000 168000 ) FS + SOURCE DIST ; +- PHY_187 TAPCELL_X1 + FIXED ( 267400 168000 ) S + SOURCE DIST ; +- PHY_188 TAPCELL_X1 + FIXED ( 28000 170800 ) N + SOURCE DIST ; +- PHY_189 TAPCELL_X1 + FIXED ( 267400 170800 ) FN + SOURCE DIST ; +- PHY_190 TAPCELL_X1 + FIXED ( 28000 173600 ) FS + SOURCE DIST ; +- PHY_191 TAPCELL_X1 + FIXED ( 267400 173600 ) S + SOURCE DIST ; +- PHY_192 TAPCELL_X1 + FIXED ( 28000 176400 ) N + SOURCE DIST ; +- PHY_193 TAPCELL_X1 + FIXED ( 267400 176400 ) FN + SOURCE DIST ; +- PHY_194 TAPCELL_X1 + FIXED ( 28000 179200 ) FS + SOURCE DIST ; +- PHY_195 TAPCELL_X1 + FIXED ( 267400 179200 ) S + SOURCE DIST ; +- PHY_196 TAPCELL_X1 + FIXED ( 28000 182000 ) N + SOURCE DIST ; +- PHY_197 TAPCELL_X1 + FIXED ( 267400 182000 ) FN + SOURCE DIST ; +- PHY_198 TAPCELL_X1 + FIXED ( 28000 184800 ) FS + SOURCE DIST ; +- PHY_199 TAPCELL_X1 + FIXED ( 267400 184800 ) S + SOURCE DIST ; +- PHY_200 TAPCELL_X1 + FIXED ( 28000 187600 ) N + SOURCE DIST ; +- PHY_201 TAPCELL_X1 + FIXED ( 267400 187600 ) FN + SOURCE DIST ; +- PHY_202 TAPCELL_X1 + FIXED ( 28000 190400 ) FS + SOURCE DIST ; +- PHY_203 TAPCELL_X1 + FIXED ( 267400 190400 ) S + SOURCE DIST ; +- PHY_204 TAPCELL_X1 + FIXED ( 28000 193200 ) N + SOURCE DIST ; +- PHY_205 TAPCELL_X1 + FIXED ( 267400 193200 ) FN + SOURCE DIST ; +- PHY_206 TAPCELL_X1 + FIXED ( 28000 196000 ) FS + SOURCE DIST ; +- PHY_207 TAPCELL_X1 + FIXED ( 267400 196000 ) S + SOURCE DIST ; +- PHY_208 TAPCELL_X1 + FIXED ( 28000 198800 ) N + SOURCE DIST ; +- PHY_209 TAPCELL_X1 + FIXED ( 267400 198800 ) FN + SOURCE DIST ; +- PHY_210 TAPCELL_X1 + FIXED ( 28000 201600 ) FS + SOURCE DIST ; +- PHY_211 TAPCELL_X1 + FIXED ( 267400 201600 ) S + SOURCE DIST ; +- PHY_212 TAPCELL_X1 + FIXED ( 28000 204400 ) N + SOURCE DIST ; +- PHY_213 TAPCELL_X1 + FIXED ( 267400 204400 ) FN + SOURCE DIST ; +- PHY_214 TAPCELL_X1 + FIXED ( 28000 207200 ) FS + SOURCE DIST ; +- PHY_215 TAPCELL_X1 + FIXED ( 267400 207200 ) S + SOURCE DIST ; +- PHY_216 TAPCELL_X1 + FIXED ( 28000 210000 ) N + SOURCE DIST ; +- PHY_217 TAPCELL_X1 + FIXED ( 267400 210000 ) FN + SOURCE DIST ; +- PHY_218 TAPCELL_X1 + FIXED ( 28000 212800 ) FS + SOURCE DIST ; +- PHY_219 TAPCELL_X1 + FIXED ( 267400 212800 ) S + SOURCE DIST ; +- PHY_220 TAPCELL_X1 + FIXED ( 28000 215600 ) N + SOURCE DIST ; +- PHY_221 TAPCELL_X1 + FIXED ( 267400 215600 ) FN + SOURCE DIST ; +- PHY_222 TAPCELL_X1 + FIXED ( 28000 218400 ) FS + SOURCE DIST ; +- PHY_223 TAPCELL_X1 + FIXED ( 267400 218400 ) S + SOURCE DIST ; +- PHY_224 TAPCELL_X1 + FIXED ( 28000 221200 ) N + SOURCE DIST ; +- PHY_225 TAPCELL_X1 + FIXED ( 267400 221200 ) FN + SOURCE DIST ; +- PHY_226 TAPCELL_X1 + FIXED ( 28000 224000 ) FS + SOURCE DIST ; +- PHY_227 TAPCELL_X1 + FIXED ( 267400 224000 ) S + SOURCE DIST ; +- PHY_228 TAPCELL_X1 + FIXED ( 28000 226800 ) N + SOURCE DIST ; +- PHY_229 TAPCELL_X1 + FIXED ( 267400 226800 ) FN + SOURCE DIST ; +- PHY_230 TAPCELL_X1 + FIXED ( 28000 229600 ) FS + SOURCE DIST ; +- PHY_231 TAPCELL_X1 + FIXED ( 267400 229600 ) S + SOURCE DIST ; +- PHY_232 TAPCELL_X1 + FIXED ( 28000 232400 ) N + SOURCE DIST ; +- PHY_233 TAPCELL_X1 + FIXED ( 267400 232400 ) FN + SOURCE DIST ; +- PHY_234 TAPCELL_X1 + FIXED ( 28000 235200 ) FS + SOURCE DIST ; +- PHY_235 TAPCELL_X1 + FIXED ( 267400 235200 ) S + SOURCE DIST ; +- PHY_236 TAPCELL_X1 + FIXED ( 28000 238000 ) N + SOURCE DIST ; +- PHY_237 TAPCELL_X1 + FIXED ( 267400 238000 ) FN + SOURCE DIST ; +- PHY_238 TAPCELL_X1 + FIXED ( 28000 240800 ) FS + SOURCE DIST ; +- PHY_239 TAPCELL_X1 + FIXED ( 267400 240800 ) S + SOURCE DIST ; +- PHY_240 TAPCELL_X1 + FIXED ( 28000 243600 ) N + SOURCE DIST ; +- PHY_241 TAPCELL_X1 + FIXED ( 267400 243600 ) FN + SOURCE DIST ; +- PHY_242 TAPCELL_X1 + FIXED ( 28000 246400 ) FS + SOURCE DIST ; +- PHY_243 TAPCELL_X1 + FIXED ( 267400 246400 ) S + SOURCE DIST ; +- PHY_244 TAPCELL_X1 + FIXED ( 28000 249200 ) N + SOURCE DIST ; +- PHY_245 TAPCELL_X1 + FIXED ( 267400 249200 ) FN + SOURCE DIST ; +- PHY_246 TAPCELL_X1 + FIXED ( 28000 252000 ) FS + SOURCE DIST ; +- PHY_247 TAPCELL_X1 + FIXED ( 267400 252000 ) S + SOURCE DIST ; +- PHY_248 TAPCELL_X1 + FIXED ( 28000 254800 ) N + SOURCE DIST ; +- PHY_249 TAPCELL_X1 + FIXED ( 267400 254800 ) FN + SOURCE DIST ; +- PHY_250 TAPCELL_X1 + FIXED ( 28000 257600 ) FS + SOURCE DIST ; +- PHY_251 TAPCELL_X1 + FIXED ( 267400 257600 ) S + SOURCE DIST ; +- PHY_252 TAPCELL_X1 + FIXED ( 28000 260400 ) N + SOURCE DIST ; +- PHY_253 TAPCELL_X1 + FIXED ( 267400 260400 ) FN + SOURCE DIST ; +- PHY_254 TAPCELL_X1 + FIXED ( 28000 263200 ) FS + SOURCE DIST ; +- PHY_255 TAPCELL_X1 + FIXED ( 267400 263200 ) S + SOURCE DIST ; +END COMPONENTS + +PINS 54 ; +- clk + NET clk + DIRECTION INPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 184430 296000 ) S ; +- req_msg\[0\] + NET req_msg\[0\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 296000 215740 ) W ; +- req_msg\[1\] + NET req_msg\[1\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 0 203420 ) E ; +- req_msg\[2\] + NET req_msg\[2\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 0 75740 ) E ; +- req_msg\[3\] + NET req_msg\[3\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 296000 45500 ) W ; +- req_msg\[4\] + NET req_msg\[4\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 192270 0 ) N ; +- req_msg\[5\] + NET req_msg\[5\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 296000 88060 ) W ; +- req_msg\[6\] + NET req_msg\[6\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 0 160860 ) E ; +- req_msg\[7\] + NET req_msg\[7\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 43310 0 ) N ; +- req_msg\[8\] + NET req_msg\[8\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 64590 0 ) N ; +- req_msg\[9\] + NET req_msg\[9\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 0 97020 ) E ; +- req_msg\[10\] + NET req_msg\[10\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 0 288540 ) E ; +- req_msg\[11\] + NET req_msg\[11\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 277390 0 ) N ; +- req_msg\[12\] + NET req_msg\[12\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 248270 296000 ) S ; +- req_msg\[13\] + NET req_msg\[13\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 35470 296000 ) S ; +- req_msg\[14\] + NET req_msg\[14\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 0 267260 ) E ; +- req_msg\[15\] + NET req_msg\[15\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 0 118300 ) E ; +- req_msg\[16\] + NET req_msg\[16\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 296000 194460 ) W ; +- req_msg\[17\] + NET req_msg\[17\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 296000 2940 ) W ; +- req_msg\[18\] + NET req_msg\[18\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 296000 173180 ) W ; +- req_msg\[19\] + NET req_msg\[19\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 170990 0 ) N ; +- req_msg\[20\] + NET req_msg\[20\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 99310 296000 ) S ; +- req_msg\[21\] + NET req_msg\[21\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 0 139580 ) E ; +- req_msg\[22\] + NET req_msg\[22\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 296000 24220 ) W ; +- req_msg\[23\] + NET req_msg\[23\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 56750 296000 ) S ; +- req_msg\[24\] + NET req_msg\[24\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 0 182140 ) E ; +- req_msg\[25\] + NET req_msg\[25\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 296000 66780 ) W ; +- req_msg\[26\] + NET req_msg\[26\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 234830 0 ) N ; +- req_msg\[27\] + NET req_msg\[27\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 0 245980 ) E ; +- req_msg\[28\] + NET req_msg\[28\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 120590 296000 ) S ; +- req_msg\[29\] + NET req_msg\[29\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 78030 296000 ) S ; +- req_msg\[30\] + NET req_msg\[30\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 149710 0 ) N ; +- req_msg\[31\] + NET req_msg\[31\] + DIRECTION INPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 141870 296000 ) S ; +- req_rdy + NET req_rdy + DIRECTION OUTPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 205710 296000 ) S ; +- req_val + NET req_val + DIRECTION INPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 163150 296000 ) S ; +- reset + NET reset + DIRECTION INPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 22030 0 ) N ; +- resp_msg\[0\] + NET resp_msg\[0\] + DIRECTION OUTPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 296000 237020 ) W ; +- resp_msg\[1\] + NET resp_msg\[1\] + DIRECTION OUTPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 128430 0 ) N ; +- resp_msg\[2\] + NET resp_msg\[2\] + DIRECTION OUTPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 290830 296000 ) S ; +- resp_msg\[3\] + NET resp_msg\[3\] + DIRECTION OUTPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 296000 279580 ) W ; +- resp_msg\[4\] + NET resp_msg\[4\] + DIRECTION OUTPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 269550 296000 ) S ; +- resp_msg\[5\] + NET resp_msg\[5\] + DIRECTION OUTPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 750 0 ) N ; +- resp_msg\[6\] + NET resp_msg\[6\] + DIRECTION OUTPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 296000 151900 ) W ; +- resp_msg\[7\] + NET resp_msg\[7\] + DIRECTION OUTPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 14190 296000 ) S ; +- resp_msg\[8\] + NET resp_msg\[8\] + DIRECTION OUTPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 107150 0 ) N ; +- resp_msg\[9\] + NET resp_msg\[9\] + DIRECTION OUTPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 296000 130620 ) W ; +- resp_msg\[10\] + NET resp_msg\[10\] + DIRECTION OUTPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 296000 109340 ) W ; +- resp_msg\[11\] + NET resp_msg\[11\] + DIRECTION OUTPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 85870 0 ) N ; +- resp_msg\[12\] + NET resp_msg\[12\] + DIRECTION OUTPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 226990 296000 ) S ; +- resp_msg\[13\] + NET resp_msg\[13\] + DIRECTION OUTPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 213550 0 ) N ; +- resp_msg\[14\] + NET resp_msg\[14\] + DIRECTION OUTPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 0 224700 ) E ; +- resp_msg\[15\] + NET resp_msg\[15\] + DIRECTION OUTPUT + USE SIGNAL + + LAYER metal6 ( -140 0 ) ( 140 280 ) + PLACED ( 256110 0 ) N ; +- resp_rdy + NET resp_rdy + DIRECTION INPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 296000 258300 ) W ; +- resp_val + NET resp_val + DIRECTION OUTPUT + USE SIGNAL + + LAYER metal5 ( -140 0 ) ( 140 280 ) + PLACED ( 0 54460 ) E ; +END PINS + +NETS 364 ; +- _000_ + ( _494_ ZN ) ( _552_ D ) ; +- _001_ + ( _492_ ZN ) ( _551_ D ) ; +- _002_ + ( _481_ ZN ) ( _550_ D ) ; +- _003_ + ( _422_ ZN ) ( _541_ D ) ; +- _004_ + ( _413_ ZN ) ( _540_ D ) ; +- _005_ + ( _402_ ZN ) ( _539_ D ) ; +- _006_ + ( _394_ ZN ) ( _538_ D ) ; +- _007_ + ( _383_ ZN ) ( _537_ D ) ; +- _008_ + ( _370_ ZN ) ( _536_ D ) ; +- _009_ + ( _477_ ZN ) ( _549_ D ) ; +- _010_ + ( _470_ ZN ) ( _548_ D ) ; +- _011_ + ( _465_ ZN ) ( _547_ D ) ; +- _012_ + ( _457_ ZN ) ( _546_ D ) ; +- _013_ + ( _452_ ZN ) ( _545_ D ) ; +- _014_ + ( _444_ ZN ) ( _544_ D ) ; +- _015_ + ( _535_ ZN ) ( _569_ D ) ; +- _016_ + ( _436_ ZN ) ( _543_ D ) ; +- _017_ + ( _431_ ZN ) ( _542_ D ) ; +- _018_ + ( _528_ Z ) ( _568_ D ) ; +- _019_ + ( _508_ Z ) ( _558_ D ) ; +- _020_ + ( _506_ Z ) ( _557_ D ) ; +- _021_ + ( _504_ Z ) ( _556_ D ) ; +- _022_ + ( _498_ Z ) ( _553_ D ) ; +- _023_ + ( _502_ Z ) ( _555_ D ) ; +- _024_ + ( _500_ Z ) ( _554_ D ) ; +- _025_ + ( _526_ Z ) ( _567_ D ) ; +- _026_ + ( _524_ Z ) ( _566_ D ) ; +- _027_ + ( _522_ Z ) ( _565_ D ) ; +- _028_ + ( _520_ Z ) ( _564_ D ) ; +- _029_ + ( _518_ Z ) ( _563_ D ) ; +- _030_ + ( _516_ Z ) ( _562_ D ) ; +- _031_ + ( _514_ Z ) ( _561_ D ) ; +- _032_ + ( _512_ Z ) ( _560_ D ) ; +- _033_ + ( _510_ Z ) ( _559_ D ) ; +- _034_ + ( _276_ ZN ) ( _277_ A ) ( _496_ A2 ) ( _515_ S ) + ( _517_ S ) ( _519_ S ) ( _521_ S ) ( _523_ S ) + ( _525_ S ) ( _527_ S ) ; +- _035_ + ( _278_ ZN ) ( _279_ A1 ) ( _333_ A1 ) ( _370_ B2 ) ; +- _036_ + ( _279_ ZN ) ( _280_ A ) ( _359_ B2 ) ; +- _037_ + ( _280_ ZN ) ( _351_ A1 ) ( _352_ B1 ) ; +- _038_ + ( _281_ ZN ) ( _282_ A1 ) ( _335_ A1 ) ( _489_ A2 ) ; +- _039_ + ( _282_ ZN ) ( _285_ A1 ) ( _338_ A ) ; +- _040_ + ( _283_ ZN ) ( _284_ A1 ) ( _336_ A1 ) ( _401_ A2 ) ; +- _041_ + ( _284_ ZN ) ( _285_ A2 ) ( _387_ A ) ; +- _042_ + ( _285_ ZN ) ( _289_ A1 ) ( _357_ A1 ) ( _372_ A2 ) + ( _374_ A2 ) ; +- _043_ + ( _286_ ZN ) ( _287_ A1 ) ( _340_ A1 ) ( _489_ A3 ) ; +- _044_ + ( _287_ ZN ) ( _288_ A ) ; +- _045_ + ( _288_ ZN ) ( _289_ A2 ) ( _339_ A2 ) ( _357_ A3 ) ; +- _046_ + ( _289_ ZN ) ( _332_ A ) ( _350_ B2 ) ; +- _047_ + ( _290_ ZN ) ( _291_ A1 ) ( _343_ C1 ) ( _344_ A1 ) + ( _430_ A2 ) ; +- _048_ + ( _291_ ZN ) ( _293_ A ) ; +- _049_ + ( _292_ ZN ) ( _293_ B2 ) ( _423_ B2 ) ( _424_ A1 ) + ( _436_ B2 ) ; +- _050_ + ( _293_ ZN ) ( _299_ A1 ) ( _372_ A1 ) ( _404_ A ) + ( _414_ A ) ; +- _051_ + ( _294_ ZN ) ( _295_ A1 ) ( _346_ A1 ) ( _412_ A2 ) ; +- _052_ + ( _295_ ZN ) ( _298_ A1 ) ( _345_ A ) ( _348_ B1 ) ; +- _053_ + ( _296_ ZN ) ( _297_ A1 ) ( _347_ A1 ) ( _406_ B2 ) ; +- _054_ + ( _297_ ZN ) ( _298_ A2 ) ( _345_ B ) ( _403_ A ) + ( _405_ A ) ; +- _055_ + ( _298_ ZN ) ( _299_ A2 ) ( _372_ A3 ) ; +- _056_ + ( _299_ ZN ) ( _332_ B ) ( _358_ A ) ( _385_ A ) ; +- _057_ + ( _300_ ZN ) ( _301_ A1 ) ( _304_ B1 ) ( _464_ A2 ) ; +- _058_ + ( _301_ ZN ) ( _303_ A1 ) ( _314_ A2 ) ; +- _059_ + ( _302_ ZN ) ( _303_ A3 ) ( _470_ B2 ) ; +- _060_ + ( _303_ ZN ) ( _304_ A ) ; +- _061_ + ( _304_ ZN ) ( _305_ A ) ; +- _062_ + ( _305_ ZN ) ( _315_ A1 ) ( _438_ C2 ) ; +- _063_ + ( _306_ ZN ) ( _307_ A1 ) ( _310_ C1 ) ( _477_ B2 ) ; +- _064_ + ( _307_ ZN ) ( _308_ A ) ; +- _065_ + ( _308_ ZN ) ( _311_ A1 ) ( _458_ A1 ) ; +- _066_ + ( _309_ ZN ) ( _310_ B ) ( _481_ B2 ) ; +- _067_ + ( _310_ ZN ) ( _311_ A2 ) ( _458_ A2 ) ; +- _068_ + ( _311_ ZN ) ( _314_ A1 ) ( _467_ A ) ; +- _069_ + ( _312_ ZN ) ( _313_ A1 ) ( _458_ B1 ) ( _469_ A2 ) + ( _484_ A2 ) ; +- _070_ + ( _313_ ZN ) ( _314_ A3 ) ( _459_ A2 ) ; +- _071_ + ( _314_ ZN ) ( _315_ A2 ) ( _438_ C1 ) ; +- _072_ + ( _315_ ZN ) ( _324_ A1 ) ( _445_ A ) ( _454_ A ) ; +- _073_ + ( _316_ ZN ) ( _317_ A1 ) ( _456_ A2 ) ( _485_ A2 ) ; +- _074_ + ( _317_ ZN ) ( _324_ A2 ) ; +- _075_ + ( _318_ ZN ) ( _319_ A1 ) ( _330_ B1 ) ( _438_ B1 ) + ( _451_ A2 ) ; +- _076_ + ( _319_ ZN ) ( _324_ A3 ) ( _329_ A1 ) ; +- _077_ + ( _320_ ZN ) ( _321_ A1 ) ( _325_ A1 ) ( _444_ B2 ) + ( _529_ B1 ) ; +- _078_ + ( _321_ ZN ) ( _323_ A ) ; +- _079_ + ( _322_ ZN ) ( _323_ B1 ) ( _326_ B1 ) ( _485_ A3 ) + ( _534_ A2 ) ; +- _080_ + ( _323_ ZN ) ( _324_ A4 ) ( _331_ C2 ) ; +- _081_ + ( _324_ ZN ) ( _332_ C1 ) ( _358_ C1 ) ( _371_ A1 ) + ( _404_ C1 ) ( _414_ B1 ) ; +- _082_ + ( _325_ ZN ) ( _326_ A ) ( _530_ A2 ) ; +- _083_ + ( _326_ ZN ) ( _331_ A ) ; +- _084_ + ( _327_ ZN ) ( _331_ B2 ) ( _535_ B2 ) ; +- _085_ + ( _328_ ZN ) ( _329_ A3 ) ( _437_ A1 ) ( _445_ B2 ) + ( _457_ B2 ) ; +- _086_ + ( _329_ ZN ) ( _330_ A ) ; +- _087_ + ( _330_ ZN ) ( _331_ C1 ) ( _439_ A2 ) ( _529_ A2 ) ; +- _088_ + ( _331_ ZN ) ( _332_ C2 ) ( _358_ C2 ) ( _371_ A2 ) + ( _404_ C2 ) ( _414_ B2 ) ; +- _089_ + ( _332_ ZN ) ( _351_ A2 ) ( _352_ A1 ) ; +- _090_ + ( _333_ ZN ) ( _334_ A ) ; +- _091_ + ( _334_ ZN ) ( _351_ A3 ) ( _352_ B2 ) ( _357_ A2 ) + ( _359_ A ) ; +- _092_ + ( _335_ ZN ) ( _337_ A1 ) ( _388_ A4 ) ( _389_ B2 ) ; +- _093_ + ( _336_ ZN ) ( _337_ A2 ) ( _386_ A ) ; +- _094_ + ( _337_ ZN ) ( _339_ A1 ) ( _374_ B2 ) ; +- _095_ + ( _338_ ZN ) ( _339_ A3 ) ( _374_ B1 ) ( _388_ A1 ) + ( _389_ B1 ) ; +- _096_ + ( _339_ ZN ) ( _341_ A1 ) ; +- _097_ + ( _340_ ZN ) ( _341_ A2 ) ; +- _098_ + ( _341_ ZN ) ( _350_ A ) ( _359_ B1 ) ; +- _099_ + ( _342_ ZN ) ( _343_ A ) ( _435_ A2 ) ( _487_ A2 ) ; +- _100_ + ( _343_ ZN ) ( _345_ C1 ) ( _405_ B1 ) ( _415_ A1 ) ; +- _101_ + ( _344_ ZN ) ( _345_ C2 ) ( _405_ B2 ) ( _415_ A2 ) ; +- _102_ + ( _345_ ZN ) ( _349_ A1 ) ( _360_ B1 ) ; +- _103_ + ( _346_ ZN ) ( _348_ A ) ; +- _104_ + ( _347_ ZN ) ( _348_ B2 ) ( _416_ A3 ) ( _417_ B2 ) ; +- _105_ + ( _348_ ZN ) ( _349_ A2 ) ( _360_ B2 ) ; +- _106_ + ( _349_ ZN ) ( _350_ B1 ) ( _374_ A1 ) ( _384_ A ) ; +- _107_ + ( _350_ ZN ) ( _351_ A4 ) ( _352_ A2 ) ; +- _108_ + ( _351_ ZN ) ( _353_ A1 ) ( _368_ B2 ) ; +- _109_ + ( _352_ ZN ) ( _353_ A2 ) ( _368_ B1 ) ; +- _110_ + ( _354_ Z ) ( _365_ A ) ( _420_ A ) ( _429_ A ) + ( _434_ A ) ( _442_ A ) ( _450_ A ) ( _455_ A ) + ( _463_ A ) ( _468_ A ) ( _475_ A ) ; +- _111_ + ( _355_ ZN ) ( _356_ A ) ( _362_ A1 ) ( _382_ B1 ) + ( _393_ B1 ) ( _455_ B1 ) ( _468_ B1 ) ( _475_ B1 ) + ( _479_ B1 ) ( _493_ A2 ) ( _533_ B1 ) ; +- _112_ + ( _356_ Z ) ( _365_ B1 ) ( _399_ B1 ) ( _411_ B1 ) + ( _420_ B1 ) ( _429_ B1 ) ( _434_ B1 ) ( _442_ B1 ) + ( _450_ B1 ) ( _463_ B1 ) ( _494_ B1 ) ; +- _113_ + ( _357_ ZN ) ( _358_ B ) ( _360_ A ) ; +- _114_ + ( _358_ ZN ) ( _361_ A1 ) ; +- _115_ + ( _359_ ZN ) ( _361_ A2 ) ; +- _116_ + ( _360_ ZN ) ( _361_ A3 ) ; +- _117_ + ( _361_ ZN ) ( _364_ A1 ) ( _366_ A1 ) ( _400_ A ) + ( _491_ A1 ) ( _534_ A1 ) ; +- _118_ + ( _362_ ZN ) ( _363_ A ) ( _366_ A2 ) ( _476_ A2 ) + ( _480_ A2 ) ( _491_ A2 ) ; +- _119_ + ( _363_ ZN ) ( _364_ A2 ) ( _401_ A3 ) ( _412_ A3 ) + ( _430_ A3 ) ( _435_ A3 ) ( _451_ A3 ) ( _456_ A3 ) + ( _464_ A3 ) ( _469_ A3 ) ( _534_ A3 ) ; +- _120_ + ( _364_ ZN ) ( _365_ C1 ) ( _382_ C1 ) ( _393_ C1 ) + ( _420_ C1 ) ( _443_ A1 ) ( _475_ C1 ) ( _479_ C1 ) + ( _496_ A1 ) ; +- _121_ + ( _365_ ZN ) ( _370_ A1 ) ; +- _122_ + ( _366_ ZN ) ( _367_ A ) ( _399_ C2 ) ( _411_ C2 ) + ( _429_ C2 ) ( _468_ C1 ) ( _533_ C2 ) ; +- _123_ + ( _367_ Z ) ( _368_ A ) ( _381_ A2 ) ( _392_ A2 ) + ( _421_ A ) ( _434_ C1 ) ( _442_ C1 ) ( _450_ C1 ) + ( _455_ C1 ) ( _463_ C1 ) ( _494_ C1 ) ; +- _124_ + ( _368_ ZN ) ( _370_ A2 ) ; +- _125_ + ( _369_ Z ) ( _370_ B1 ) ( _399_ A ) ( _411_ A ) + ( _436_ B1 ) ( _444_ B1 ) ( _457_ B1 ) ( _470_ B1 ) + ( _477_ B1 ) ( _481_ B1 ) ( _535_ B1 ) ; +- _126_ + ( _371_ ZN ) ( _373_ A1 ) ( _386_ C1 ) ( _395_ B1 ) + ( _423_ A ) ( _433_ A ) ; +- _127_ + ( _372_ ZN ) ( _373_ A2 ) ; +- _128_ + ( _373_ ZN ) ( _375_ A1 ) ; +- _129_ + ( _374_ ZN ) ( _375_ A2 ) ; +- _130_ + ( _375_ ZN ) ( _377_ A ) ; +- _131_ + ( _376_ Z ) ( _377_ B ) ; +- _132_ + ( _378_ ZN ) ( _379_ A ) ( _493_ A1 ) ; +- _133_ + ( _379_ Z ) ( _380_ A1 ) ( _391_ A1 ) ( _398_ A1 ) + ( _410_ A1 ) ( _419_ A1 ) ( _428_ A1 ) ( _449_ A1 ) + ( _462_ A1 ) ( _482_ A1 ) ( _492_ C2 ) ; +- _134_ + ( _380_ ZN ) ( _383_ A ) ; +- _135_ + ( _381_ ZN ) ( _383_ B1 ) ; +- _136_ + ( _382_ ZN ) ( _383_ B2 ) ; +- _137_ + ( _384_ ZN ) ( _386_ B ) ( _395_ A ) ; +- _138_ + ( _385_ ZN ) ( _386_ C2 ) ( _395_ B2 ) ; +- _139_ + ( _386_ ZN ) ( _388_ A2 ) ( _389_ A1 ) ; +- _140_ + ( _387_ ZN ) ( _388_ A3 ) ( _389_ A2 ) ; +- _141_ + ( _388_ ZN ) ( _390_ A1 ) ; +- _142_ + ( _389_ ZN ) ( _390_ A2 ) ; +- _143_ + ( _391_ ZN ) ( _394_ A ) ; +- _144_ + ( _392_ ZN ) ( _394_ B1 ) ; +- _145_ + ( _393_ ZN ) ( _394_ B2 ) ; +- _146_ + ( _395_ ZN ) ( _397_ A ) ; +- _147_ + ( _396_ Z ) ( _397_ B ) ; +- _148_ + ( _398_ ZN ) ( _402_ A ) ; +- _149_ + ( _399_ ZN ) ( _402_ B1 ) ; +- _150_ + ( _400_ Z ) ( _401_ A1 ) ( _412_ A1 ) ( _430_ A1 ) + ( _435_ A1 ) ( _451_ A1 ) ( _456_ A1 ) ( _464_ A1 ) + ( _469_ A1 ) ( _476_ A1 ) ( _480_ A1 ) ; +- _151_ + ( _401_ ZN ) ( _402_ B2 ) ; +- _152_ + ( _403_ ZN ) ( _404_ B ) ( _416_ A1 ) ( _417_ B1 ) ; +- _153_ + ( _404_ ZN ) ( _407_ A1 ) ; +- _154_ + ( _405_ ZN ) ( _406_ A ) ; +- _155_ + ( _406_ ZN ) ( _407_ A2 ) ; +- _156_ + ( _407_ ZN ) ( _409_ A ) ; +- _157_ + ( _408_ ZN ) ( _409_ B ) ; +- _158_ + ( _410_ ZN ) ( _413_ A ) ; +- _159_ + ( _411_ ZN ) ( _413_ B1 ) ; +- _160_ + ( _412_ ZN ) ( _413_ B2 ) ; +- _161_ + ( _414_ ZN ) ( _416_ A2 ) ( _417_ A1 ) ; +- _162_ + ( _415_ ZN ) ( _416_ A4 ) ( _417_ A2 ) ; +- _163_ + ( _416_ ZN ) ( _418_ A1 ) ( _421_ B2 ) ; +- _164_ + ( _417_ ZN ) ( _418_ A2 ) ( _421_ B1 ) ; +- _165_ + ( _419_ ZN ) ( _422_ A ) ; +- _166_ + ( _420_ ZN ) ( _422_ B1 ) ; +- _167_ + ( _421_ ZN ) ( _422_ B2 ) ; +- _168_ + ( _423_ ZN ) ( _425_ A1 ) ; +- _169_ + ( _424_ ZN ) ( _425_ A2 ) ; +- _170_ + ( _425_ ZN ) ( _427_ A ) ; +- _171_ + ( _426_ ZN ) ( _427_ B ) ; +- _172_ + ( _428_ ZN ) ( _431_ A ) ; +- _173_ + ( _429_ ZN ) ( _431_ B1 ) ; +- _174_ + ( _430_ ZN ) ( _431_ B2 ) ; +- _175_ + ( _432_ ZN ) ( _433_ B ) ; +- _176_ + ( _434_ ZN ) ( _436_ A1 ) ; +- _177_ + ( _435_ ZN ) ( _436_ A2 ) ; +- _178_ + ( _437_ ZN ) ( _438_ A ) ( _446_ A2 ) ; +- _179_ + ( _438_ ZN ) ( _439_ A1 ) ( _529_ A1 ) ; +- _180_ + ( _439_ ZN ) ( _441_ A ) ; +- _181_ + ( _440_ Z ) ( _441_ B ) ; +- _182_ + ( _442_ ZN ) ( _444_ A1 ) ; +- _183_ + ( _443_ ZN ) ( _444_ A2 ) ; +- _184_ + ( _445_ ZN ) ( _446_ A1 ) ; +- _185_ + ( _446_ ZN ) ( _448_ A ) ; +- _186_ + ( _447_ ZN ) ( _448_ B ) ; +- _187_ + ( _449_ ZN ) ( _452_ A ) ; +- _188_ + ( _450_ ZN ) ( _452_ B1 ) ; +- _189_ + ( _451_ ZN ) ( _452_ B2 ) ; +- _190_ + ( _453_ ZN ) ( _454_ B ) ; +- _191_ + ( _455_ ZN ) ( _457_ A1 ) ; +- _192_ + ( _456_ ZN ) ( _457_ A2 ) ; +- _193_ + ( _458_ ZN ) ( _459_ A1 ) ; +- _194_ + ( _459_ ZN ) ( _461_ A ) ; +- _195_ + ( _460_ Z ) ( _461_ B ) ; +- _196_ + ( _462_ ZN ) ( _465_ A ) ; +- _197_ + ( _463_ ZN ) ( _465_ B1 ) ; +- _198_ + ( _464_ ZN ) ( _465_ B2 ) ; +- _199_ + ( _466_ ZN ) ( _467_ B ) ; +- _200_ + ( _468_ ZN ) ( _470_ A1 ) ; +- _201_ + ( _469_ ZN ) ( _470_ A2 ) ; +- _202_ + ( _471_ ZN ) ( _474_ A ) ; +- _203_ + ( _472_ ZN ) ( _473_ A1 ) ( _484_ A3 ) ; +- _204_ + ( _473_ ZN ) ( _474_ B ) ; +- _205_ + ( _475_ ZN ) ( _477_ A1 ) ; +- _206_ + ( _476_ ZN ) ( _477_ A2 ) ; +- _207_ + ( _479_ ZN ) ( _481_ A1 ) ; +- _208_ + ( _480_ ZN ) ( _481_ A2 ) ; +- _209_ + ( _483_ ZN ) ( _484_ A1 ) ; +- _210_ + ( _484_ ZN ) ( _485_ A1 ) ; +- _211_ + ( _485_ ZN ) ( _488_ A1 ) ; +- _212_ + ( _486_ ZN ) ( _487_ A1 ) ; +- _213_ + ( _487_ ZN ) ( _488_ A4 ) ; +- _214_ + ( _488_ ZN ) ( _489_ A1 ) ; +- _215_ + ( _489_ ZN ) ( _490_ A1 ) ; +- _216_ + ( _490_ ZN ) ( _491_ A3 ) ( _494_ C2 ) ; +- _217_ + ( _491_ ZN ) ( _492_ C1 ) ; +- _218_ + ( _493_ ZN ) ( _494_ B2 ) ; +- _219_ + ( _495_ Z ) ( _498_ A ) ; +- _220_ + ( _496_ ZN ) ( _497_ A ) ( _518_ S ) ( _520_ S ) + ( _522_ S ) ( _524_ S ) ( _526_ S ) ( _528_ S ) ; +- _221_ + ( _497_ Z ) ( _498_ S ) ( _500_ S ) ( _502_ S ) + ( _504_ S ) ( _506_ S ) ( _508_ S ) ( _510_ S ) + ( _512_ S ) ( _514_ S ) ( _516_ S ) ; +- _222_ + ( _499_ Z ) ( _500_ A ) ; +- _223_ + ( _501_ Z ) ( _502_ A ) ; +- _224_ + ( _503_ Z ) ( _504_ A ) ; +- _225_ + ( _505_ Z ) ( _506_ A ) ; +- _226_ + ( _507_ Z ) ( _508_ A ) ; +- _227_ + ( _509_ Z ) ( _510_ A ) ; +- _228_ + ( _511_ Z ) ( _512_ A ) ; +- _229_ + ( _513_ Z ) ( _514_ A ) ; +- _230_ + ( _515_ Z ) ( _516_ A ) ; +- _231_ + ( _517_ Z ) ( _518_ A ) ; +- _232_ + ( _519_ Z ) ( _520_ A ) ; +- _233_ + ( _521_ Z ) ( _522_ A ) ; +- _234_ + ( _523_ Z ) ( _524_ A ) ; +- _235_ + ( _525_ Z ) ( _526_ A ) ; +- _236_ + ( _527_ Z ) ( _528_ A ) ; +- _237_ + ( _529_ ZN ) ( _530_ A1 ) ; +- _238_ + ( _530_ ZN ) ( _532_ A ) ; +- _239_ + ( _531_ ZN ) ( _532_ B ) ; +- _240_ + ( _533_ ZN ) ( _535_ A1 ) ; +- _241_ + ( _534_ ZN ) ( _535_ A2 ) ; +- _242_ + ( _536_ QN ) ; +- _243_ + ( _537_ QN ) ; +- _244_ + ( _538_ QN ) ; +- _245_ + ( _539_ QN ) ; +- _246_ + ( _540_ QN ) ; +- _247_ + ( _541_ QN ) ; +- _248_ + ( _542_ QN ) ; +- _249_ + ( _543_ QN ) ; +- _250_ + ( _544_ QN ) ; +- _251_ + ( _545_ QN ) ; +- _252_ + ( _546_ QN ) ; +- _253_ + ( _547_ QN ) ; +- _254_ + ( _548_ QN ) ; +- _255_ + ( _549_ QN ) ; +- _256_ + ( _550_ QN ) ; +- _257_ + ( _551_ QN ) ; +- _258_ + ( _552_ QN ) ; +- _259_ + ( _553_ QN ) ; +- _260_ + ( _554_ QN ) ; +- _261_ + ( _555_ QN ) ; +- _262_ + ( _556_ QN ) ; +- _263_ + ( _557_ QN ) ; +- _264_ + ( _558_ QN ) ; +- _265_ + ( _559_ QN ) ; +- _266_ + ( _560_ QN ) ; +- _267_ + ( _561_ QN ) ; +- _268_ + ( _562_ QN ) ; +- _269_ + ( _563_ QN ) ; +- _270_ + ( _564_ QN ) ; +- _271_ + ( _565_ QN ) ; +- _272_ + ( _566_ QN ) ; +- _273_ + ( _567_ QN ) ; +- _274_ + ( _568_ QN ) ; +- _275_ + ( _569_ QN ) ; +- clk + ( PIN clk ) ( _536_ CK ) ( _537_ CK ) ( _538_ CK ) + ( _539_ CK ) ( _540_ CK ) ( _541_ CK ) ( _542_ CK ) + ( _543_ CK ) ( _544_ CK ) ( _545_ CK ) ( _546_ CK ) + ( _547_ CK ) ( _548_ CK ) ( _549_ CK ) ( _550_ CK ) + ( _551_ CK ) ( _552_ CK ) ( _553_ CK ) ( _554_ CK ) + ( _555_ CK ) ( _556_ CK ) ( _557_ CK ) ( _558_ CK ) + ( _559_ CK ) ( _560_ CK ) ( _561_ CK ) ( _562_ CK ) + ( _563_ CK ) ( _564_ CK ) ( _565_ CK ) ( _566_ CK ) + ( _567_ CK ) ( _568_ CK ) ( _569_ CK ) ; +- ctrl.state.out_reg\[0\].qi + ( _276_ A2 ) ( _355_ A ) ( _482_ A2 ) ( _552_ Q ) ; +- ctrl.state.out_reg\[1\].qi + ( _276_ A1 ) ( _354_ A ) ( _362_ A2 ) ( _369_ A ) + ( _378_ A ) ( _382_ A ) ( _393_ A ) ( _479_ A ) + ( _533_ A ) ( _551_ Q ) ; +- dpath.a_reg.out_reg\[0\].qi + ( _309_ A ) ( _473_ A2 ) ( _478_ B ) ( _527_ A ) + ( _550_ Q ) ; +- dpath.a_reg.out_reg\[10\].qi + ( _297_ A2 ) ( _347_ A2 ) ( _406_ B1 ) ( _419_ A2 ) + ( _507_ A ) ( _541_ Q ) ; +- dpath.a_reg.out_reg\[11\].qi + ( _295_ A2 ) ( _346_ A2 ) ( _408_ B ) ( _410_ A2 ) + ( _505_ A ) ( _540_ Q ) ; +- dpath.a_reg.out_reg\[12\].qi + ( _284_ A2 ) ( _336_ A2 ) ( _396_ B ) ( _398_ A2 ) + ( _503_ A ) ( _539_ Q ) ; +- dpath.a_reg.out_reg\[13\].qi + ( _282_ A2 ) ( _335_ A2 ) ( _391_ A2 ) ( _495_ A ) + ( _538_ Q ) ; +- dpath.a_reg.out_reg\[14\].qi + ( _287_ A2 ) ( _340_ A2 ) ( _376_ B ) ( _380_ A2 ) + ( _501_ A ) ( _537_ Q ) ; +- dpath.a_reg.out_reg\[15\].qi + ( _278_ A ) ( _499_ A ) ( _536_ Q ) ; +- dpath.a_reg.out_reg\[1\].qi + ( _306_ A ) ( _471_ B ) ( _525_ A ) ( _549_ Q ) ; +- dpath.a_reg.out_reg\[2\].qi + ( _302_ A ) ( _313_ A2 ) ( _458_ B2 ) ( _466_ B ) + ( _523_ A ) ( _548_ Q ) ; +- dpath.a_reg.out_reg\[3\].qi + ( _301_ A2 ) ( _304_ B2 ) ( _460_ B ) ( _462_ A2 ) + ( _521_ A ) ( _547_ Q ) ; +- dpath.a_reg.out_reg\[4\].qi + ( _317_ A2 ) ( _328_ A ) ( _453_ B ) ( _519_ A ) + ( _546_ Q ) ; +- dpath.a_reg.out_reg\[5\].qi + ( _319_ A2 ) ( _330_ B2 ) ( _438_ B2 ) ( _447_ B ) + ( _449_ A2 ) ( _517_ A ) ( _545_ Q ) ; +- dpath.a_reg.out_reg\[6\].qi + ( _320_ A ) ( _440_ A ) ( _515_ A ) ( _544_ Q ) ; +- dpath.a_reg.out_reg\[7\].qi + ( _323_ B2 ) ( _326_ B2 ) ( _327_ A ) ( _513_ A ) + ( _531_ B ) ( _569_ Q ) ; +- dpath.a_reg.out_reg\[8\].qi + ( _292_ A ) ( _343_ B ) ( _432_ B ) ( _511_ A ) + ( _543_ Q ) ; +- dpath.a_reg.out_reg\[9\].qi + ( _291_ A2 ) ( _343_ C2 ) ( _344_ A2 ) ( _426_ B ) + ( _428_ A2 ) ( _509_ A ) ( _542_ Q ) ; +- dpath.b_reg.out_reg\[0\].qi + ( _310_ A ) ( _472_ A ) ( _478_ A ) ( _479_ C2 ) + ( _528_ B ) ( _568_ Q ) ; +- dpath.b_reg.out_reg\[10\].qi + ( _296_ A ) ( _420_ C2 ) ( _486_ A2 ) ( _508_ B ) + ( _558_ Q ) ; +- dpath.b_reg.out_reg\[11\].qi + ( _294_ A ) ( _408_ A ) ( _486_ A3 ) ( _506_ B ) + ( _557_ Q ) ; +- dpath.b_reg.out_reg\[12\].qi + ( _283_ A ) ( _396_ A ) ( _488_ A2 ) ( _504_ B ) + ( _556_ Q ) ; +- dpath.b_reg.out_reg\[13\].qi + ( _281_ A ) ( _393_ C2 ) ( _498_ B ) ( _553_ Q ) ; +- dpath.b_reg.out_reg\[14\].qi + ( _286_ A ) ( _376_ A ) ( _382_ C2 ) ( _502_ B ) + ( _555_ Q ) ; +- dpath.b_reg.out_reg\[15\].qi + ( _279_ A2 ) ( _333_ A2 ) ( _365_ C2 ) ( _488_ A3 ) + ( _500_ B ) ( _554_ Q ) ; +- dpath.b_reg.out_reg\[1\].qi + ( _307_ A2 ) ( _310_ C2 ) ( _471_ A ) ( _475_ C2 ) + ( _483_ A2 ) ( _526_ B ) ( _567_ Q ) ; +- dpath.b_reg.out_reg\[2\].qi + ( _303_ A2 ) ( _312_ A ) ( _466_ A ) ( _524_ B ) + ( _566_ Q ) ; +- dpath.b_reg.out_reg\[3\].qi + ( _300_ A ) ( _460_ A ) ( _483_ A1 ) ( _522_ B ) + ( _565_ Q ) ; +- dpath.b_reg.out_reg\[4\].qi + ( _316_ A ) ( _329_ A2 ) ( _437_ A2 ) ( _445_ B1 ) + ( _453_ A ) ( _520_ B ) ( _564_ Q ) ; +- dpath.b_reg.out_reg\[5\].qi + ( _318_ A ) ( _447_ A ) ( _490_ A2 ) ( _518_ B ) + ( _563_ Q ) ; +- dpath.b_reg.out_reg\[6\].qi + ( _321_ A2 ) ( _325_ A2 ) ( _440_ B ) ( _443_ A2 ) + ( _490_ A3 ) ( _516_ B ) ( _529_ B2 ) ( _562_ Q ) ; +- dpath.b_reg.out_reg\[7\].qi + ( _322_ A ) ( _331_ B1 ) ( _514_ B ) ( _531_ A ) + ( _561_ Q ) ; +- dpath.b_reg.out_reg\[8\].qi + ( _293_ B1 ) ( _342_ A ) ( _423_ B1 ) ( _424_ A2 ) + ( _432_ A ) ( _512_ B ) ( _560_ Q ) ; +- dpath.b_reg.out_reg\[9\].qi + ( _290_ A ) ( _426_ A ) ( _486_ A1 ) ( _510_ B ) + ( _559_ Q ) ; +- req_msg\[0\] + ( PIN req_msg\[0\] ) ( _527_ B ) ; +- req_msg\[10\] + ( PIN req_msg\[10\] ) ( _507_ B ) ; +- req_msg\[11\] + ( PIN req_msg\[11\] ) ( _505_ B ) ; +- req_msg\[12\] + ( PIN req_msg\[12\] ) ( _503_ B ) ; +- req_msg\[13\] + ( PIN req_msg\[13\] ) ( _495_ B ) ; +- req_msg\[14\] + ( PIN req_msg\[14\] ) ( _501_ B ) ; +- req_msg\[15\] + ( PIN req_msg\[15\] ) ( _499_ B ) ; +- req_msg\[16\] + ( PIN req_msg\[16\] ) ( _479_ B2 ) ; +- req_msg\[17\] + ( PIN req_msg\[17\] ) ( _475_ B2 ) ; +- req_msg\[18\] + ( PIN req_msg\[18\] ) ( _468_ B2 ) ; +- req_msg\[19\] + ( PIN req_msg\[19\] ) ( _463_ B2 ) ; +- req_msg\[1\] + ( PIN req_msg\[1\] ) ( _525_ B ) ; +- req_msg\[20\] + ( PIN req_msg\[20\] ) ( _455_ B2 ) ; +- req_msg\[21\] + ( PIN req_msg\[21\] ) ( _450_ B2 ) ; +- req_msg\[22\] + ( PIN req_msg\[22\] ) ( _442_ B2 ) ; +- req_msg\[23\] + ( PIN req_msg\[23\] ) ( _533_ B2 ) ; +- req_msg\[24\] + ( PIN req_msg\[24\] ) ( _434_ B2 ) ; +- req_msg\[25\] + ( PIN req_msg\[25\] ) ( _429_ B2 ) ; +- req_msg\[26\] + ( PIN req_msg\[26\] ) ( _420_ B2 ) ; +- req_msg\[27\] + ( PIN req_msg\[27\] ) ( _411_ B2 ) ; +- req_msg\[28\] + ( PIN req_msg\[28\] ) ( _399_ B2 ) ; +- req_msg\[29\] + ( PIN req_msg\[29\] ) ( _393_ B2 ) ; +- req_msg\[2\] + ( PIN req_msg\[2\] ) ( _523_ B ) ; +- req_msg\[30\] + ( PIN req_msg\[30\] ) ( _382_ B2 ) ; +- req_msg\[31\] + ( PIN req_msg\[31\] ) ( _365_ B2 ) ; +- req_msg\[3\] + ( PIN req_msg\[3\] ) ( _521_ B ) ; +- req_msg\[4\] + ( PIN req_msg\[4\] ) ( _519_ B ) ; +- req_msg\[5\] + ( PIN req_msg\[5\] ) ( _517_ B ) ; +- req_msg\[6\] + ( PIN req_msg\[6\] ) ( _515_ B ) ; +- req_msg\[7\] + ( PIN req_msg\[7\] ) ( _513_ B ) ; +- req_msg\[8\] + ( PIN req_msg\[8\] ) ( _511_ B ) ; +- req_msg\[9\] + ( PIN req_msg\[9\] ) ( _509_ B ) ; +- req_rdy + ( PIN req_rdy ) ( _277_ Z ) ( _495_ S ) ( _499_ S ) + ( _501_ S ) ( _503_ S ) ( _505_ S ) ( _507_ S ) + ( _509_ S ) ( _511_ S ) ( _513_ S ) ; +- req_val + ( PIN req_val ) ( _493_ A3 ) ; +- reset + ( PIN reset ) ( _492_ A ) ( _494_ A ) ; +- resp_msg\[0\] + ( PIN resp_msg\[0\] ) ( _478_ Z ) ( _480_ A3 ) ; +- resp_msg\[10\] + ( PIN resp_msg\[10\] ) ( _418_ ZN ) ; +- resp_msg\[11\] + ( PIN resp_msg\[11\] ) ( _409_ ZN ) ( _411_ C1 ) ; +- resp_msg\[12\] + ( PIN resp_msg\[12\] ) ( _397_ ZN ) ( _399_ C1 ) ; +- resp_msg\[13\] + ( PIN resp_msg\[13\] ) ( _390_ ZN ) ( _392_ A1 ) ; +- resp_msg\[14\] + ( PIN resp_msg\[14\] ) ( _377_ ZN ) ( _381_ A1 ) ; +- resp_msg\[15\] + ( PIN resp_msg\[15\] ) ( _353_ ZN ) ; +- resp_msg\[1\] + ( PIN resp_msg\[1\] ) ( _474_ ZN ) ( _476_ A3 ) ; +- resp_msg\[2\] + ( PIN resp_msg\[2\] ) ( _467_ ZN ) ( _468_ C2 ) ; +- resp_msg\[3\] + ( PIN resp_msg\[3\] ) ( _461_ ZN ) ( _463_ C2 ) ; +- resp_msg\[4\] + ( PIN resp_msg\[4\] ) ( _454_ ZN ) ( _455_ C2 ) ; +- resp_msg\[5\] + ( PIN resp_msg\[5\] ) ( _448_ ZN ) ( _450_ C2 ) ; +- resp_msg\[6\] + ( PIN resp_msg\[6\] ) ( _441_ ZN ) ( _442_ C2 ) ; +- resp_msg\[7\] + ( PIN resp_msg\[7\] ) ( _532_ ZN ) ( _533_ C1 ) ; +- resp_msg\[8\] + ( PIN resp_msg\[8\] ) ( _433_ ZN ) ( _434_ C2 ) ; +- resp_msg\[9\] + ( PIN resp_msg\[9\] ) ( _427_ ZN ) ( _429_ C1 ) ; +- resp_rdy + ( PIN resp_rdy ) ( _492_ B1 ) ; +- resp_val + ( PIN resp_val ) ( _482_ ZN ) ( _492_ B2 ) ; +END NETS + +END DESIGN diff --git a/src/ppl/test/obstruction_boundary.ok b/src/ppl/test/obstruction_boundary.ok new file mode 100644 index 00000000000..59453d7532c --- /dev/null +++ b/src/ppl/test/obstruction_boundary.ok @@ -0,0 +1,13 @@ +[INFO ODB-0227] LEF file: Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells +[INFO ODB-0128] Design: gcd +[INFO ODB-0130] Created 54 pins. +[INFO ODB-0131] Created 549 components and 2166 component-terminals. +[INFO ODB-0133] Created 364 nets and 1068 connections. +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-0005] Slots per section 200 +[INFO PPL-0008] Successfully assigned pins to sections. +pin to obstruction violations: 0 +pin to min spacing obstruction violations: 0 diff --git a/src/ppl/test/obstruction_boundary.tcl b/src/ppl/test/obstruction_boundary.tcl new file mode 100644 index 00000000000..f0ee1b0d4c7 --- /dev/null +++ b/src/ppl/test/obstruction_boundary.tcl @@ -0,0 +1,29 @@ +# place_pins must keep min spacing from routing obstructions at the die edges +source "helpers.tcl" +source "pdn_helpers.tcl" + +# slot count and HPWL change once boundary shapes block slots +suppress_message PPL 1 +suppress_message PPL 12 + +read_lef Nangate45/Nangate45.lef +read_def gcd_placed.def + +set block [ord::get_db_block] +set metal2 [[ord::get_db_tech] findLayer metal2] + +# routing obstruction touching the top edge +odb::dbObstruction_create $block $metal2 100000 292000 104000 296000 + +# obstruction with a min spacing rule larger than the layer spacing +set obs [odb::dbObstruction_create $block $metal2 60000 292000 64000 296000] +$obs setMinSpacing 5000 + +place_pins -hor_layers metal3 -ver_layers metal2 -corner_avoidance 0 \ + -min_distance 0.12 + +set obstruction_rect [list [list 100000 292000 104000 296000]] +puts "pin to obstruction violations: [count_rect_violations metal2 $obstruction_rect spacing]" +set min_spacing_rect [list [list 60000 292000 64000 296000]] +puts "pin to min spacing obstruction violations:\ + [count_rect_violations metal2 $min_spacing_rect 5000]" diff --git a/src/ppl/test/pdn_boundary_mirrored_pins.ok b/src/ppl/test/pdn_boundary_mirrored_pins.ok new file mode 100644 index 00000000000..963f0f34bb3 --- /dev/null +++ b/src/ppl/test/pdn_boundary_mirrored_pins.ok @@ -0,0 +1,22 @@ +[INFO ODB-0227] LEF file: Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells +[INFO ODB-0128] Design: gcd +[INFO ODB-0130] Created 54 pins. +[INFO ODB-0131] Created 549 components and 2166 component-terminals. +[INFO ODB-0133] Created 364 nets and 1068 connections. +Found 0 macro blocks. +[INFO PPL-0067] Restrict pins [ req_msg\[0\] ] to region 40.00u-60.00u at the BOTTOM edge. +[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-0008] Successfully assigned pins to sections. +mirrored pin overlaps with strap: 0 +Found 0 macro blocks. +[INFO PPL-0067] Restrict pins [ req_msg\[2\] ] to region 50.20u-51.80u at the BOTTOM edge. +[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 +[WARNING PPL-0033] I/O pin req_msg\[2\] cannot be placed in the specified region. Not enough space. +[ERROR PPL-0082] Mirrored position (50.38um, 148.00um) at layer metal2 is not a valid position for pin req_msg\[3\] placement. +PPL-0082 diff --git a/src/ppl/test/pdn_boundary_mirrored_pins.tcl b/src/ppl/test/pdn_boundary_mirrored_pins.tcl new file mode 100644 index 00000000000..41cd8a5cbd9 --- /dev/null +++ b/src/ppl/test/pdn_boundary_mirrored_pins.tcl @@ -0,0 +1,40 @@ +# mirrored pins must not land on slots blocked by boundary PDN shapes: +# the matcher avoids them when possible and errors out when not +source "helpers.tcl" +source "pdn_helpers.tcl" + +# slot count and HPWL change once boundary PDN shapes block slots +suppress_message PPL 1 +suppress_message PPL 12 + +read_lef Nangate45/Nangate45.lef +read_def gcd_placed.def + +set block [ord::get_db_block] +set metal2 [[ord::get_db_tech] findLayer metal2] + +# strap on the top edge only, so mirrored slots at the bottom edge stay free +set net [odb::dbNet_create $block "VDD"] +$net setSpecial +$net setSigType POWER +set swire [odb::dbSWire_create $net "ROUTED"] +odb::dbSBox_create $swire $metal2 100000 292000 104000 296000 "STRIPE" + +set_io_pin_constraint -mirrored_pins {req_msg\[0\] req_msg\[1\]} +set_io_pin_constraint -region bottom:40-60 -pin_names {req_msg\[0\]} + +place_pins -hor_layers metal3 -ver_layers metal2 -corner_avoidance 0 \ + -min_distance 0.12 + +puts "mirrored pin overlaps with strap: [count_pdn_shape_violations overlap]" + +# a region whose mirrored slots are all blocked must error, not overlap +clear_io_pin_constraints +set_io_pin_constraint -mirrored_pins {req_msg\[2\] req_msg\[3\]} +set_io_pin_constraint -region bottom:50.2-51.8 -pin_names {req_msg\[2\]} + +catch { + place_pins -hor_layers metal3 -ver_layers metal2 -corner_avoidance 0 \ + -min_distance 0.12 +} error +puts $error diff --git a/src/ppl/test/pdn_boundary_pg_pins.ok b/src/ppl/test/pdn_boundary_pg_pins.ok new file mode 100644 index 00000000000..5da024fe6f7 --- /dev/null +++ b/src/ppl/test/pdn_boundary_pg_pins.ok @@ -0,0 +1,13 @@ +[INFO ODB-0227] LEF file: Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells +[INFO ODB-0128] Design: gcd +[INFO ODB-0130] Created 54 pins. +[INFO ODB-0131] Created 549 components and 2166 component-terminals. +[INFO ODB-0133] Created 364 nets and 1068 connections. +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-0005] Slots per section 200 +[INFO PPL-0008] Successfully assigned pins to sections. +pin violations against PG pins: 0 +pin violations against min spacing PG pin: 0 diff --git a/src/ppl/test/pdn_boundary_pg_pins.tcl b/src/ppl/test/pdn_boundary_pg_pins.tcl new file mode 100644 index 00000000000..9284b1c412e --- /dev/null +++ b/src/ppl/test/pdn_boundary_pg_pins.tcl @@ -0,0 +1,42 @@ +# place_pins must keep min spacing from fixed power/ground pins on the die edge +source "helpers.tcl" +source "pdn_helpers.tcl" + +# slot count and HPWL change once boundary PDN shapes block slots +suppress_message PPL 1 +suppress_message PPL 12 + +read_lef Nangate45/Nangate45.lef +read_def gcd_placed.def + +set block [ord::get_db_block] +set metal2 [[ord::get_db_tech] findLayer metal2] + +# fixed power pin on the top edge, like the ones created by pdngen; its ends +# sit between routing tracks so the adjacent slot centers fall outside the box +set net [odb::dbNet_create $block "VDD"] +$net setSpecial +$net setSigType POWER +set term [odb::dbBTerm_create $net "VDD"] +$term setSigType POWER +set pin [odb::dbBPin_create $term] +odb::dbBox_create $pin $metal2 22140 295440 273640 296000 +$pin setPlacementStatus FIRM + +# power pin on the bottom edge requiring more than the layer min spacing +set bottom_net [odb::dbNet_create $block "VDDB"] +set bottom_term [odb::dbBTerm_create $bottom_net "VDDB"] +$bottom_term setSigType POWER +set bottom_pin [odb::dbBPin_create $bottom_term] +odb::dbBox_create $bottom_pin $metal2 22140 0 273640 560 +$bottom_pin setMinSpacing 5000 +$bottom_pin setPlacementStatus FIRM + +place_pins -hor_layers metal3 -ver_layers metal2 -corner_avoidance 0 \ + -min_distance 0.12 -exclude left:* -exclude right:* + +set pg_rect [list [list 22140 295440 273640 296000]] +puts "pin violations against PG pins: [count_rect_violations metal2 $pg_rect spacing]" +set min_spacing_rect [list [list 22140 0 273640 560]] +puts "pin violations against min spacing PG pin:\ + [count_rect_violations metal2 $min_spacing_rect 5000]" diff --git a/src/ppl/test/pdn_boundary_place_pin.ok b/src/ppl/test/pdn_boundary_place_pin.ok new file mode 100644 index 00000000000..a6c72b6db53 --- /dev/null +++ b/src/ppl/test/pdn_boundary_place_pin.ok @@ -0,0 +1,9 @@ +[INFO ODB-0227] LEF file: Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells +[INFO ODB-0128] Design: gcd +[INFO ODB-0130] Created 54 pins. +[INFO ODB-0131] Created 549 components and 2166 component-terminals. +[INFO ODB-0133] Created 364 nets and 1068 connections. +[INFO PPL-0070] Pin req_msg\[0\] placed at (49.81um, 147.97um) instead of (51.00um, 148.00um). Pin was snapped to a routing track, to the manufacturing grid or moved away from blocked region. +[INFO PPL-0070] Pin req_msg\[1\] placed at (49.62um, 147.97um) instead of (50.50um, 148.00um). Pin was snapped to a routing track, to the manufacturing grid or moved away from blocked region. +[INFO PPL-0070] Pin req_msg\[2\] placed at (62.55um, 147.00um) instead of (51.00um, 148.00um). Pin was snapped to a routing track, to the manufacturing grid or moved away from blocked region. +pin to stripe violations: 0 diff --git a/src/ppl/test/pdn_boundary_place_pin.tcl b/src/ppl/test/pdn_boundary_place_pin.tcl new file mode 100644 index 00000000000..ea28d287b55 --- /dev/null +++ b/src/ppl/test/pdn_boundary_place_pin.tcl @@ -0,0 +1,27 @@ +# place_pin -force_to_die_boundary must move pins away from boundary PDN +# stripes instead of placing them on top +source "helpers.tcl" +source "pdn_helpers.tcl" + +read_lef Nangate45/Nangate45.lef +read_def gcd_placed.def + +set block [ord::get_db_block] +set metal2 [[ord::get_db_tech] findLayer metal2] + +# stripe without pins on the top edge +set net [odb::dbNet_create $block "VDD"] +$net setSpecial +$net setSigType POWER +set swire [odb::dbSWire_create $net "ROUTED"] +odb::dbSBox_create $swire $metal2 100000 292000 104000 296000 "STRIPE" + +place_pin -pin_name req_msg\[0\] -layer metal2 -location {51 148} \ + -force_to_die_boundary +place_pin -pin_name req_msg\[1\] -layer metal2 -location {50.5 148} \ + -force_to_die_boundary +# wide pins must be kept away using their own size, not the default one +place_pin -pin_name req_msg\[2\] -layer metal2 -location {51 148} \ + -pin_size {10 2} -force_to_die_boundary + +puts "pin to stripe violations: [count_pdn_shape_violations spacing]" diff --git a/src/ppl/test/pdn_boundary_stripes.ok b/src/ppl/test/pdn_boundary_stripes.ok new file mode 100644 index 00000000000..99e1d4962c5 --- /dev/null +++ b/src/ppl/test/pdn_boundary_stripes.ok @@ -0,0 +1,13 @@ +[INFO ODB-0227] LEF file: Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells +[INFO ODB-0128] Design: gcd +[INFO ODB-0130] Created 54 pins. +[INFO ODB-0131] Created 549 components and 2166 component-terminals. +[INFO ODB-0133] Created 364 nets and 1068 connections. +[INFO PDN-0001] Inserting grid: Core +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-0005] Slots per section 200 +[INFO PPL-0008] Successfully assigned pins to sections. +pin to boundary stripe violations: 0 diff --git a/src/ppl/test/pdn_boundary_stripes.tcl b/src/ppl/test/pdn_boundary_stripes.tcl new file mode 100644 index 00000000000..70352b7eed5 --- /dev/null +++ b/src/ppl/test/pdn_boundary_stripes.tcl @@ -0,0 +1,31 @@ +# place_pins must not place pins over PDN stripes extended to the die boundary +source "helpers.tcl" +source "pdn_helpers.tcl" + +# slot count and HPWL change once boundary PDN shapes block slots +suppress_message PPL 1 +suppress_message PPL 12 + +read_lef Nangate45/Nangate45.lef +read_def gcd_placed.def + +add_global_connection -net VDD -pin_pattern VDD -power +add_global_connection -net VSS -pin_pattern VSS -ground + +set_voltage_domain -power VDD -ground VSS + +define_pdn_grid -name "Core" +add_pdn_stripe -followpins -layer metal1 +add_pdn_stripe -layer metal2 -width 2.0 -pitch 20.0 -offset 5.0 \ + -extend_to_boundary +add_pdn_stripe -layer metal3 -width 2.0 -pitch 20.0 -offset 5.0 \ + -extend_to_boundary +add_pdn_connect -layers {metal1 metal2} +add_pdn_connect -layers {metal2 metal3} + +pdngen + +place_pins -hor_layers metal3 -ver_layers metal2 -corner_avoidance 0 \ + -min_distance 0.12 + +puts "pin to boundary stripe violations: [count_pdn_shape_violations overlap]" diff --git a/src/ppl/test/pdn_boundary_stripes_length.ok b/src/ppl/test/pdn_boundary_stripes_length.ok new file mode 100644 index 00000000000..e833fb0df07 --- /dev/null +++ b/src/ppl/test/pdn_boundary_stripes_length.ok @@ -0,0 +1,13 @@ +[INFO ODB-0227] LEF file: Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells +[INFO ODB-0128] Design: gcd +[INFO ODB-0130] Created 54 pins. +[INFO ODB-0131] Created 549 components and 2166 component-terminals. +[INFO ODB-0133] Created 364 nets and 1068 connections. +[INFO PDN-0001] Inserting grid: Core +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-0005] Slots per section 200 +[INFO PPL-0008] Successfully assigned pins to sections. +pin to wide stripe spacing violations: 0 diff --git a/src/ppl/test/pdn_boundary_stripes_length.tcl b/src/ppl/test/pdn_boundary_stripes_length.tcl new file mode 100644 index 00000000000..408a1462db6 --- /dev/null +++ b/src/ppl/test/pdn_boundary_stripes_length.tcl @@ -0,0 +1,34 @@ +# place_pins must honor the width-dependent spacing rules to wide boundary +# PDN stripes when long pins have enough parallel run length to trigger them +source "helpers.tcl" +source "pdn_helpers.tcl" + +# slot count and HPWL change once boundary PDN shapes block slots +suppress_message PPL 1 +suppress_message PPL 12 + +read_lef Nangate45/Nangate45.lef +read_def gcd_placed.def + +add_global_connection -net VDD -pin_pattern VDD -power +add_global_connection -net VSS -pin_pattern VSS -ground + +set_voltage_domain -power VDD -ground VSS + +define_pdn_grid -name "Core" +add_pdn_stripe -followpins -layer metal1 +add_pdn_stripe -layer metal2 -width 2.0 -pitch 20.0 -offset 5.0 \ + -extend_to_boundary +add_pdn_stripe -layer metal3 -width 2.0 -pitch 20.0 -offset 5.0 \ + -extend_to_boundary +add_pdn_connect -layers {metal1 metal2} +add_pdn_connect -layers {metal2 metal3} + +pdngen -dont_add_pins + +set_pin_length -ver_length 1.0 -hor_length 1.0 + +place_pins -hor_layers metal3 -ver_layers metal2 -corner_avoidance 0 \ + -min_distance 0.12 + +puts "pin to wide stripe spacing violations: [count_pdn_shape_violations table]" diff --git a/src/ppl/test/pdn_boundary_stripes_no_pins.ok b/src/ppl/test/pdn_boundary_stripes_no_pins.ok new file mode 100644 index 00000000000..99e1d4962c5 --- /dev/null +++ b/src/ppl/test/pdn_boundary_stripes_no_pins.ok @@ -0,0 +1,13 @@ +[INFO ODB-0227] LEF file: Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells +[INFO ODB-0128] Design: gcd +[INFO ODB-0130] Created 54 pins. +[INFO ODB-0131] Created 549 components and 2166 component-terminals. +[INFO ODB-0133] Created 364 nets and 1068 connections. +[INFO PDN-0001] Inserting grid: Core +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-0005] Slots per section 200 +[INFO PPL-0008] Successfully assigned pins to sections. +pin to boundary stripe violations: 0 diff --git a/src/ppl/test/pdn_boundary_stripes_no_pins.tcl b/src/ppl/test/pdn_boundary_stripes_no_pins.tcl new file mode 100644 index 00000000000..5a54139fcdd --- /dev/null +++ b/src/ppl/test/pdn_boundary_stripes_no_pins.tcl @@ -0,0 +1,33 @@ +# place_pins must not place pins over PDN stripes extended to the die boundary; +# -dont_add_pins leaves the straps without BPins, so avoiding them depends +# entirely on place_pins checking the special net wires (dbSBox) +source "helpers.tcl" +source "pdn_helpers.tcl" + +# slot count and HPWL change once boundary PDN shapes block slots +suppress_message PPL 1 +suppress_message PPL 12 + +read_lef Nangate45/Nangate45.lef +read_def gcd_placed.def + +add_global_connection -net VDD -pin_pattern VDD -power +add_global_connection -net VSS -pin_pattern VSS -ground + +set_voltage_domain -power VDD -ground VSS + +define_pdn_grid -name "Core" +add_pdn_stripe -followpins -layer metal1 +add_pdn_stripe -layer metal2 -width 2.0 -pitch 20.0 -offset 5.0 \ + -extend_to_boundary +add_pdn_stripe -layer metal3 -width 2.0 -pitch 20.0 -offset 5.0 \ + -extend_to_boundary +add_pdn_connect -layers {metal1 metal2} +add_pdn_connect -layers {metal2 metal3} + +pdngen -dont_add_pins + +place_pins -hor_layers metal3 -ver_layers metal2 -corner_avoidance 0 \ + -min_distance 0.12 + +puts "pin to boundary stripe violations: [count_pdn_shape_violations overlap]" diff --git a/src/ppl/test/pdn_boundary_stripes_polygon.ok b/src/ppl/test/pdn_boundary_stripes_polygon.ok new file mode 100644 index 00000000000..950437d418e --- /dev/null +++ b/src/ppl/test/pdn_boundary_stripes_polygon.ok @@ -0,0 +1,13 @@ +[INFO ODB-0227] LEF file: Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells +[INFO ODB-0128] Design: gcd +[INFO ODB-0130] Created 54 pins. +[INFO ODB-0131] Created 421 components and 1975 component-terminals. +[INFO ODB-0132] Created 2 special nets and 842 connections. +[INFO ODB-0133] Created 418 nets and 1133 connections. +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-0005] Slots per section 200 +[INFO PPL-0008] Successfully assigned pins to sections. +pin to stripe violations: 0 diff --git a/src/ppl/test/pdn_boundary_stripes_polygon.tcl b/src/ppl/test/pdn_boundary_stripes_polygon.tcl new file mode 100644 index 00000000000..86cf7592a27 --- /dev/null +++ b/src/ppl/test/pdn_boundary_stripes_polygon.tcl @@ -0,0 +1,26 @@ +# place_pins must not place pins over boundary PDN stripes on polygon dies +source "helpers.tcl" +source "pdn_helpers.tcl" + +# slot count and HPWL change once boundary PDN shapes block slots +suppress_message PPL 1 +suppress_message PPL 12 + +read_lef Nangate45/Nangate45.lef +read_def gcd_polygon_pre_ppl-tcl.def + +set block [ord::get_db_block] +set metal2 [[ord::get_db_tech] findLayer metal2] + +# stripe without pins touching the bottom edge of the polygon stem +set net [$block findNet "VDD"] +set swire [odb::dbSWire_create $net "ROUTED"] +odb::dbSBox_create $swire $metal2 70000 0 74000 20000 "STRIPE" +# stripe touching the internal edge of the polygon, which the die area +# bounding box cannot represent +odb::dbSBox_create $swire $metal2 20000 80000 24000 100000 "STRIPE" + +place_pins -hor_layers metal3 -ver_layers metal2 -corner_avoidance 0 \ + -min_distance 0.12 + +puts "pin to stripe violations: [count_pdn_shape_violations spacing]" diff --git a/src/ppl/test/pdn_boundary_vias.ok b/src/ppl/test/pdn_boundary_vias.ok new file mode 100644 index 00000000000..e043c6d8dd5 --- /dev/null +++ b/src/ppl/test/pdn_boundary_vias.ok @@ -0,0 +1,12 @@ +[INFO ODB-0227] LEF file: Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells +[INFO ODB-0128] Design: gcd +[INFO ODB-0130] Created 54 pins. +[INFO ODB-0131] Created 549 components and 2166 component-terminals. +[INFO ODB-0133] Created 364 nets and 1068 connections. +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-0005] Slots per section 200 +[INFO PPL-0008] Successfully assigned pins to sections. +pin to via pad violations: 0 diff --git a/src/ppl/test/pdn_boundary_vias.tcl b/src/ppl/test/pdn_boundary_vias.tcl new file mode 100644 index 00000000000..d65d1d7709e --- /dev/null +++ b/src/ppl/test/pdn_boundary_vias.tcl @@ -0,0 +1,34 @@ +# place_pins must keep min spacing from special net via landing pads close to +# the die boundary, even when no wire shape covers them +source "helpers.tcl" +source "pdn_helpers.tcl" + +# slot count and HPWL change once boundary PDN shapes block slots +suppress_message PPL 1 +suppress_message PPL 12 + +read_lef Nangate45/Nangate45.lef +read_def gcd_placed.def + +set block [ord::get_db_block] +set tech [ord::get_db_tech] +set via [$tech findVia "via1_0"] + +# naked vias near the top edge; via1_0 metal2 enclosure is 0.07um around the +# origin, so the pads span y 295650-295930, within reach of the pins +set net [odb::dbNet_create $block "VDD"] +$net setSpecial +$net setSigType POWER +set swire [odb::dbSWire_create $net "ROUTED"] +for { set x 98000 } { $x <= 106000 } { incr x 380 } { + odb::dbSBox_create $swire $via $x 295790 "STRIPE" +} + +place_pins -hor_layers metal3 -ver_layers metal2 -corner_avoidance 0 \ + -min_distance 0.12 + +set via_rects {} +for { set x 98000 } { $x <= 106000 } { incr x 380 } { + lappend via_rects [list [expr { $x - 140 }] 295650 [expr { $x + 140 }] 295930] +} +puts "pin to via pad violations: [count_rect_violations metal2 $via_rects spacing]" diff --git a/src/ppl/test/pdn_helpers.tcl b/src/ppl/test/pdn_helpers.tcl new file mode 100644 index 00000000000..5a9745be020 --- /dev/null +++ b/src/ppl/test/pdn_helpers.tcl @@ -0,0 +1,105 @@ +# Helper procs for the boundary PDN tests. A violation is a signal pin shape +# closer to a blocking shape than the required spacing: "overlap" requires +# plain intersection, "spacing" uses the layer default spacing and "table" +# the width-dependent spacing for wide shapes. + +proc get_required_spacing { layer pin_box llx lly urx ury mode } { + if { $mode == "overlap" } { + return 0 + } + if { [string is integer -strict $mode] } { + return $mode + } + if { $mode == "table" } { + set shape_width [expr { min($urx - $llx, $ury - $lly) }] + set pin_length [expr { + max([$pin_box xMax] - [$pin_box xMin], [$pin_box yMax] - [$pin_box yMin]) + }] + return [$layer getSpacing $shape_width $pin_length] + } + return [$layer getSpacing] +} + +proc is_pin_shape_violation { pin_box llx lly urx ury required } { + set dx [expr { max($llx - [$pin_box xMax], [$pin_box xMin] - $urx) }] + set dy [expr { max($lly - [$pin_box yMax], [$pin_box yMin] - $ury) }] + if { $dx < 0 && $dy < 0 } { + return 1 + } + return [expr { max($dx, 0) < $required && max($dy, 0) < $required }] +} + +proc report_pin_violation { bterm box what } { + puts "pin [$bterm getName] on layer [[$box getTechLayer] getName] at\ + ([ord::dbu_to_microns [$box xMin]] [ord::dbu_to_microns [$box yMin]])\ + ([ord::dbu_to_microns [$box xMax]] [ord::dbu_to_microns [$box yMax]])\ + too close to $what" +} + +# count signal pin shapes too close to same layer special net wires +proc count_pdn_shape_violations { mode } { + set block [ord::get_db_block] + set violations 0 + foreach bterm [$block getBTerms] { + if { [$bterm getSigType] == "POWER" || [$bterm getSigType] == "GROUND" } { + continue + } + foreach bpin [$bterm getBPins] { + foreach box [$bpin getBoxes] { + set layer [$box getTechLayer] + foreach net [$block getNets] { + if { ![$net isSpecial] } { + continue + } + foreach swire [$net getSWires] { + foreach sbox [$swire getWires] { + set slayer [$sbox getTechLayer] + if { $slayer == "NULL" || $slayer != $layer } { + continue + } + set required [get_required_spacing $layer $box [$sbox xMin] \ + [$sbox yMin] [$sbox xMax] [$sbox yMax] $mode] + if { + [is_pin_shape_violation $box [$sbox xMin] [$sbox yMin] \ + [$sbox xMax] [$sbox yMax] $required] + } { + report_pin_violation $bterm $box "[$net getName] wire" + incr violations + } + } + } + } + } + } + } + return $violations +} + +# count signal pin shapes on the given layer too close to the given rects +proc count_rect_violations { layer_name rects mode } { + set block [ord::get_db_block] + set violations 0 + foreach bterm [$block getBTerms] { + if { [$bterm getSigType] == "POWER" || [$bterm getSigType] == "GROUND" } { + continue + } + foreach bpin [$bterm getBPins] { + foreach box [$bpin getBoxes] { + set layer [$box getTechLayer] + if { [$layer getName] != $layer_name } { + continue + } + foreach rect $rects { + lassign $rect llx lly urx ury + set required \ + [get_required_spacing $layer $box $llx $lly $urx $ury $mode] + if { [is_pin_shape_violation $box $llx $lly $urx $ury $required] } { + report_pin_violation $bterm $box "shape ($llx $lly) ($urx $ury)" + incr violations + } + } + } + } + } + return $violations +} diff --git a/src/ppl/test/pdn_near_boundary_stripes.ok b/src/ppl/test/pdn_near_boundary_stripes.ok new file mode 100644 index 00000000000..1d31f5afcbc --- /dev/null +++ b/src/ppl/test/pdn_near_boundary_stripes.ok @@ -0,0 +1,12 @@ +[INFO ODB-0227] LEF file: Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells +[INFO ODB-0128] Design: gcd +[INFO ODB-0130] Created 54 pins. +[INFO ODB-0131] Created 549 components and 2166 component-terminals. +[INFO ODB-0133] Created 364 nets and 1068 connections. +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-0005] Slots per section 200 +[INFO PPL-0008] Successfully assigned pins to sections. +pin to near boundary stripe violations: 0 diff --git a/src/ppl/test/pdn_near_boundary_stripes.tcl b/src/ppl/test/pdn_near_boundary_stripes.tcl new file mode 100644 index 00000000000..eedf247a286 --- /dev/null +++ b/src/ppl/test/pdn_near_boundary_stripes.tcl @@ -0,0 +1,26 @@ +# place_pins must keep min spacing from PDN stripes close to the die boundary, +# even when they do not touch it, since pin shapes extend into the die +source "helpers.tcl" +source "pdn_helpers.tcl" + +# slot count and HPWL change once boundary PDN shapes block slots +suppress_message PPL 1 +suppress_message PPL 12 + +read_lef Nangate45/Nangate45.lef +read_def gcd_placed.def + +set block [ord::get_db_block] +set metal2 [[ord::get_db_tech] findLayer metal2] + +# stripe without pins ending 0.05um inside the top edge (die top y=296000) +set net [odb::dbNet_create $block "VDD"] +$net setSpecial +$net setSigType POWER +set swire [odb::dbSWire_create $net "ROUTED"] +odb::dbSBox_create $swire $metal2 22140 295340 273640 295900 "STRIPE" + +place_pins -hor_layers metal3 -ver_layers metal2 -corner_avoidance 0 \ + -min_distance 0.12 + +puts "pin to near boundary stripe violations: [count_pdn_shape_violations spacing]" diff --git a/src/ppl/test/pdn_near_boundary_stripes_length.ok b/src/ppl/test/pdn_near_boundary_stripes_length.ok new file mode 100644 index 00000000000..a3b06f7eb96 --- /dev/null +++ b/src/ppl/test/pdn_near_boundary_stripes_length.ok @@ -0,0 +1,12 @@ +[INFO ODB-0227] LEF file: Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells +[INFO ODB-0128] Design: gcd +[INFO ODB-0130] Created 54 pins. +[INFO ODB-0131] Created 549 components and 2166 component-terminals. +[INFO ODB-0133] Created 364 nets and 1068 connections. +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-0005] Slots per section 200 +[INFO PPL-0008] Successfully assigned pins to sections. +pin to stripe violations: 0 diff --git a/src/ppl/test/pdn_near_boundary_stripes_length.tcl b/src/ppl/test/pdn_near_boundary_stripes_length.tcl new file mode 100644 index 00000000000..cb425f3e83a --- /dev/null +++ b/src/ppl/test/pdn_near_boundary_stripes_length.tcl @@ -0,0 +1,30 @@ +# place_pins must keep min spacing from near-boundary PDN stripes when the pin +# length is not aligned to the manufacturing grid, since the created pins are +# rounded up to it +source "helpers.tcl" +source "pdn_helpers.tcl" + +# slot count and HPWL change once boundary PDN shapes block slots +suppress_message PPL 1 +suppress_message PPL 12 + +read_lef Nangate45/Nangate45.lef +read_def gcd_placed.def + +set block [ord::get_db_block] +set metal2 [[ord::get_db_tech] findLayer metal2] + +# stripe just outside the reach of a 1.001um pin before mfg-grid rounding; +# the actual pins round up to 1.005um and reach it +set net [odb::dbNet_create $block "VDD"] +$net setSpecial +$net setSigType POWER +set swire [odb::dbSWire_create $net "ROUTED"] +odb::dbSBox_create $swire $metal2 20000 291857 280000 293857 "STRIPE" + +set_pin_length -ver_length 1.001 -hor_length 1.001 + +place_pins -hor_layers metal3 -ver_layers metal2 -corner_avoidance 0 \ + -min_distance 0.12 + +puts "pin to stripe violations: [count_pdn_shape_violations spacing]" diff --git a/src/ppl/test/top_layer_pdn_spacing.ok b/src/ppl/test/top_layer_pdn_spacing.ok new file mode 100644 index 00000000000..e2dceaee157 --- /dev/null +++ b/src/ppl/test/top_layer_pdn_spacing.ok @@ -0,0 +1,20 @@ +[INFO ODB-0227] LEF file: sky130hd/sky130hd.tlef, created 13 layers, 25 vias +[INFO ODB-0227] LEF file: sky130hd/sky130_fd_sc_hd_merged.lef, created 437 library cells +[INFO ODB-0227] LEF file: blocked_region.lef, created 1 library cells +[INFO ODB-0128] Design: gcd +[INFO ODB-0130] Created 54 pins. +[INFO ODB-0131] Created 253 components and 1357 component-terminals. +[INFO ODB-0133] Created 54 nets and 155 connections. +Found 1 macro blocks. +Using 2 tracks default min distance between IO pins. +[INFO PPL-0060] Restrict pins [ clk req_rdy req_val reset resp_rdy ... ] to region (50.00u, 122.95u)-(250.00u, 204.00u) at routing layer met5. +[INFO PPL-0001] Number of available slots 866 +[INFO PPL-0062] Number of top layer slots 360 +[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-0008] Successfully assigned pins to sections. +[INFO PPL-0012] I/O nets HPWL: 7599.82 um. +pin to strap spacing violations: 0 +pin to min spacing obstruction violations: 0 diff --git a/src/ppl/test/top_layer_pdn_spacing.tcl b/src/ppl/test/top_layer_pdn_spacing.tcl new file mode 100644 index 00000000000..57645c1904c --- /dev/null +++ b/src/ppl/test/top_layer_pdn_spacing.tcl @@ -0,0 +1,38 @@ +# top layer pin placement must keep at least the layer min spacing from PDN +# shapes when the user keepout is smaller than it +source "helpers.tcl" +source "pdn_helpers.tcl" + +read_lef sky130hd/sky130hd.tlef +read_lef sky130hd/sky130_fd_sc_hd_merged.lef +read_lef blocked_region.lef + +read_def blocked_region.def + +set block [ord::get_db_block] +set met5 [[ord::get_db_tech] findLayer met5] + +# wide strap crossing the pin pattern region +set net [odb::dbNet_create $block "VDD"] +$net setSpecial +$net setSigType POWER +set swire [odb::dbSWire_create $net "ROUTED"] +odb::dbSBox_create $swire $met5 50000 125000 250000 130000 "STRIPE" + +# obstruction with a min spacing rule larger than the layer spacing +set obs [odb::dbObstruction_create $block $met5 50000 205000 250000 210000] +$obs setMinSpacing 10000 + +# the first slot row ends 0.8um below the strap: allowed by the 0.3um user +# keepout, but closer than the layer min spacing +define_pin_shape_pattern -layer met5 -x_step 6.8 -y_step 6.8 \ + -region { 50 122.95 250 204 } -size { 1.6 2.5 } -pin_keepout 0.3 +set_io_pin_constraint \ + -pin_names {clk resp_val req_val resp_rdy reset req_rdy} -region "up:*" + +place_pins -hor_layer met3 -ver_layer met2 + +puts "pin to strap spacing violations: [count_pdn_shape_violations table]" +set obstruction_rect [list [list 50000 205000 250000 210000]] +puts "pin to min spacing obstruction violations:\ + [count_rect_violations met5 $obstruction_rect 10000]"