diff --git a/src/mpl2/README.md b/src/mpl2/README.md index 6c8aab5f2a5..5c70abef73c 100644 --- a/src/mpl2/README.md +++ b/src/mpl2/README.md @@ -25,7 +25,6 @@ rtl_macro_placer [-tolerance tolerance] [-max_num_level max_num_level] [-coarsening_ratio coarsening_ratio] - [-num_bundled_ios num_bundled_ios] [-large_net_threshold large_net_threshold] [-signature_net_threshold signature_net_threshold] [-halo_width halo_width] @@ -61,7 +60,6 @@ rtl_macro_placer | `-tolerance` | Add a margin to the minimum and maximum number of macros/std cells in a cluster. For min, we multiply by (1 - `tol`), and for the max (1 + `tol`). This is to improve the robustness of hierarchical clustering. The allowed values are floats `[0, 1)`, and the default value is `0.1`. | | `-max_num_level` | Maximum depth of physical hierarchical tree. The default value is `2`, and the allowed values are integers `[0, MAX_INT]`. | | `-coarsening_ratio` | The larger the coarsening_ratio, the faster the convergence process. The allowed values are floats, and the default value is `10.0`. | -| `-num_bundled_ios` | Specifies the number of bundled pins for the left, right, top, and bottom boundaries. The default value is `3`, and the allowed values are integers `[0, MAX_INT]`. | | `-large_net_threshold` | Ignore nets with many connections during clustering, such as global nets. The default value is `50`, and the allowed values are integers `[0, MAX_INT]`. | | `-signature_net_threshold` | Minimum number of connections between two clusters to be identified as connected. The default value is `50`, and the allowed values are integers `[0, MAX_INT]`. | | `-halo_width` | Horizontal/vertical halo around macros (microns). The allowed values are floats, and the default value is `0.0`. | diff --git a/src/mpl2/include/mpl2/rtl_mp.h b/src/mpl2/include/mpl2/rtl_mp.h index 5e6b95a8d73..2eb5379e889 100644 --- a/src/mpl2/include/mpl2/rtl_mp.h +++ b/src/mpl2/include/mpl2/rtl_mp.h @@ -80,7 +80,6 @@ class MacroPlacer2 float tolerance, int max_num_level, float coarsening_ratio, - int num_bundled_ios, int large_net_threshold, int signature_net_threshold, float halo_width, diff --git a/src/mpl2/src/Mpl2Observer.h b/src/mpl2/src/Mpl2Observer.h index d02057926db..3f8b65ddbd1 100644 --- a/src/mpl2/src/Mpl2Observer.h +++ b/src/mpl2/src/Mpl2Observer.h @@ -38,6 +38,7 @@ #include #include +#include "clusterEngine.h" #include "object.h" #include "odb/geom.h" #include "utl/Logger.h" @@ -68,7 +69,7 @@ class Mpl2Observer virtual void endSA(float norm_cost) {} virtual void drawResult() {} - virtual void finishedClustering(Cluster* root) {} + virtual void finishedClustering(PhysicalHierarchy* tree) {} virtual void setMaxLevel(int max_level) {} virtual void setMacroBlockages(const std::vector& macro_blockages) diff --git a/src/mpl2/src/SACoreHardMacro.cpp b/src/mpl2/src/SACoreHardMacro.cpp index 50e426045ff..5271adff7bc 100644 --- a/src/mpl2/src/SACoreHardMacro.cpp +++ b/src/mpl2/src/SACoreHardMacro.cpp @@ -45,6 +45,7 @@ using utl::MPL; // Class SACoreHardMacro // constructors SACoreHardMacro::SACoreHardMacro( + PhysicalHierarchy* tree, const Rect& outline, const std::vector& macros, // weight for different penalty @@ -66,7 +67,8 @@ SACoreHardMacro::SACoreHardMacro( unsigned seed, Mpl2Observer* graphics, utl::Logger* logger) - : SimulatedAnnealingCore(outline, + : SimulatedAnnealingCore(tree, + outline, macros, area_weight, outline_weight, diff --git a/src/mpl2/src/SACoreHardMacro.h b/src/mpl2/src/SACoreHardMacro.h index 397ba020252..121aec0e8ec 100644 --- a/src/mpl2/src/SACoreHardMacro.h +++ b/src/mpl2/src/SACoreHardMacro.h @@ -49,7 +49,8 @@ namespace mpl2 { class SACoreHardMacro : public SimulatedAnnealingCore { public: - SACoreHardMacro(const Rect& outline, + SACoreHardMacro(PhysicalHierarchy* tree, + const Rect& outline, const std::vector& macros, // weight for different penalty float area_weight, diff --git a/src/mpl2/src/SACoreSoftMacro.cpp b/src/mpl2/src/SACoreSoftMacro.cpp index 390ab47f911..e00895abe66 100644 --- a/src/mpl2/src/SACoreSoftMacro.cpp +++ b/src/mpl2/src/SACoreSoftMacro.cpp @@ -45,7 +45,7 @@ using utl::MPL; // Class SACoreSoftMacro // constructors SACoreSoftMacro::SACoreSoftMacro( - Cluster* root, + PhysicalHierarchy* tree, const Rect& outline, const std::vector& macros, // weight for different penalty @@ -73,7 +73,8 @@ SACoreSoftMacro::SACoreSoftMacro( unsigned seed, Mpl2Observer* graphics, utl::Logger* logger) - : SimulatedAnnealingCore(outline, + : SimulatedAnnealingCore(tree, + outline, macros, area_weight, outline_weight, @@ -90,7 +91,7 @@ SACoreSoftMacro::SACoreSoftMacro( seed, graphics, logger), - root_(root) + root_(tree->root.get()) { boundary_weight_ = boundary_weight; macro_blockage_weight_ = macro_blockage_weight; diff --git a/src/mpl2/src/SACoreSoftMacro.h b/src/mpl2/src/SACoreSoftMacro.h index 2356732cd5f..27da80022ca 100644 --- a/src/mpl2/src/SACoreSoftMacro.h +++ b/src/mpl2/src/SACoreSoftMacro.h @@ -50,7 +50,7 @@ class Graphics; class SACoreSoftMacro : public SimulatedAnnealingCore { public: - SACoreSoftMacro(Cluster* root, + SACoreSoftMacro(PhysicalHierarchy* tree, const Rect& outline, const std::vector& macros, // weight for different penalty diff --git a/src/mpl2/src/SimulatedAnnealingCore.cpp b/src/mpl2/src/SimulatedAnnealingCore.cpp index f49af42ca56..eff1289c297 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.cpp +++ b/src/mpl2/src/SimulatedAnnealingCore.cpp @@ -49,6 +49,7 @@ using std::string; // Class SimulatedAnnealingCore template SimulatedAnnealingCore::SimulatedAnnealingCore( + PhysicalHierarchy* tree, const Rect& outline, // boundary constraints const std::vector& macros, // macros (T = HardMacro or T = SoftMacro) // weight for different penalty @@ -69,7 +70,9 @@ SimulatedAnnealingCore::SimulatedAnnealingCore( unsigned seed, Mpl2Observer* graphics, utl::Logger* logger) - : outline_(outline), graphics_(graphics) + : outline_(outline), + blocked_boundaries_(tree->blocked_boundaries), + graphics_(graphics) { area_weight_ = area_weight; outline_weight_ = outline_weight; @@ -94,6 +97,28 @@ SimulatedAnnealingCore::SimulatedAnnealingCore( logger_ = logger; macros_ = macros; + + setBlockedBoundariesForIOs(); +} + +template +void SimulatedAnnealingCore::setBlockedBoundariesForIOs() +{ + if (blocked_boundaries_.find(Boundary::L) != blocked_boundaries_.end()) { + left_is_blocked_ = true; + } + + if (blocked_boundaries_.find(Boundary::R) != blocked_boundaries_.end()) { + right_is_blocked_ = true; + } + + if (blocked_boundaries_.find(Boundary::B) != blocked_boundaries_.end()) { + bottom_is_blocked_ = true; + } + + if (blocked_boundaries_.find(Boundary::T) != blocked_boundaries_.end()) { + top_is_blocked_ = true; + } } template @@ -274,10 +299,18 @@ void SimulatedAnnealingCore::calWirelength() } for (const auto& net : nets_) { - const float x1 = macros_[net.terminals.first].getPinX(); - const float y1 = macros_[net.terminals.first].getPinY(); - const float x2 = macros_[net.terminals.second].getPinX(); - const float y2 = macros_[net.terminals.second].getPinY(); + T& source = macros_[net.terminals.first]; + T& target = macros_[net.terminals.second]; + + if (target.isIOCluster()) { + addBoundaryDistToWirelength(source, target, net.weight); + continue; + } + + const float x1 = source.getPinX(); + const float y1 = source.getPinY(); + const float x2 = target.getPinX(); + const float y2 = target.getPinY(); wirelength_ += net.weight * (std::abs(x2 - x1) + std::abs(y2 - y1)); } @@ -291,6 +324,71 @@ void SimulatedAnnealingCore::calWirelength() } } +template +void SimulatedAnnealingCore::addBoundaryDistToWirelength( + const T& macro, + const T& io, + const float net_weight) +{ + Cluster* io_cluster = io.getCluster(); + const Rect die = io_cluster->getBBox(); + const float die_hpwl = die.getWidth() + die.getHeight(); + + if (isOutsideTheOutline(macro)) { + wirelength_ += net_weight * die_hpwl; + return; + } + + const float x1 = macro.getPinX(); + const float y1 = macro.getPinY(); + + Boundary constraint_boundary = io_cluster->getConstraintBoundary(); + + if (constraint_boundary == NONE) { + float dist_to_left = die_hpwl; + if (!left_is_blocked_) { + dist_to_left = std::abs(x1 - die.xMin()); + } + + float dist_to_right = die_hpwl; + if (!right_is_blocked_) { + dist_to_right = std::abs(x1 - die.xMax()); + } + + float dist_to_bottom = die_hpwl; + if (!bottom_is_blocked_) { + dist_to_right = std::abs(y1 - die.yMin()); + } + + float dist_to_top = die_hpwl; + if (!top_is_blocked_) { + dist_to_top = std::abs(y1 - die.yMax()); + } + + wirelength_ + += net_weight + * std::min( + {dist_to_left, dist_to_right, dist_to_bottom, dist_to_top}); + } else if (constraint_boundary == Boundary::L + || constraint_boundary == Boundary::R) { + const float x2 = io.getPinX(); + wirelength_ += net_weight * std::abs(x2 - x1); + } else if (constraint_boundary == Boundary::T + || constraint_boundary == Boundary::B) { + const float y2 = io.getPinY(); + wirelength_ += net_weight * std::abs(y2 - y1); + } +} + +// We consider the macro outside the outline based on the location of +// the pin to avoid too many checks. +template +bool SimulatedAnnealingCore::isOutsideTheOutline(const T& macro) const +{ + return macro.getPinX() > outline_.getWidth() + || macro.getPinY() > outline_.getHeight(); +} + template void SimulatedAnnealingCore::calFencePenalty() { diff --git a/src/mpl2/src/SimulatedAnnealingCore.h b/src/mpl2/src/SimulatedAnnealingCore.h index 29e835178a1..7f8e78050ec 100644 --- a/src/mpl2/src/SimulatedAnnealingCore.h +++ b/src/mpl2/src/SimulatedAnnealingCore.h @@ -38,6 +38,7 @@ #include #include "Mpl2Observer.h" +#include "clusterEngine.h" namespace utl { class Logger; @@ -68,6 +69,7 @@ class SimulatedAnnealingCore { public: SimulatedAnnealingCore( + PhysicalHierarchy* tree, const Rect& outline, // boundary constraints const std::vector& macros, // macros (T = HardMacro or T = SoftMacro) // weight for different penalty @@ -134,6 +136,7 @@ class SimulatedAnnealingCore void fastSA(); void initSequencePair(); + void setBlockedBoundariesForIOs(); void updateBestValidResult(); void useBestValidResult(); @@ -141,6 +144,10 @@ class SimulatedAnnealingCore virtual void calPenalty() = 0; void calOutlinePenalty(); void calWirelength(); + void addBoundaryDistToWirelength(const T& macro, + const T& io, + float net_weight); + bool isOutsideTheOutline(const T& macro) const; void calGuidancePenalty(); void calFencePenalty(); @@ -165,6 +172,9 @@ class SimulatedAnnealingCore // boundary constraints Rect outline_; + // Boundaries blocked for IO pins + std::set blocked_boundaries_; + // Number of macros that will actually be part of the sequence pair int macros_to_place_ = 0; @@ -249,6 +259,13 @@ class SimulatedAnnealingCore static constexpr float acc_tolerance_ = 0.001; bool has_initial_sequence_pair_ = false; + + // Blocked boundaries data is kept in bools to avoid overhead + // during SA steps. + bool left_is_blocked_ = false; + bool right_is_blocked_ = false; + bool bottom_is_blocked_ = false; + bool top_is_blocked_ = false; }; // SACore wrapper function diff --git a/src/mpl2/src/clusterEngine.cpp b/src/mpl2/src/clusterEngine.cpp index 28967392d33..50e900832ac 100644 --- a/src/mpl2/src/clusterEngine.cpp +++ b/src/mpl2/src/clusterEngine.cpp @@ -66,6 +66,8 @@ void ClusteringEngine::run() setBaseThresholds(); createIOClusters(); + classifyBoundariesStateForIOs(); + createDataFlow(); if (design_metrics_->getNumStdCell() == 0) { @@ -355,165 +357,158 @@ void ClusteringEngine::setBaseThresholds() tree_->base_min_std_cell); } +// Group IOs with the same constraints: +// 1. If an IO has a constraint region in a certain boundary, +// it is constrained to that entire boundary. +// 2. If an IO has no constraints, it is constrained to all boundaries. void ClusteringEngine::createIOClusters() { mapIOPads(); - debugPrint(logger_, - MPL, - "multilevel_autoclustering", - 1, - "Creating bundledIO clusters..."); - // Get the floorplan information and get the range of bundled IO regions + // Boundary with constrained IOs -> cluster + std::map boundary_to_cluster; const odb::Rect die = block_->getDieArea(); - const odb::Rect core = block_->getCoreArea(); - const int x_base = (die.xMax() - die.xMin()) / tree_->bundled_ios_per_edge; - const int y_base = (die.yMax() - die.yMin()) / tree_->bundled_ios_per_edge; - const int cluster_id_base = id_; - - // Map all the BTerms / Pads to Bundled IOs (cluster) - std::vector prefix_vec; - prefix_vec.emplace_back("L"); - prefix_vec.emplace_back("T"); - prefix_vec.emplace_back("R"); - prefix_vec.emplace_back("B"); - std::map cluster_io_map; - for (int i = 0; i < 4; - i++) { // four boundaries (Left, Top, Right and Bottom in order) - for (int j = 0; j < tree_->bundled_ios_per_edge; j++) { - const std::string cluster_name = prefix_vec[i] + std::to_string(j); - auto cluster = std::make_unique(id_, cluster_name, logger_); - cluster->setParent(tree_->root.get()); - cluster_io_map[id_] = false; - tree_->maps.id_to_cluster[id_++] = cluster.get(); - int x = 0.0; - int y = 0.0; - int width = 0; - int height = 0; - if (i == 0) { // Left boundary - x = die.xMin(); - y = die.yMin() + y_base * j; - height = y_base; - } else if (i == 1) { // Top boundary - x = die.xMin() + x_base * j; - y = die.yMax(); - width = x_base; - } else if (i == 2) { // Right boundary - x = die.xMax(); - y = die.yMax() - y_base * (j + 1); - height = y_base; - } else { // Bottom boundary - x = die.xMax() - x_base * (j + 1); - y = die.yMin(); - width = x_base; - } - // set the cluster to a IO cluster - cluster->setAsIOCluster(std::pair(block_->dbuToMicrons(x), - block_->dbuToMicrons(y)), - block_->dbuToMicrons(width), - block_->dbuToMicrons(height)); - tree_->root->addChild(std::move(cluster)); - } - } - - // Map all the BTerms to bundled IOs - for (auto term : block_->getBTerms()) { - int lx = std::numeric_limits::max(); - int ly = std::numeric_limits::max(); - int ux = 0; - int uy = 0; - // If the design has IO pads, these block terms - // will not have block pins. - // Otherwise, the design will have IO pins. - for (const auto pin : term->getBPins()) { - for (const auto box : pin->getBoxes()) { - lx = std::min(lx, box->xMin()); - ly = std::min(ly, box->yMin()); - ux = std::max(ux, box->xMax()); - uy = std::max(uy, box->yMax()); - } + for (odb::dbBTerm* bterm : block_->getBTerms()) { + Boundary constraint_boundary = NONE; + + auto constraint_region = bterm->getConstraintRegion(); + if (constraint_region) { + constraint_boundary + = getConstraintBoundary(die, constraint_region.value()); } - // remove power pins - if (term->getSigType().isSupply()) { - continue; + + const auto itr = boundary_to_cluster.find(constraint_boundary); + if (itr != boundary_to_cluster.end()) { + Cluster* io_cluster = itr->second; + tree_->maps.bterm_to_cluster_id[bterm] = io_cluster->getId(); + } else { + createIOCluster(die, constraint_boundary, boundary_to_cluster, bterm); } + } - // If the term has a connected pad, get the bbox from the pad inst - if (tree_->maps.bterm_to_inst.find(term) - != tree_->maps.bterm_to_inst.end()) { - lx = tree_->maps.bterm_to_inst[term]->getBBox()->xMin(); - ly = tree_->maps.bterm_to_inst[term]->getBBox()->yMin(); - ux = tree_->maps.bterm_to_inst[term]->getBBox()->xMax(); - uy = tree_->maps.bterm_to_inst[term]->getBBox()->yMax(); - if (lx <= core.xMin()) { - lx = die.xMin(); - } - if (ly <= core.yMin()) { - ly = die.yMin(); - } - if (ux >= core.xMax()) { - ux = die.xMax(); - } - if (uy >= core.yMax()) { - uy = die.yMax(); - } + if (tree_->maps.id_to_cluster.size() == 1) { + logger_->warn(MPL, 26, "Design has no IO pins!"); + tree_->has_io_clusters = false; + } +} + +Boundary ClusteringEngine::getConstraintBoundary( + const odb::Rect& die, + const odb::Rect& constraint_region) +{ + Boundary constraint_boundary = NONE; + if (constraint_region.xMin() == constraint_region.xMax()) { + if (constraint_region.xMin() == die.xMin()) { + constraint_boundary = L; + } else { + constraint_boundary = R; } - // calculate cluster id based on the location of IO Pins / Pads - int cluster_id = -1; - if (lx <= die.xMin()) { - // The IO is on the left boundary - cluster_id = cluster_id_base - + std::floor(((ly + uy) / 2.0 - die.yMin()) / y_base); - } else if (uy >= die.yMax()) { - // The IO is on the top boundary - cluster_id = cluster_id_base + tree_->bundled_ios_per_edge - + std::floor(((lx + ux) / 2.0 - die.xMin()) / x_base); - } else if (ux >= die.xMax()) { - // The IO is on the right boundary - cluster_id = cluster_id_base + tree_->bundled_ios_per_edge * 2 - + std::floor((die.yMax() - (ly + uy) / 2.0) / y_base); - } else if (ly <= die.yMin()) { - // The IO is on the bottom boundary - cluster_id = cluster_id_base + tree_->bundled_ios_per_edge * 3 - + std::floor((die.xMax() - (lx + ux) / 2.0) / x_base); - } - - // Check if the IO pins / Pads exist - if (cluster_id == -1) { - logger_->error( - MPL, - 2, - "Floorplan has not been initialized? Pin location error for {}.", - term->getName()); + } else { + if (constraint_region.yMin() == die.yMin()) { + constraint_boundary = B; } else { - tree_->maps.bterm_to_cluster_id[term] = cluster_id; + constraint_boundary = T; } + } + return constraint_boundary; +} + +void ClusteringEngine::createIOCluster( + const odb::Rect& die, + const Boundary constraint_boundary, + std::map& boundary_to_cluster, + odb::dbBTerm* bterm) +{ + auto cluster + = std::make_unique(id_, toString(constraint_boundary), logger_); + tree_->maps.bterm_to_cluster_id[bterm] = id_; + tree_->maps.id_to_cluster[id_++] = cluster.get(); + + boundary_to_cluster[constraint_boundary] = cluster.get(); + + int x = die.xMin(), y = die.yMin(); + int width = die.dx(), height = die.dy(); - cluster_io_map[cluster_id] = true; + if (constraint_boundary != NONE) { + setIOClusterDimensions(die, constraint_boundary, x, y, width, height); } - // delete the IO clusters that do not have any pins assigned to them - for (auto& [cluster_id, flag] : cluster_io_map) { - if (!flag) { - debugPrint(logger_, - MPL, - "multilevel_autoclustering", - 1, - "Remove IO Cluster with no pins: {}, id: {}", - tree_->maps.id_to_cluster[cluster_id]->getName(), - cluster_id); - std::unique_ptr released_bundled_io - = tree_->maps.id_to_cluster[cluster_id]->getParent()->releaseChild( - tree_->maps.id_to_cluster[cluster_id]); - tree_->maps.id_to_cluster.erase(cluster_id); + cluster->setAsIOCluster( + std::pair(block_->dbuToMicrons(x), block_->dbuToMicrons(y)), + block_->dbuToMicrons(width), + block_->dbuToMicrons(height), + constraint_boundary); + tree_->root->addChild(std::move(cluster)); +} + +void ClusteringEngine::classifyBoundariesStateForIOs() +{ + const float blocked_boundary_threshold = 0.7; + std::map blockage_extension_map + = computeBlockageExtensionMap(); + + for (const auto [boundary, blockage_extension] : blockage_extension_map) { + if (blockage_extension >= blocked_boundary_threshold) { + tree_->blocked_boundaries.insert(boundary); + } else { + tree_->unblocked_boundaries.insert(boundary); } } +} - // At this point the cluster map has only the root (id = 0) and bundledIOs - if (tree_->maps.id_to_cluster.size() == 1) { - logger_->warn(MPL, 26, "Design has no IO pins!"); - tree_->has_io_clusters = false; +// Computes how much blocked each boundary is for IOs base on PPL exclude +// contraints. +std::map ClusteringEngine::computeBlockageExtensionMap() +{ + std::map blockage_extension_map; + + blockage_extension_map[L] = 0.0; + blockage_extension_map[R] = 0.0; + blockage_extension_map[B] = 0.0; + blockage_extension_map[T] = 0.0; + + const odb::Rect die = block_->getDieArea(); + for (const odb::Rect& blocked_region : block_->getBlockedRegionsForPins()) { + Boundary blocked_region_boundary + = getConstraintBoundary(die, blocked_region); + float blockage_extension = 0.0; + + if (blocked_region_boundary == L || blocked_region_boundary == R) { + blockage_extension = blocked_region.dy() / static_cast(die.dy()); + } else if (blocked_region_boundary == B || blocked_region_boundary == T) { + blockage_extension = blocked_region.dx() / static_cast(die.dx()); + } + + blockage_extension_map[blocked_region_boundary] += blockage_extension; + } + + return blockage_extension_map; +} + +void ClusteringEngine::setIOClusterDimensions(const odb::Rect& die, + const Boundary boundary, + int& x, + int& y, + int& width, + int& height) +{ + if (boundary == L) { + x = die.xMin(); + y = die.yMin(); + width = 0; + } else if (boundary == T) { + x = die.xMin(); + y = die.yMax(); + height = 0; + } else if (boundary == R) { + x = die.xMax(); + y = die.yMin(); + width = 0; + } else { // Bottom + x = die.xMin(); + y = die.yMin(); + height = 0; } } @@ -911,12 +906,12 @@ void ClusteringEngine::updateDataFlow() // bterm, macros or ffs for (const auto& [bterm, insts] : data_connections_.io_and_regs) { - if (tree_->maps.bterm_to_cluster_id.find(bterm) - == tree_->maps.bterm_to_cluster_id.end()) { + const auto itr = tree_->maps.bterm_to_cluster_id.find(bterm); + if (itr == tree_->maps.bterm_to_cluster_id.end()) { continue; } - const int driver_id = tree_->maps.bterm_to_cluster_id.at(bterm); + const int driver_id = itr->second; for (int hops = 0; hops < max_num_of_hops_; hops++) { std::set sink_clusters = computeSinks(insts[hops]); @@ -1767,7 +1762,6 @@ void ClusteringEngine::updateConnections() } bool net_has_io_pin = false; - for (odb::dbBTerm* bterm : net->getBTerms()) { const int cluster_id = tree_->maps.bterm_to_cluster_id.at(bterm); net_has_io_pin = true; @@ -1938,6 +1932,10 @@ void ClusteringEngine::mapMacroInCluster2HardMacro(Cluster* cluster) getHardMacros(module, hard_macros); } cluster->specifyHardMacros(hard_macros); + + for (HardMacro* hard_macro : hard_macros) { + hard_macro->setCluster(cluster); + } } // Get all the hard macros in a logical module @@ -2158,17 +2156,30 @@ void ClusteringEngine::printPhysicalHierarchyTree(Cluster* parent, int level) for (int i = 0; i < level; i++) { line += "+---"; } - line += fmt::format( - "{} ({}) num_macro : {} num_std_cell : {}" - " macro_area : {} std_cell_area : {} cluster type: {} {}", - parent->getName(), - parent->getId(), - parent->getNumMacro(), - parent->getNumStdCell(), - parent->getMacroArea(), - parent->getStdCellArea(), - parent->getIsLeafString(), - parent->getClusterTypeString()); + + line += fmt::format("{} ({}) Type: {}", + parent->getName(), + parent->getId(), + parent->getClusterTypeString()); + + if (parent->isIOCluster()) { + int number_of_pins = 0; + for (const auto [pin, cluster_id] : tree_->maps.bterm_to_cluster_id) { + if (cluster_id == parent->getId()) { + ++number_of_pins; + } + } + + line += fmt::format(" Pins: {}", number_of_pins); + } else { + line += fmt::format(" {}, StdCells: {} ({} μ²), Macros: {} ({} μ²)", + parent->getIsLeafString(), + parent->getNumStdCell(), + parent->getStdCellArea(), + parent->getNumMacro(), + parent->getMacroArea()); + } + logger_->report("{}", line); for (auto& cluster : parent->getChildren()) { diff --git a/src/mpl2/src/clusterEngine.h b/src/mpl2/src/clusterEngine.h index c0031faf0dc..bfaa9c6b595 100644 --- a/src/mpl2/src/clusterEngine.h +++ b/src/mpl2/src/clusterEngine.h @@ -114,6 +114,10 @@ struct PhysicalHierarchy std::unique_ptr root; PhysicalHierarchyMaps maps; + // This is set according to the ppl -exclude constraints + std::set blocked_boundaries; + std::set unblocked_boundaries; // For orientation improvement. + float halo_width{0.0f}; float halo_height{0.0f}; float macro_with_halo_area{0.0f}; @@ -131,7 +135,6 @@ struct PhysicalHierarchy int base_min_std_cell{0}; int max_level{0}; - int bundled_ios_per_edge{0}; int large_net_threshold{0}; // used to ignore global nets int min_net_count_for_connection{0}; float cluster_size_ratio{0.0f}; @@ -188,6 +191,20 @@ class ClusteringEngine void createRoot(); void setBaseThresholds(); void createIOClusters(); + void classifyBoundariesStateForIOs(); + std::map computeBlockageExtensionMap(); + Boundary getConstraintBoundary(const odb::Rect& die, + const odb::Rect& constraint_region); + void createIOCluster(const odb::Rect& die, + Boundary constraint_boundary, + std::map& boundary_to_cluster, + odb::dbBTerm* bterm); + void setIOClusterDimensions(const odb::Rect& die, + Boundary boundary, + int& x, + int& y, + int& width, + int& height); void mapIOPads(); void treatEachMacroAsSingleCluster(); void incorporateNewCluster(std::unique_ptr cluster, Cluster* parent); diff --git a/src/mpl2/src/graphics.cpp b/src/mpl2/src/graphics.cpp index 70505ed08b8..f7bb784bc07 100644 --- a/src/mpl2/src/graphics.cpp +++ b/src/mpl2/src/graphics.cpp @@ -304,9 +304,46 @@ void Graphics::setMaxLevel(const int max_level) max_level_ = max_level; } -void Graphics::finishedClustering(Cluster* root) +void Graphics::finishedClustering(PhysicalHierarchy* tree) { - root_ = root; + root_ = tree->root.get(); + setXMarksSizeAndPosition(tree->blocked_boundaries); +} + +void Graphics::setXMarksSizeAndPosition( + const std::set& blocked_boundaries) +{ + const odb::Rect die = block_->getDieArea(); + + // Not too big/small + x_mark_size_ = (die.dx() + die.dy()) * 0.03; + + for (Boundary boundary : blocked_boundaries) { + odb::Point x_mark_point; + + switch (boundary) { + case L: { + x_mark_point = odb::Point(die.xMin(), die.yCenter()); + break; + } + case R: { + x_mark_point = odb::Point(die.xMax(), die.yCenter()); + break; + } + case B: { + x_mark_point = odb::Point(die.xCenter(), die.yMin()); + break; + } + case T: { + x_mark_point = odb::Point(die.xCenter(), die.yMax()); + break; + } + case NONE: + break; + } + + blocked_boundary_to_mark_[boundary] = x_mark_point; + } } void Graphics::drawCluster(Cluster* cluster, gui::Painter& painter) @@ -401,6 +438,16 @@ void Graphics::drawObjects(gui::Painter& painter) int i = 0; for (const auto& macro : soft_macros_) { + Cluster* cluster = macro.getCluster(); + + if (!cluster) { // fixed terminals + continue; + } + + if (cluster->isIOCluster()) { + continue; + } + setSoftMacroBrush(painter, macro); const int lx = block_->micronsToDbu(macro.getX()); @@ -496,6 +543,8 @@ void Graphics::drawObjects(gui::Painter& painter) } } + drawBlockedBoundariesIndication(painter); + painter.setBrush(gui::Painter::transparent); if (only_final_result_) { // Draw all outlines. Same level outlines have the same color. @@ -540,41 +589,189 @@ void Graphics::drawGuides(gui::Painter& painter) } } +void Graphics::drawBlockedBoundariesIndication(gui::Painter& painter) +{ + painter.setPen(gui::Painter::red, true); + painter.setBrush(gui::Painter::transparent); + + for (const auto [boundary, x_mark_point] : blocked_boundary_to_mark_) { + painter.drawX(x_mark_point.getX(), x_mark_point.getY(), x_mark_size_); + } +} + template void Graphics::drawBundledNets(gui::Painter& painter, const std::vector& macros) { for (const auto& bundled_net : bundled_nets_) { - const int x1 - = block_->micronsToDbu(macros[bundled_net.terminals.first].getPinX()); - const int y1 - = block_->micronsToDbu(macros[bundled_net.terminals.first].getPinY()); + const T& source = macros[bundled_net.terminals.first]; + const T& target = macros[bundled_net.terminals.second]; + + if (target.isIOCluster()) { + drawDistToIoConstraintBoundary(painter, source, target); + continue; + } + + const int x1 = block_->micronsToDbu(source.getPinX()); + const int y1 = block_->micronsToDbu(source.getPinY()); odb::Point from(x1, y1); - const int x2 - = block_->micronsToDbu(macros[bundled_net.terminals.second].getPinX()); - const int y2 - = block_->micronsToDbu(macros[bundled_net.terminals.second].getPinY()); + const int x2 = block_->micronsToDbu(target.getPinX()); + const int y2 = block_->micronsToDbu(target.getPinY()); odb::Point to(x2, y2); - from.addX(outline_.xMin()); - from.addY(outline_.yMin()); - to.addX(outline_.xMin()); - to.addY(outline_.yMin()); - + addOutlineOffsetToLine(from, to); painter.drawLine(from, to); } } +template +void Graphics::drawDistToIoConstraintBoundary(gui::Painter& painter, + const T& macro, + const T& io) +{ + if (isOutsideTheOutline(macro)) { + return; + } + + Cluster* io_cluster = io.getCluster(); + + const int x1 = block_->micronsToDbu(macro.getPinX()); + const int y1 = block_->micronsToDbu(macro.getPinY()); + odb::Point from(x1, y1); + + odb::Point to; + Boundary constraint_boundary = io_cluster->getConstraintBoundary(); + + if (constraint_boundary == Boundary::L + || constraint_boundary == Boundary::R) { + const int x2 = block_->micronsToDbu(io.getPinX()); + const int y2 = block_->micronsToDbu(macro.getPinY()); + to.setX(x2); + to.setY(y2); + } else if (constraint_boundary == Boundary::B + || constraint_boundary == Boundary::T) { + const int x2 = block_->micronsToDbu(macro.getPinX()); + const int y2 = block_->micronsToDbu(io.getPinY()); + to.setX(x2); + to.setY(y2); + } else { + // For NONE, the shape of the io cluster is the die area. + const Rect die = io_cluster->getBBox(); + Boundary closest_unblocked_boundary + = getClosestUnblockedBoundary(macro, die); + + to = getClosestBoundaryPoint(macro, die, closest_unblocked_boundary); + } + + addOutlineOffsetToLine(from, to); + + painter.drawLine(from, to); + painter.drawString(to.getX(), + to.getY(), + gui::Painter::CENTER, + toString(constraint_boundary)); +} + +template +bool Graphics::isOutsideTheOutline(const T& macro) const +{ + return block_->micronsToDbu(macro.getPinX()) > outline_.dx() + || block_->micronsToDbu(macro.getPinY()) > outline_.dy(); +} + +// Here, we have to manually decompensate the offset of the +// coordinates that come from the cluster. +template +odb::Point Graphics::getClosestBoundaryPoint(const T& macro, + const Rect& die, + Boundary closest_boundary) +{ + odb::Point to; + + if (closest_boundary == Boundary::L) { + to.setX(block_->micronsToDbu(die.xMin())); + to.setY(block_->micronsToDbu(macro.getPinY())); + to.addX(-outline_.xMin()); + } else if (closest_boundary == Boundary::R) { + to.setX(block_->micronsToDbu(die.xMax())); + to.setY(block_->micronsToDbu(macro.getPinY())); + to.addX(-outline_.xMin()); + } else if (closest_boundary == Boundary::B) { + to.setX(block_->micronsToDbu(macro.getPinX())); + to.setY(block_->micronsToDbu(die.yMin())); + to.addY(-outline_.yMin()); + } else { // Top + to.setX(block_->micronsToDbu(macro.getPinX())); + to.setY(block_->micronsToDbu(die.yMax())); + to.addY(-outline_.yMin()); + } + + return to; +} + +void Graphics::addOutlineOffsetToLine(odb::Point& from, odb::Point& to) +{ + from.addX(outline_.xMin()); + from.addY(outline_.yMin()); + to.addX(outline_.xMin()); + to.addY(outline_.yMin()); +} + +template +Boundary Graphics::getClosestUnblockedBoundary(const T& macro, const Rect& die) +{ + const float macro_x = macro.getPinX(); + const float macro_y = macro.getPinY(); + + float shortest_distance = std::numeric_limits::max(); + Boundary closest_boundary = Boundary::NONE; + + if (!isBlockedBoundary(Boundary::L)) { + const float dist_to_left = std::abs(macro_x - die.xMin()); + if (dist_to_left < shortest_distance) { + shortest_distance = dist_to_left; + closest_boundary = Boundary::L; + } + } + + if (!isBlockedBoundary(Boundary::R)) { + const float dist_to_right = std::abs(macro_x - die.xMax()); + if (dist_to_right < shortest_distance) { + shortest_distance = dist_to_right; + closest_boundary = Boundary::R; + } + } + + if (!isBlockedBoundary(Boundary::B)) { + const float dist_to_bottom = std::abs(macro_y - die.yMin()); + if (dist_to_bottom < shortest_distance) { + shortest_distance = dist_to_bottom; + closest_boundary = Boundary::B; + } + } + + if (!isBlockedBoundary(Boundary::T)) { + const float dist_to_top = std::abs(macro_y - die.yMax()); + if (dist_to_top < shortest_distance) { + closest_boundary = Boundary::T; + } + } + + return closest_boundary; +} + +bool Graphics::isBlockedBoundary(Boundary boundary) +{ + return blocked_boundary_to_mark_.find(boundary) + != blocked_boundary_to_mark_.end(); +} + // Give some transparency to mixed and hard so we can see overlap with // macro blockages. void Graphics::setSoftMacroBrush(gui::Painter& painter, const SoftMacro& soft_macro) { - if (soft_macro.getCluster() == nullptr) { // fixed terminals - return; - } - if (soft_macro.getCluster()->getClusterType() == StdCellCluster) { painter.setBrush(gui::Painter::dark_blue); } else if (soft_macro.getCluster()->getClusterType() == HardMacroCluster) { @@ -670,6 +867,7 @@ void Graphics::eraseDrawing() bundled_nets_.clear(); outline_.reset(0, 0, 0, 0); outlines_.clear(); + blocked_boundary_to_mark_.clear(); guides_.clear(); } diff --git a/src/mpl2/src/graphics.h b/src/mpl2/src/graphics.h index 9303b693f4a..ca53e453e01 100644 --- a/src/mpl2/src/graphics.h +++ b/src/mpl2/src/graphics.h @@ -60,7 +60,7 @@ class Graphics : public gui::Renderer, public Mpl2Observer void saStep(const std::vector& macros) override; void endSA(float norm_cost) override; void drawResult() override; - void finishedClustering(Cluster* root) override; + void finishedClustering(PhysicalHierarchy* tree) override; void setMaxLevel(int max_level) override; void setAreaPenalty(const Penalty& penalty) override; @@ -94,8 +94,10 @@ class Graphics : public gui::Renderer, public Mpl2Observer void eraseDrawing() override; private: + void setXMarksSizeAndPosition(const std::set& blocked_boundaries); void resetPenalties(); void drawCluster(Cluster* cluster, gui::Painter& painter); + void drawBlockedBoundariesIndication(gui::Painter& painter); void drawAllBlockages(gui::Painter& painter); void drawOffsetRect(const Rect& rect, const std::string& center_text, @@ -104,6 +106,20 @@ class Graphics : public gui::Renderer, public Mpl2Observer void drawGuides(gui::Painter& painter); template void drawBundledNets(gui::Painter& painter, const std::vector& macros); + template + void drawDistToIoConstraintBoundary(gui::Painter& painter, + const T& macro, + const T& io); + template + bool isOutsideTheOutline(const T& macro) const; + template + odb::Point getClosestBoundaryPoint(const T& macro, + const Rect& die, + Boundary closest_boundary); + template + Boundary getClosestUnblockedBoundary(const T& macro, const Rect& die); + bool isBlockedBoundary(Boundary boundary); + void addOutlineOffsetToLine(odb::Point& from, odb::Point& to); void setSoftMacroBrush(gui::Painter& painter, const SoftMacro& soft_macro); void fetchSoftAndHard(Cluster* parent, std::vector& hard, @@ -124,12 +140,16 @@ class Graphics : public gui::Renderer, public Mpl2Observer odb::Rect outline_; int target_cluster_id_{-1}; std::vector> outlines_; + std::map blocked_boundary_to_mark_; + // In Soft SA, we're shaping/placing the children of a certain parent, // so for this case, the current cluster is actually the current parent. Cluster* current_cluster_{nullptr}; std::map guides_; // Id -> Guidance Region std::map fences_; // Id -> Fence + int x_mark_size_{0}; // For blocked boundaries. + bool active_ = true; bool coarse_; bool fine_; diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 4a01c00eed5..71bdb1141b1 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -149,10 +149,6 @@ void HierRTLMP::setGuidanceRegions( } // Options related to clustering -void HierRTLMP::setNumBundledIOsPerBoundary(int num_bundled_ios) -{ - tree_->bundled_ios_per_edge = num_bundled_ios; -} void HierRTLMP::setClusterSize(int max_num_macro, int min_num_macro, @@ -236,7 +232,7 @@ void HierRTLMP::setReportDirectory(const char* report_directory) // b) Placement of Macros (one macro cluster at a time). // 5) Boundary Pushing // Push macro clusters to the boundaries of the design if they don't -// overlap with either bundled IOs' blockages or other macros. +// overlap with either pin access blockages or other macros. // 6) Orientation Improvement // Attempts macro flipping to improve WR. void HierRTLMP::run() @@ -306,7 +302,7 @@ void HierRTLMP::runMultilevelAutoclustering() } if (graphics_) { - graphics_->finishedClustering(tree_->root.get()); + graphics_->finishedClustering(tree_.get()); } } @@ -359,7 +355,7 @@ void HierRTLMP::runCoarseShaping() calculateChildrenTilings(tree_->root.get()); - setIOClustersBlockages(); + setPinAccessBlockages(); setPlacementBlockages(); } @@ -507,7 +503,7 @@ void HierRTLMP::calculateChildrenTilings(Cluster* parent) graphics_->setOutline(micronsToDbu(new_outline)); } std::unique_ptr sa - = std::make_unique(tree_->root.get(), + = std::make_unique(tree_.get(), new_outline, macros, 1.0, // area weight @@ -571,7 +567,7 @@ void HierRTLMP::calculateChildrenTilings(Cluster* parent) graphics_->setOutline(micronsToDbu(new_outline)); } std::unique_ptr sa - = std::make_unique(tree_->root.get(), + = std::make_unique(tree_.get(), new_outline, macros, 1.0, // area weight @@ -746,7 +742,8 @@ void HierRTLMP::calculateMacroTilings(Cluster* cluster) graphics_->setOutline(micronsToDbu(new_outline)); } std::unique_ptr sa - = std::make_unique(new_outline, + = std::make_unique(tree_.get(), + new_outline, macros, 1.0, // area_weight 1000.0, // outline weight @@ -804,7 +801,8 @@ void HierRTLMP::calculateMacroTilings(Cluster* cluster) graphics_->setOutline(micronsToDbu(new_outline)); } std::unique_ptr sa - = std::make_unique(new_outline, + = std::make_unique(tree_.get(), + new_outline, macros, 1.0, // area_weight 1000.0, // outline weight @@ -914,134 +912,107 @@ void HierRTLMP::setTightPackingTilings(Cluster* macro_array) macro_array->setMacroTilings(tight_packing_tilings); } -void HierRTLMP::setIOClustersBlockages() +void HierRTLMP::setPinAccessBlockages() { if (!tree_->maps.bterm_to_inst.empty()) { return; } - IOSpans io_spans = computeIOSpans(); - const float depth = computeIOBlockagesDepth(io_spans); - - const Rect root(tree_->root->getX(), - tree_->root->getY(), - tree_->root->getX() + tree_->root->getWidth(), - tree_->root->getY() + tree_->root->getHeight()); + std::vector io_clusters = getIOClusters(); + const Rect die = dbuToMicrons(block_->getDieArea()); - // Note that the range can be larger than the respective core dimension. - // As SA only sees what is inside its current outline, this is not a problem. - if (io_spans[L].second > io_spans[L].first) { - const Rect left_io_blockage(root.xMin(), - io_spans[L].first, - root.xMin() + depth, - io_spans[L].second); + const float depth = computePinAccessBlockagesDepth(io_clusters, die); - boundary_to_io_blockage_[L] = left_io_blockage; - macro_blockages_.push_back(left_io_blockage); + for (Cluster* io_cluster : io_clusters) { + Boundary constraint_boundary = io_cluster->getConstraintBoundary(); + if (constraint_boundary != NONE) { + createPinAccessBlockage(constraint_boundary, depth, die); + } } - if (io_spans[T].second > io_spans[T].first) { - const Rect top_io_blockage(io_spans[T].first, - root.yMax() - depth, - io_spans[T].second, - root.yMax()); - - boundary_to_io_blockage_[T] = top_io_blockage; - macro_blockages_.push_back(top_io_blockage); - } + if (boundary_to_io_blockage_.empty()) { + // If there are no constraints at all, give freedom to SA so it + // doesn't have to deal with pin access blockages in all boundaries. + // This will help SA not relying on extreme utilizations to + // converge for designs such as sky130hd/uW. + if (tree_->blocked_boundaries.empty()) { + return; + } - if (io_spans[R].second > io_spans[R].first) { - const Rect right_io_blockage(root.xMax() - depth, - io_spans[R].first, - root.xMax(), - io_spans[R].second); + // There are only -exclude constraints, so we create pin access + // blockages based on the boundaries that are not blocked. + if (tree_->blocked_boundaries.find(L) == tree_->blocked_boundaries.end()) { + createPinAccessBlockage(L, depth, die); + } - boundary_to_io_blockage_[R] = right_io_blockage; - macro_blockages_.push_back(right_io_blockage); - } + if (tree_->blocked_boundaries.find(R) == tree_->blocked_boundaries.end()) { + createPinAccessBlockage(R, depth, die); + } - if (io_spans[B].second > io_spans[B].first) { - const Rect bottom_io_blockage(io_spans[B].first, - root.yMin(), - io_spans[B].second, - root.yMin() + depth); + if (tree_->blocked_boundaries.find(B) == tree_->blocked_boundaries.end()) { + createPinAccessBlockage(B, depth, die); + } - boundary_to_io_blockage_[B] = bottom_io_blockage; - macro_blockages_.push_back(bottom_io_blockage); + if (tree_->blocked_boundaries.find(T) == tree_->blocked_boundaries.end()) { + createPinAccessBlockage(T, depth, die); + } } } -// Determine the range of IOs in each boundary of the die. -HierRTLMP::IOSpans HierRTLMP::computeIOSpans() +void HierRTLMP::createPinAccessBlockage(Boundary constraint_boundary, + const float depth, + const Rect& die) { - IOSpans io_spans; - - odb::Rect die = block_->getDieArea(); - - // Initialize spans based on the dimensions of the die area. - io_spans[L] - = {block_->dbuToMicrons(die.yMax()), block_->dbuToMicrons(die.yMin())}; - io_spans[T] - = {block_->dbuToMicrons(die.xMax()), block_->dbuToMicrons(die.xMin())}; - io_spans[R] = io_spans[L]; - io_spans[B] = io_spans[T]; - - for (auto term : block_->getBTerms()) { - if (term->getSigType().isSupply()) { - continue; - } - - int lx = std::numeric_limits::max(); - int ly = std::numeric_limits::max(); - int ux = 0; - int uy = 0; + Rect blockage = die; + if (constraint_boundary == L) { + blockage.setXMax(blockage.xMin() + depth); + } else if (constraint_boundary == T) { + blockage.setYMin(blockage.yMax() - depth); + } else if (constraint_boundary == R) { + blockage.setXMin(blockage.xMax() - depth); + } else { // Bottom + blockage.setYMax(blockage.yMin() + depth); + } + + boundary_to_io_blockage_[constraint_boundary] = blockage; + macro_blockages_.push_back(blockage); +} - for (const auto pin : term->getBPins()) { - for (const auto box : pin->getBoxes()) { - lx = std::min(lx, box->xMin()); - ly = std::min(ly, box->yMin()); - ux = std::max(ux, box->xMax()); - uy = std::max(uy, box->yMax()); - } - } +std::vector HierRTLMP::getIOClusters() +{ + std::vector io_clusters; - // Modify ranges based on the position of the IO pins. - if (lx <= die.xMin()) { - io_spans[L].first = std::min( - io_spans[L].first, static_cast(block_->dbuToMicrons(ly))); - io_spans[L].second = std::max( - io_spans[L].second, static_cast(block_->dbuToMicrons(uy))); - } else if (uy >= die.yMax()) { - io_spans[T].first = std::min( - io_spans[T].first, static_cast(block_->dbuToMicrons(lx))); - io_spans[T].second = std::max( - io_spans[T].second, static_cast(block_->dbuToMicrons(ux))); - } else if (ux >= die.xMax()) { - io_spans[R].first = std::min( - io_spans[R].first, static_cast(block_->dbuToMicrons(ly))); - io_spans[R].second = std::max( - io_spans[R].second, static_cast(block_->dbuToMicrons(uy))); - } else { - io_spans[B].first = std::min( - io_spans[B].first, static_cast(block_->dbuToMicrons(lx))); - io_spans[B].second = std::max( - io_spans[B].second, static_cast(block_->dbuToMicrons(ux))); + for (const auto& child : tree_->root->getChildren()) { + if (child->isIOCluster()) { + io_clusters.push_back(child.get()); } } - return io_spans; + return io_clusters; } -// The depth of IO clusters' blockages is generated based on: -// 1) How many vertical or horizontal boundaries have signal IO pins. -// 2) The total length of the io spans in all used boundaries. -float HierRTLMP::computeIOBlockagesDepth(const IOSpans& io_spans) +// The depth of pin access blockages is computed based on: +// 1) Amount of std cell area in the design. +// 2) Extension of the IO clusters across the design's boundaries. +float HierRTLMP::computePinAccessBlockagesDepth( + const std::vector& io_clusters, + const Rect& die) { - float sum_length = 0.0; + float io_clusters_extension = 0.0; + + for (Cluster* io_cluster : io_clusters) { + if (io_cluster->getConstraintBoundary() == NONE) { + const Rect die = io_cluster->getBBox(); + io_clusters_extension = die.getPerimeter(); + break; + } + + Boundary constraint_boundary = io_cluster->getConstraintBoundary(); - for (auto& [pin_access, length] : io_spans) { - if (length.second > length.first) { - sum_length += std::abs(length.second - length.first); + if (constraint_boundary == L || constraint_boundary == R) { + io_clusters_extension += die.getWidth(); + } else { // Bottom or Top + io_clusters_extension += die.getHeight(); } } @@ -1052,17 +1023,25 @@ float HierRTLMP::computeIOBlockagesDepth(const IOSpans& io_spans) } } + if (std_cell_area == 0.0) { + for (auto& cluster : tree_->root->getChildren()) { + if (cluster->getClusterType() == MixedCluster) { + std_cell_area += cluster->getArea(); + } + } + } + const float macro_dominance_factor = tree_->macro_with_halo_area / (tree_->root->getWidth() * tree_->root->getHeight()); - const float depth = (std_cell_area / sum_length) + const float depth = (std_cell_area / io_clusters_extension) * std::pow((1 - macro_dominance_factor), 2); debugPrint(logger_, MPL, "coarse_shaping", 1, - "Bundled IO clusters blokaged depth = {}", + "Pin access blockages depth = {}", depth); return depth; @@ -1210,7 +1189,7 @@ void HierRTLMP::runHierarchicalMacroPlacement(Cluster* parent) findOverlappingBlockages(macro_blockages, placement_blockages, outline); - // We store the bundled io clusters to push them into the macros' vector + // We store the io clusters to push them into the macros' vector // only after it is already populated with the clusters we're trying to // place. This will facilitate how we deal with fixed terminals in SA moves. std::vector io_clusters; @@ -1657,7 +1636,7 @@ void HierRTLMP::runHierarchicalMacroPlacement(Cluster* parent) // Note that the weight are not necessaries summarized to 1.0, i.e., not // normalized. std::unique_ptr sa - = std::make_unique(tree_->root.get(), + = std::make_unique(tree_.get(), outline, shaped_macros, area_weight_, @@ -1915,7 +1894,7 @@ void HierRTLMP::runHierarchicalMacroPlacement(Cluster* parent) // of 1.0. Note that the weight are not necessaries summarized to 1.0, // i.e., not normalized. std::unique_ptr sa = std::make_unique( - tree_->root.get(), + tree_.get(), outline, shaped_macros, area_weight_, @@ -2197,7 +2176,7 @@ void HierRTLMP::runHierarchicalMacroPlacementWithoutBusPlanning(Cluster* parent) findOverlappingBlockages(macro_blockages, placement_blockages, outline); - // We store the bundled io clusters to push them into the macros' vector + // We store the io clusters to push them into the macros' vector // only after it is already populated with the clusters we're trying to // place. This will facilitate how we deal with fixed terminals in SA moves. std::vector io_clusters; @@ -2289,7 +2268,10 @@ void HierRTLMP::runHierarchicalMacroPlacementWithoutBusPlanning(Cluster* parent) cluster->getName(), 0.0, 0.0, - nullptr); + // The information of whether or not a cluster is an IO cluster is + // needed inside the SA Core, so if a fixed terminal corresponds + // to an IO Cluster it needs to contains that cluster data. + cluster->isIOCluster() ? cluster.get() : nullptr); debugPrint( logger_, MPL, @@ -2489,7 +2471,7 @@ void HierRTLMP::runHierarchicalMacroPlacementWithoutBusPlanning(Cluster* parent) // Note that the weight are not necessaries summarized to 1.0, i.e., not // normalized. std::unique_ptr sa - = std::make_unique(tree_->root.get(), + = std::make_unique(tree_.get(), outline, shaped_macros, area_weight_, @@ -2698,7 +2680,7 @@ void HierRTLMP::runEnhancedHierarchicalMacroPlacement(Cluster* parent) findOverlappingBlockages(macro_blockages, placement_blockages, outline); - // We store the bundled io clusters to push them into the macros' vector + // We store the io clusters to push them into the macros' vector // only after it is already populated with the clusters we're trying to // place. This will facilitate how we deal with fixed terminals in SA moves. std::vector io_clusters; @@ -2790,7 +2772,10 @@ void HierRTLMP::runEnhancedHierarchicalMacroPlacement(Cluster* parent) cluster->getName(), 0.0, 0.0, - nullptr); + // The information of whether or not a cluster is an IO cluster is + // needed inside the SA Core, so if a fixed terminal corresponds + // to an IO Cluster it needs to contains that cluster data. + cluster->isIOCluster() ? cluster.get() : nullptr); debugPrint( logger_, MPL, @@ -2975,7 +2960,7 @@ void HierRTLMP::runEnhancedHierarchicalMacroPlacement(Cluster* parent) // Note that the weight are not necessaries summarized to 1.0, i.e., not // normalized. std::unique_ptr sa - = std::make_unique(tree_->root.get(), + = std::make_unique(tree_.get(), outline, shaped_macros, area_weight_, @@ -3471,6 +3456,7 @@ void HierRTLMP::placeMacros(Cluster* cluster) } std::unique_ptr sa = std::make_unique( + tree_.get(), outline, sa_macros, area_weight_, @@ -3651,7 +3637,11 @@ void HierRTLMP::createFixedTerminals(const Rect& outline, - outline.xMin(), temp_cluster->getY() + temp_cluster->getHeight() / 2.0 - outline.yMin()), - temp_cluster->getName()); + temp_cluster->getName(), + // The information of whether or not a cluster is an IO cluster is + // needed inside the SA Core, so if a fixed terminal corresponds + // to an IO Cluster it needs to contains that cluster data. + temp_cluster->isIOCluster() ? temp_cluster : nullptr); } } @@ -3956,14 +3946,114 @@ float HierRTLMP::calculateRealMacroWirelength(odb::dbInst* macro) odb::dbNet* net = iterm->getNet(); if (net != nullptr) { - const odb::Rect bbox = net->getTermBBox(); - wirelength += block_->dbuToMicrons(bbox.dx() + bbox.dy()); + // Mimic dbNet::getTermBBox() behavior, but considering + // the pin constraint region instead of its position. + odb::Rect net_box; + net_box.mergeInit(); + + for (odb::dbITerm* iterm : net->getITerms()) { + int x, y; + if (iterm->getAvgXY(&x, &y)) { + odb::Rect iterm_rect(x, y, x, y); + net_box.merge(iterm_rect); + } + } + + for (odb::dbBTerm* bterm : net->getBTerms()) { + auto constraint_region = bterm->getConstraintRegion(); + if (constraint_region) { + int x = constraint_region->xCenter(); + int y = constraint_region->yCenter(); + odb::Rect region_rect(x, y, x, y); + net_box.merge(region_rect); + } else { + odb::Point bterm_location(bterm->getBBox().xCenter(), + bterm->getBBox().yCenter()); + Boundary closest_boundary + = getClosestBoundary(bterm_location, tree_->unblocked_boundaries); + + // As we classify the blocked/unblocked state of the boundary based on + // the extension of the -exclude constraint, it's possible to have + // all boundaries blocked for IOs even though there are small + // unblocked spaces in those boundaries. For this situation, we just + // skip IOs without constraint regions. + if (closest_boundary == NONE) { + continue; + } + + odb::Point closest_point + = getClosestBoundaryPoint(bterm_location, closest_boundary); + odb::Rect closest_point_rect(closest_point, closest_point); + net_box.merge(closest_point_rect); + } + } + + wirelength += block_->dbuToMicrons(net_box.dx() + net_box.dy()); } } return wirelength; } +// Search the given boundaries list for the closest boundary to the point. +Boundary HierRTLMP::getClosestBoundary(const odb::Point& from, + const std::set& boundaries) +{ + Boundary closest_boundary = NONE; + int shortest_distance = std::numeric_limits::max(); + + for (const Boundary boundary : boundaries) { + const int dist_to_boundary = getDistanceToBoundary(from, boundary); + if (dist_to_boundary < shortest_distance) { + shortest_distance = dist_to_boundary; + closest_boundary = boundary; + } + } + + return closest_boundary; +} + +int HierRTLMP::getDistanceToBoundary(const odb::Point& from, + const Boundary boundary) +{ + int distance = 0; + + if (boundary == L) { + distance = from.x() - block_->getDieArea().xMin(); + } else if (boundary == R) { + distance = from.x() - block_->getDieArea().xMax(); + } else if (boundary == B) { + distance = from.y() - block_->getDieArea().yMin(); + } else if (boundary == T) { + distance = from.y() - block_->getDieArea().yMax(); + } + + return std::abs(distance); +} + +odb::Point HierRTLMP::getClosestBoundaryPoint(const odb::Point& from, + const Boundary boundary) +{ + odb::Point closest_boundary_point; + const odb::Rect& die = block_->getDieArea(); + + if (boundary == L) { + closest_boundary_point.setX(die.xMin()); + closest_boundary_point.setY(from.y()); + } else if (boundary == R) { + closest_boundary_point.setX(die.xMax()); + closest_boundary_point.setY(from.y()); + } else if (boundary == B) { + closest_boundary_point.setX(from.x()); + closest_boundary_point.setY(die.yMin()); + } else { // Top + closest_boundary_point.setX(from.x()); + closest_boundary_point.setY(die.yMax()); + } + + return closest_boundary_point; +} + void HierRTLMP::flipRealMacro(odb::dbInst* macro, const bool& is_vertical_flip) { if (is_vertical_flip) { @@ -4132,6 +4222,14 @@ odb::Rect HierRTLMP::micronsToDbu(const Rect& micron_rect) block_->micronsToDbu(micron_rect.yMax())); } +Rect HierRTLMP::dbuToMicrons(const odb::Rect& dbu_rect) +{ + return Rect(block_->dbuToMicrons(dbu_rect.xMin()), + block_->dbuToMicrons(dbu_rect.yMin()), + block_->dbuToMicrons(dbu_rect.xMax()), + block_->dbuToMicrons(dbu_rect.yMax())); +} + //////// Pusher //////// Pusher::Pusher(utl::Logger* logger, diff --git a/src/mpl2/src/hier_rtlmp.h b/src/mpl2/src/hier_rtlmp.h index 190db67731a..f1134fe543a 100644 --- a/src/mpl2/src/hier_rtlmp.h +++ b/src/mpl2/src/hier_rtlmp.h @@ -118,7 +118,6 @@ class HierRTLMP void setGuidanceRegions(const std::map& guidance_regions); // Clustering Related Options - void setNumBundledIOsPerBoundary(int num_bundled_ios); void setClusterSize(int max_num_macro, int min_num_macro, int max_num_inst, @@ -157,7 +156,6 @@ class HierRTLMP private: using SoftSAVector = std::vector>; using HardSAVector = std::vector>; - using IOSpans = std::map>; void runMultilevelAutoclustering(); void runHierarchicalMacroPlacement(); @@ -180,9 +178,13 @@ class HierRTLMP void calculateChildrenTilings(Cluster* parent); void calculateMacroTilings(Cluster* cluster); void setTightPackingTilings(Cluster* macro_array); - void setIOClustersBlockages(); - IOSpans computeIOSpans(); - float computeIOBlockagesDepth(const IOSpans& io_spans); + void setPinAccessBlockages(); + std::vector getIOClusters(); + float computePinAccessBlockagesDepth(const std::vector& io_clusters, + const Rect& die); + void createPinAccessBlockage(Boundary constraint_boundary, + float depth, + const Rect& die); void setPlacementBlockages(); // Fine Shaping @@ -238,6 +240,10 @@ class HierRTLMP void correctAllMacrosOrientation(); float calculateRealMacroWirelength(odb::dbInst* macro); + Boundary getClosestBoundary(const odb::Point& from, + const std::set& boundaries); + int getDistanceToBoundary(const odb::Point& from, Boundary boundary); + odb::Point getClosestBoundaryPoint(const odb::Point& from, Boundary boundary); void adjustRealMacroOrientation(const bool& is_vertical_flip); void flipRealMacro(odb::dbInst* macro, const bool& is_vertical_flip); @@ -248,6 +254,7 @@ class HierRTLMP // Aux for conversion odb::Rect micronsToDbu(const Rect& micron_rect); + Rect dbuToMicrons(const odb::Rect& dbu_rect); sta::dbNetwork* network_ = nullptr; odb::dbDatabase* db_ = nullptr; diff --git a/src/mpl2/src/mpl.i b/src/mpl2/src/mpl.i index 72bfc683e9f..8aea2d36632 100644 --- a/src/mpl2/src/mpl.i +++ b/src/mpl2/src/mpl.i @@ -63,7 +63,6 @@ bool rtl_macro_placer_cmd(const int max_num_macro, const float tolerance, const int max_num_level, const float coarsening_ratio, - const int num_bundled_ios, const int large_net_threshold, const int signature_net_threshold, const float halo_width, @@ -98,7 +97,6 @@ bool rtl_macro_placer_cmd(const int max_num_macro, tolerance, max_num_level, coarsening_ratio, - num_bundled_ios, large_net_threshold, signature_net_threshold, halo_width, diff --git a/src/mpl2/src/mpl.tcl b/src/mpl2/src/mpl.tcl index c5d66e79fdb..ec72bc3d5af 100644 --- a/src/mpl2/src/mpl.tcl +++ b/src/mpl2/src/mpl.tcl @@ -38,7 +38,6 @@ sta::define_cmd_args "rtl_macro_placer" { -max_num_macro max_num_macro \ -tolerance tolerance \ -max_num_level max_num_level \ -coarsening_ratio coarsening_ratio \ - -num_bundled_ios num_bundled_ios \ -large_net_threshold large_net_threshold \ -signature_net_threshold signature_net_threshold \ -halo_width halo_width \ @@ -67,7 +66,7 @@ sta::define_cmd_args "rtl_macro_placer" { -max_num_macro max_num_macro \ proc rtl_macro_placer { args } { sta::parse_key_args "rtl_macro_placer" args \ keys {-max_num_macro -min_num_macro -max_num_inst -min_num_inst -tolerance \ - -max_num_level -coarsening_ratio -num_bundled_ios -large_net_threshold \ + -max_num_level -coarsening_ratio -large_net_threshold \ -signature_net_threshold -halo_width -halo_height \ -fence_lx -fence_ly -fence_ux -fence_uy \ -area_weight -outline_weight -wirelength_weight -guidance_weight -fence_weight \ @@ -95,7 +94,6 @@ proc rtl_macro_placer { args } { set tolerance 0.1 set max_num_level 2 set coarsening_ratio 10.0 - set num_bundled_ios 3 set large_net_threshold 50 set signature_net_threshold 50 set halo_width 0.0 @@ -143,9 +141,6 @@ proc rtl_macro_placer { args } { if { [info exists keys(-coarsening_ratio)] } { set coarsening_ratio $keys(-coarsening_ratio) } - if { [info exists keys(-num_bundled_ios)] } { - set num_bundled_ios $keys(-num_bundled_ios) - } if { [info exists keys(-large_net_threshold)] } { set large_net_threshold $keys(-large_net_threshold) } @@ -233,7 +228,6 @@ proc rtl_macro_placer { args } { $tolerance \ $max_num_level \ $coarsening_ratio \ - $num_bundled_ios \ $large_net_threshold \ $signature_net_threshold \ $halo_width \ diff --git a/src/mpl2/src/object.cpp b/src/mpl2/src/object.cpp index f69490203ac..757392bddac 100644 --- a/src/mpl2/src/object.cpp +++ b/src/mpl2/src/object.cpp @@ -265,7 +265,7 @@ std::string Cluster::getClusterTypeString() const std::string cluster_type; if (is_io_cluster_) { - return "BundledIO"; + return "IO"; } switch (type_) { @@ -327,14 +327,13 @@ void Cluster::copyInstances(const Cluster& cluster) } } -// Bundled IO (Pads) cluster support -// The position is the center of IO pads in the cluster void Cluster::setAsIOCluster(const std::pair& pos, const float width, - const float height) + const float height, + const Boundary constraint_boundary) { is_io_cluster_ = true; - // Create a SoftMacro representing the IO cluster + constraint_boundary_ = constraint_boundary; soft_macro_ = std::make_unique(pos, name_, width, height, this); } @@ -791,7 +790,9 @@ void Cluster::addVirtualConnection(int src, int target) /////////////////////////////////////////////////////////////////////// // HardMacro -HardMacro::HardMacro(std::pair loc, const std::string& name) +HardMacro::HardMacro(std::pair loc, + const std::string& name, + Cluster* cluster) { width_ = 0.0; height_ = 0.0; @@ -800,6 +801,7 @@ HardMacro::HardMacro(std::pair loc, const std::string& name) pin_y_ = 0.0; x_ = loc.first; y_ = loc.second; + cluster_ = cluster; } HardMacro::HardMacro(float width, float height, const std::string& name) @@ -862,6 +864,17 @@ bool HardMacro::operator==(const HardMacro& macro) const return (width_ == macro.width_) && (height_ == macro.height_); } +// Cluster support to identify if a fixed terminal correponds +// to an IO cluster when running HardMacro SA. +bool HardMacro::isIOCluster() const +{ + if (!cluster_) { + return false; + } + + return cluster_->isIOCluster(); +} + // Get Physical Information // Note that the default X and Y include halo_width void HardMacro::setLocation(const std::pair& location) @@ -1338,6 +1351,15 @@ bool SoftMacro::isMixedCluster() const return (cluster_->getClusterType() == MixedCluster); } +bool SoftMacro::isIOCluster() const +{ + if (!cluster_) { + return false; + } + + return cluster_->isIOCluster(); +} + void SoftMacro::setLocationF(float x, float y) { x_ = x; diff --git a/src/mpl2/src/object.h b/src/mpl2/src/object.h index 1dfb9f953db..6c907cb9d9b 100644 --- a/src/mpl2/src/object.h +++ b/src/mpl2/src/object.h @@ -202,8 +202,11 @@ class Cluster // Position must be specified when setting an IO cluster void setAsIOCluster(const std::pair& pos, float width, - float height); + float height, + Boundary constraint_boundary); bool isIOCluster() const; + Boundary getConstraintBoundary() const { return constraint_boundary_; } + void setAsArrayOfInterconnectedMacros(); bool isArrayOfInterconnectedMacros() const; bool isEmpty() const; @@ -297,9 +300,11 @@ class Cluster // all the macros in the cluster std::vector hard_macros_; - // We model bundled IOS (Pads) as a cluster with no area + // We model pads as clusters with no area // The position be the center of IOs bool is_io_cluster_ = false; + Boundary constraint_boundary_ = NONE; + bool is_array_of_interconnected_macros = false; // Each cluster uses metrics to store its statistics @@ -343,7 +348,9 @@ class HardMacro public: // Create a macro with specified size // Model fixed terminals - HardMacro(std::pair loc, const std::string& name); + HardMacro(std::pair loc, + const std::string& name, + Cluster* cluster = nullptr); // In this case, we model the pin position at the center of the macro HardMacro(float width, float height, const std::string& name); @@ -356,6 +363,10 @@ class HardMacro bool operator<(const HardMacro& macro) const; bool operator==(const HardMacro& macro) const; + void setCluster(Cluster* cluster) { cluster_ = cluster; } + Cluster* getCluster() const { return cluster_; } + bool isIOCluster() const; + // Get Physical Information // Note that the default X and Y include halo_width void setLocation(const std::pair& location); @@ -444,6 +455,8 @@ class HardMacro odb::dbInst* inst_ = nullptr; odb::dbBlock* block_ = nullptr; + + Cluster* cluster_ = nullptr; }; // We have three types of SoftMacros @@ -526,6 +539,7 @@ class SoftMacro bool isMacroCluster() const; bool isStdCellCluster() const; bool isMixedCluster() const; + bool isIOCluster() const; void setLocationF(float x, float y); void setShapeF(float width, float height); int getNumMacro() const; @@ -628,12 +642,18 @@ struct Rect float xMax() const { return ux; } float yMax() const { return uy; } + void setXMin(float lx) { this->lx = lx; } + void setYMin(float ly) { this->ly = ly; } + void setXMax(float ux) { this->ux = ux; } + void setYMax(float uy) { this->uy = uy; } + float getX() const { return (lx + ux) / 2.0; } float getY() const { return (ly + uy) / 2.0; } float getWidth() const { return ux - lx; } float getHeight() const { return uy - ly; } + float getPerimeter() const { return 2 * getWidth() + 2 * getHeight(); } float getArea() const { return getWidth() * getHeight(); } void setLoc(float x, diff --git a/src/mpl2/src/rtl_mp.cpp b/src/mpl2/src/rtl_mp.cpp index 8f74cf611e6..a0492f23bdb 100644 --- a/src/mpl2/src/rtl_mp.cpp +++ b/src/mpl2/src/rtl_mp.cpp @@ -67,7 +67,6 @@ bool MacroPlacer2::place(const int num_threads, const float tolerance, const int max_num_level, const float coarsening_ratio, - const int num_bundled_ios, const int large_net_threshold, const int signature_net_threshold, const float halo_width, @@ -97,7 +96,6 @@ bool MacroPlacer2::place(const int num_threads, hier_rtlmp_->setClusterSizeTolerance(tolerance); hier_rtlmp_->setMaxNumLevel(max_num_level); hier_rtlmp_->setClusterSizeRatioPerLevel(coarsening_ratio); - hier_rtlmp_->setNumBundledIOsPerBoundary(num_bundled_ios); hier_rtlmp_->setLargeNetThreshold(large_net_threshold); hier_rtlmp_->setSignatureNetThreshold(signature_net_threshold); hier_rtlmp_->setHaloWidth(halo_width); diff --git a/src/mpl2/test/CMakeLists.txt b/src/mpl2/test/CMakeLists.txt index 9d814fc8f48..84d7e97c973 100644 --- a/src/mpl2/test/CMakeLists.txt +++ b/src/mpl2/test/CMakeLists.txt @@ -5,6 +5,8 @@ or_integration_tests( no_unfixed_macros guides1 guides2 + io_constraints1 + io_constraints2 ) # Skipped diff --git a/src/mpl2/test/io_constraints1.defok b/src/mpl2/test/io_constraints1.defok new file mode 100644 index 00000000000..1cd34ff791b --- /dev/null +++ b/src/mpl2/test/io_constraints1.defok @@ -0,0 +1,538 @@ +VERSION 5.8 ; +DIVIDERCHAR "/" ; +BUSBITCHARS "[]" ; +DESIGN io_constraints1 ; +UNITS DISTANCE MICRONS 2000 ; +DIEAREA ( 0 0 ) ( 300000 250000 ) ; +ROW ROW_0 FreePDK45_38x28_10R_NP_162NW_34O 0 0 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_1 FreePDK45_38x28_10R_NP_162NW_34O 0 2800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_2 FreePDK45_38x28_10R_NP_162NW_34O 0 5600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_3 FreePDK45_38x28_10R_NP_162NW_34O 0 8400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_4 FreePDK45_38x28_10R_NP_162NW_34O 0 11200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_5 FreePDK45_38x28_10R_NP_162NW_34O 0 14000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_6 FreePDK45_38x28_10R_NP_162NW_34O 0 16800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_7 FreePDK45_38x28_10R_NP_162NW_34O 0 19600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_8 FreePDK45_38x28_10R_NP_162NW_34O 0 22400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_9 FreePDK45_38x28_10R_NP_162NW_34O 0 25200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_10 FreePDK45_38x28_10R_NP_162NW_34O 0 28000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_11 FreePDK45_38x28_10R_NP_162NW_34O 0 30800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_12 FreePDK45_38x28_10R_NP_162NW_34O 0 33600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_13 FreePDK45_38x28_10R_NP_162NW_34O 0 36400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_14 FreePDK45_38x28_10R_NP_162NW_34O 0 39200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_15 FreePDK45_38x28_10R_NP_162NW_34O 0 42000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_16 FreePDK45_38x28_10R_NP_162NW_34O 0 44800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_17 FreePDK45_38x28_10R_NP_162NW_34O 0 47600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_18 FreePDK45_38x28_10R_NP_162NW_34O 0 50400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_19 FreePDK45_38x28_10R_NP_162NW_34O 0 53200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_20 FreePDK45_38x28_10R_NP_162NW_34O 0 56000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_21 FreePDK45_38x28_10R_NP_162NW_34O 0 58800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_22 FreePDK45_38x28_10R_NP_162NW_34O 0 61600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_23 FreePDK45_38x28_10R_NP_162NW_34O 0 64400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_24 FreePDK45_38x28_10R_NP_162NW_34O 0 67200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_25 FreePDK45_38x28_10R_NP_162NW_34O 0 70000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_26 FreePDK45_38x28_10R_NP_162NW_34O 0 72800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_27 FreePDK45_38x28_10R_NP_162NW_34O 0 75600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_28 FreePDK45_38x28_10R_NP_162NW_34O 0 78400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_29 FreePDK45_38x28_10R_NP_162NW_34O 0 81200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_30 FreePDK45_38x28_10R_NP_162NW_34O 0 84000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_31 FreePDK45_38x28_10R_NP_162NW_34O 0 86800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_32 FreePDK45_38x28_10R_NP_162NW_34O 0 89600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_33 FreePDK45_38x28_10R_NP_162NW_34O 0 92400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_34 FreePDK45_38x28_10R_NP_162NW_34O 0 95200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_35 FreePDK45_38x28_10R_NP_162NW_34O 0 98000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_36 FreePDK45_38x28_10R_NP_162NW_34O 0 100800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_37 FreePDK45_38x28_10R_NP_162NW_34O 0 103600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_38 FreePDK45_38x28_10R_NP_162NW_34O 0 106400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_39 FreePDK45_38x28_10R_NP_162NW_34O 0 109200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_40 FreePDK45_38x28_10R_NP_162NW_34O 0 112000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_41 FreePDK45_38x28_10R_NP_162NW_34O 0 114800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_42 FreePDK45_38x28_10R_NP_162NW_34O 0 117600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_43 FreePDK45_38x28_10R_NP_162NW_34O 0 120400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_44 FreePDK45_38x28_10R_NP_162NW_34O 0 123200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_45 FreePDK45_38x28_10R_NP_162NW_34O 0 126000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_46 FreePDK45_38x28_10R_NP_162NW_34O 0 128800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_47 FreePDK45_38x28_10R_NP_162NW_34O 0 131600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_48 FreePDK45_38x28_10R_NP_162NW_34O 0 134400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_49 FreePDK45_38x28_10R_NP_162NW_34O 0 137200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_50 FreePDK45_38x28_10R_NP_162NW_34O 0 140000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_51 FreePDK45_38x28_10R_NP_162NW_34O 0 142800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_52 FreePDK45_38x28_10R_NP_162NW_34O 0 145600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_53 FreePDK45_38x28_10R_NP_162NW_34O 0 148400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_54 FreePDK45_38x28_10R_NP_162NW_34O 0 151200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_55 FreePDK45_38x28_10R_NP_162NW_34O 0 154000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_56 FreePDK45_38x28_10R_NP_162NW_34O 0 156800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_57 FreePDK45_38x28_10R_NP_162NW_34O 0 159600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_58 FreePDK45_38x28_10R_NP_162NW_34O 0 162400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_59 FreePDK45_38x28_10R_NP_162NW_34O 0 165200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_60 FreePDK45_38x28_10R_NP_162NW_34O 0 168000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_61 FreePDK45_38x28_10R_NP_162NW_34O 0 170800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_62 FreePDK45_38x28_10R_NP_162NW_34O 0 173600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_63 FreePDK45_38x28_10R_NP_162NW_34O 0 176400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_64 FreePDK45_38x28_10R_NP_162NW_34O 0 179200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_65 FreePDK45_38x28_10R_NP_162NW_34O 0 182000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_66 FreePDK45_38x28_10R_NP_162NW_34O 0 184800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_67 FreePDK45_38x28_10R_NP_162NW_34O 0 187600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_68 FreePDK45_38x28_10R_NP_162NW_34O 0 190400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_69 FreePDK45_38x28_10R_NP_162NW_34O 0 193200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_70 FreePDK45_38x28_10R_NP_162NW_34O 0 196000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_71 FreePDK45_38x28_10R_NP_162NW_34O 0 198800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_72 FreePDK45_38x28_10R_NP_162NW_34O 0 201600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_73 FreePDK45_38x28_10R_NP_162NW_34O 0 204400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_74 FreePDK45_38x28_10R_NP_162NW_34O 0 207200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_75 FreePDK45_38x28_10R_NP_162NW_34O 0 210000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_76 FreePDK45_38x28_10R_NP_162NW_34O 0 212800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_77 FreePDK45_38x28_10R_NP_162NW_34O 0 215600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_78 FreePDK45_38x28_10R_NP_162NW_34O 0 218400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_79 FreePDK45_38x28_10R_NP_162NW_34O 0 221200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_80 FreePDK45_38x28_10R_NP_162NW_34O 0 224000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_81 FreePDK45_38x28_10R_NP_162NW_34O 0 226800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_82 FreePDK45_38x28_10R_NP_162NW_34O 0 229600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_83 FreePDK45_38x28_10R_NP_162NW_34O 0 232400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_84 FreePDK45_38x28_10R_NP_162NW_34O 0 235200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_85 FreePDK45_38x28_10R_NP_162NW_34O 0 238000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_86 FreePDK45_38x28_10R_NP_162NW_34O 0 240800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_87 FreePDK45_38x28_10R_NP_162NW_34O 0 243600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_88 FreePDK45_38x28_10R_NP_162NW_34O 0 246400 N DO 789 BY 1 STEP 380 0 ; +TRACKS X 190 DO 2368 STEP 380 LAYER metal1 ; +TRACKS Y 140 DO 3214 STEP 280 LAYER metal1 ; +TRACKS X 190 DO 2368 STEP 380 LAYER metal2 ; +TRACKS Y 140 DO 3214 STEP 280 LAYER metal2 ; +TRACKS X 190 DO 2368 STEP 380 LAYER metal3 ; +TRACKS Y 140 DO 3214 STEP 280 LAYER metal3 ; +TRACKS X 190 DO 1607 STEP 560 LAYER metal4 ; +TRACKS Y 140 DO 1607 STEP 560 LAYER metal4 ; +TRACKS X 190 DO 1607 STEP 560 LAYER metal5 ; +TRACKS Y 140 DO 1607 STEP 560 LAYER metal5 ; +TRACKS X 190 DO 1607 STEP 560 LAYER metal6 ; +TRACKS Y 140 DO 1607 STEP 560 LAYER metal6 ; +TRACKS X 190 DO 563 STEP 1600 LAYER metal7 ; +TRACKS Y 140 DO 563 STEP 1600 LAYER metal7 ; +TRACKS X 190 DO 563 STEP 1600 LAYER metal8 ; +TRACKS Y 140 DO 563 STEP 1600 LAYER metal8 ; +TRACKS X 190 DO 282 STEP 3200 LAYER metal9 ; +TRACKS Y 140 DO 282 STEP 3200 LAYER metal9 ; +TRACKS X 190 DO 282 STEP 3200 LAYER metal10 ; +TRACKS Y 140 DO 282 STEP 3200 LAYER metal10 ; +COMPONENTS 401 ; + - MACRO_1 HM_100x100_1x1 + FIXED ( 91820 8010 ) S ; + - _001_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _002_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _003_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _004_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _005_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _006_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _007_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _008_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _009_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _010_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _011_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _012_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _013_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _014_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _015_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _016_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _017_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _018_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _019_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _020_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _021_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _022_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _023_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _024_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _025_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _026_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _027_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _028_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _029_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _030_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _031_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _032_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _033_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _034_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _035_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _036_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _037_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _038_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _039_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _040_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _041_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _042_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _043_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _044_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _045_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _046_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _047_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _048_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _049_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _050_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _051_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _052_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _053_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _054_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _055_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _056_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _057_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _058_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _059_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _060_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _061_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _062_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _063_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _064_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _065_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _066_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _067_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _068_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _069_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _070_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _071_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _072_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _073_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _074_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _075_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _076_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _077_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _078_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _079_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _080_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _081_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _082_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _083_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _084_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _085_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _086_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _087_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _088_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _089_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _090_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _091_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _092_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _093_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _094_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _095_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _096_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _097_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _098_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _099_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _100_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _101_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _102_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _103_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _104_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _105_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _106_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _107_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _108_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _109_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _110_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _111_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _112_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _113_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _114_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _115_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _116_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _117_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _118_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _119_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _120_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _121_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _122_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _123_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _124_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _125_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _126_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _127_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _128_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _129_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _130_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _131_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _132_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _133_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _134_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _135_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _136_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _137_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _138_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _139_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _140_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _141_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _142_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _143_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _144_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _145_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _146_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _147_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _148_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _149_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _150_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _151_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _152_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _153_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _154_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _155_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _156_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _157_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _158_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _159_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _160_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _161_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _162_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _163_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _164_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _165_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _166_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _167_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _168_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _169_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _170_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _171_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _172_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _173_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _174_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _175_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _176_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _177_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _178_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _179_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _180_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _181_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _182_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _183_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _184_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _185_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _186_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _187_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _188_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _189_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _190_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _191_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _192_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _193_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _194_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _195_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _196_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _197_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _198_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _199_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _200_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _201_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _202_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _203_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _204_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _205_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _206_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _207_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _208_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _209_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _210_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _211_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _212_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _213_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _214_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _215_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _216_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _217_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _218_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _219_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _220_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _221_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _222_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _223_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _224_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _225_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _226_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _227_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _228_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _229_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _230_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _231_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _232_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _233_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _234_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _235_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _236_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _237_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _238_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _239_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _240_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _241_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _242_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _243_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _244_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _245_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _246_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _247_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _248_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _249_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _250_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _251_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _252_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _253_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _254_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _255_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _256_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _257_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _258_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _259_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _260_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _261_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _262_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _263_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _264_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _265_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _266_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _267_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _268_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _269_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _270_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _271_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _272_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _273_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _274_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _275_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _276_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _277_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _278_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _279_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _280_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _281_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _282_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _283_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _284_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _285_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _286_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _287_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _288_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _289_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _290_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _291_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _292_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _293_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _294_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _295_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _296_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _297_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _298_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _299_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _300_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _301_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _302_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _303_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _304_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _305_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _306_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _307_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _308_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _309_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _310_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _311_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _312_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _313_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _314_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _315_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _316_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _317_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _318_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _319_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _320_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _321_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _322_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _323_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _324_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _325_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _326_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _327_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _328_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _329_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _330_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _331_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _332_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _333_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _334_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _335_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _336_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _337_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _338_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _339_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _340_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _341_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _342_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _343_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _344_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _345_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _346_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _347_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _348_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _349_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _350_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _351_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _352_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _353_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _354_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _355_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _356_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _357_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _358_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _359_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _360_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _361_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _362_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _363_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _364_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _365_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _366_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _367_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _368_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _369_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _370_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _371_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _372_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _373_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _374_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _375_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _376_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _377_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _378_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _379_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _380_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _381_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _382_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _383_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _384_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _385_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _386_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _387_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _388_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _389_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _390_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _391_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _392_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _393_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _394_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _395_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _396_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _397_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _398_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _399_ DFF_X1 + PLACED ( 38680 123234 ) N ; + - _400_ DFF_X1 + PLACED ( 38680 123234 ) N ; +END COMPONENTS +PINS 3 ; + - io_1 + NET io_1 + DIRECTION INPUT + USE SIGNAL + + PORT + + LAYER metal5 ( -140 -140 ) ( 140 140 ) + + PLACED ( 140 155820 ) N ; + - io_2 + NET io_2 + DIRECTION INPUT + USE SIGNAL + + PORT + + LAYER metal5 ( -140 -140 ) ( 140 140 ) + + PLACED ( 140 50540 ) N ; + - io_3 + NET io_3 + DIRECTION INPUT + USE SIGNAL + + PORT + + LAYER metal5 ( -140 -140 ) ( 140 140 ) + + PLACED ( 140 12460 ) N ; +END PINS +NETS 3 ; + - io_1 ( PIN io_1 ) + USE SIGNAL ; + - io_2 ( PIN io_2 ) + USE SIGNAL ; + - io_3 ( PIN io_3 ) + USE SIGNAL ; +END NETS +END DESIGN diff --git a/src/mpl2/test/io_constraints1.ok b/src/mpl2/test/io_constraints1.ok new file mode 100644 index 00000000000..a58caca5939 --- /dev/null +++ b/src/mpl2/test/io_constraints1.ok @@ -0,0 +1,31 @@ +[INFO ODB-0227] LEF file: ./Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells +[INFO ODB-0227] LEF file: ./testcases/macro_only.lef, created 9 library cells +[WARNING STA-1171] ./testcases/macro_only.lib line 32, default_max_transition is 0.0. +[WARNING ORD-2011] LEF master DFF_X1 has no liberty cell. +[INFO ODB-0128] Design: io_constraints1 +[INFO ODB-0252] Updated 3 pins. +[INFO ODB-0253] Updated 401 components. +[INFO PPL-0067] Restrict INPUT pins to region 0u-125u, in the LEFT edge. +Found 1 macro blocks. +Using 2 tracks default min distance between IO pins. +[INFO PPL-0001] Number of slots 974 +[INFO PPL-0002] Number of I/O 3 +[INFO PPL-0003] Number of I/O w/sink 0 +[INFO PPL-0004] Number of I/O w/o sink 3 +[INFO PPL-0012] I/O nets HPWL: 0.00 um. +Die Area: (0, 0) (150, 125), Floorplan Area: (0, 0) (149.91, 124.6) + Number of std cell instances: 400 + Area of std cell instances: 1808.79 + Number of macros: 1 + Area of macros: 10000.00 + Halo width: 4.00 + Halo height: 4.00 + Area of macros with halos: 11664.00 + Area of std cell instances + Area of macros: 11808.79 + Floorplan area: 18678.79 + Design Utilization: 0.63 + Floorplan Utilization: 0.21 + Manufacturing Grid: 10 + +[WARNING MPL-0014] No Liberty data found for std cells. Continuing without dataflow. +No differences found. diff --git a/src/mpl2/test/io_constraints1.tcl b/src/mpl2/test/io_constraints1.tcl new file mode 100644 index 00000000000..b5f31c91ba0 --- /dev/null +++ b/src/mpl2/test/io_constraints1.tcl @@ -0,0 +1,25 @@ +# Test if pin access blockage is generated correctly for a case +# with pins in a single boundary. +source "helpers.tcl" + +# We're not interested in the connections, so don't include the lib. +read_lef "./Nangate45/Nangate45.lef" + +read_lef "./testcases/macro_only.lef" +read_liberty "./testcases/macro_only.lib" + +read_verilog "./testcases/io_constraints1.v" +link_design "io_constraints1" +read_def "./testcases/io_constraints1.def" -floorplan_initialize + +# Run random PPL to incorporate the constraints into ODB +set_io_pin_constraint -direction INPUT -region left:* +place_pins -annealing -random -hor_layers metal5 -ver_layer metal6 + +set_thread_count 0 +rtl_macro_placer -report_directory results/io_constraints1 -halo_width 4.0 + +set def_file [make_result_file io_constraints1.def] +write_def $def_file + +diff_files io_constraints1.defok $def_file \ No newline at end of file diff --git a/src/mpl2/test/io_constraints2.defok b/src/mpl2/test/io_constraints2.defok new file mode 100644 index 00000000000..6b4473039f2 --- /dev/null +++ b/src/mpl2/test/io_constraints2.defok @@ -0,0 +1,538 @@ +VERSION 5.8 ; +DIVIDERCHAR "/" ; +BUSBITCHARS "[]" ; +DESIGN io_constraints1 ; +UNITS DISTANCE MICRONS 2000 ; +DIEAREA ( 0 0 ) ( 300000 250000 ) ; +ROW ROW_0 FreePDK45_38x28_10R_NP_162NW_34O 0 0 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_1 FreePDK45_38x28_10R_NP_162NW_34O 0 2800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_2 FreePDK45_38x28_10R_NP_162NW_34O 0 5600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_3 FreePDK45_38x28_10R_NP_162NW_34O 0 8400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_4 FreePDK45_38x28_10R_NP_162NW_34O 0 11200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_5 FreePDK45_38x28_10R_NP_162NW_34O 0 14000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_6 FreePDK45_38x28_10R_NP_162NW_34O 0 16800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_7 FreePDK45_38x28_10R_NP_162NW_34O 0 19600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_8 FreePDK45_38x28_10R_NP_162NW_34O 0 22400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_9 FreePDK45_38x28_10R_NP_162NW_34O 0 25200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_10 FreePDK45_38x28_10R_NP_162NW_34O 0 28000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_11 FreePDK45_38x28_10R_NP_162NW_34O 0 30800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_12 FreePDK45_38x28_10R_NP_162NW_34O 0 33600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_13 FreePDK45_38x28_10R_NP_162NW_34O 0 36400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_14 FreePDK45_38x28_10R_NP_162NW_34O 0 39200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_15 FreePDK45_38x28_10R_NP_162NW_34O 0 42000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_16 FreePDK45_38x28_10R_NP_162NW_34O 0 44800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_17 FreePDK45_38x28_10R_NP_162NW_34O 0 47600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_18 FreePDK45_38x28_10R_NP_162NW_34O 0 50400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_19 FreePDK45_38x28_10R_NP_162NW_34O 0 53200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_20 FreePDK45_38x28_10R_NP_162NW_34O 0 56000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_21 FreePDK45_38x28_10R_NP_162NW_34O 0 58800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_22 FreePDK45_38x28_10R_NP_162NW_34O 0 61600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_23 FreePDK45_38x28_10R_NP_162NW_34O 0 64400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_24 FreePDK45_38x28_10R_NP_162NW_34O 0 67200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_25 FreePDK45_38x28_10R_NP_162NW_34O 0 70000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_26 FreePDK45_38x28_10R_NP_162NW_34O 0 72800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_27 FreePDK45_38x28_10R_NP_162NW_34O 0 75600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_28 FreePDK45_38x28_10R_NP_162NW_34O 0 78400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_29 FreePDK45_38x28_10R_NP_162NW_34O 0 81200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_30 FreePDK45_38x28_10R_NP_162NW_34O 0 84000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_31 FreePDK45_38x28_10R_NP_162NW_34O 0 86800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_32 FreePDK45_38x28_10R_NP_162NW_34O 0 89600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_33 FreePDK45_38x28_10R_NP_162NW_34O 0 92400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_34 FreePDK45_38x28_10R_NP_162NW_34O 0 95200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_35 FreePDK45_38x28_10R_NP_162NW_34O 0 98000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_36 FreePDK45_38x28_10R_NP_162NW_34O 0 100800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_37 FreePDK45_38x28_10R_NP_162NW_34O 0 103600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_38 FreePDK45_38x28_10R_NP_162NW_34O 0 106400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_39 FreePDK45_38x28_10R_NP_162NW_34O 0 109200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_40 FreePDK45_38x28_10R_NP_162NW_34O 0 112000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_41 FreePDK45_38x28_10R_NP_162NW_34O 0 114800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_42 FreePDK45_38x28_10R_NP_162NW_34O 0 117600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_43 FreePDK45_38x28_10R_NP_162NW_34O 0 120400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_44 FreePDK45_38x28_10R_NP_162NW_34O 0 123200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_45 FreePDK45_38x28_10R_NP_162NW_34O 0 126000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_46 FreePDK45_38x28_10R_NP_162NW_34O 0 128800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_47 FreePDK45_38x28_10R_NP_162NW_34O 0 131600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_48 FreePDK45_38x28_10R_NP_162NW_34O 0 134400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_49 FreePDK45_38x28_10R_NP_162NW_34O 0 137200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_50 FreePDK45_38x28_10R_NP_162NW_34O 0 140000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_51 FreePDK45_38x28_10R_NP_162NW_34O 0 142800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_52 FreePDK45_38x28_10R_NP_162NW_34O 0 145600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_53 FreePDK45_38x28_10R_NP_162NW_34O 0 148400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_54 FreePDK45_38x28_10R_NP_162NW_34O 0 151200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_55 FreePDK45_38x28_10R_NP_162NW_34O 0 154000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_56 FreePDK45_38x28_10R_NP_162NW_34O 0 156800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_57 FreePDK45_38x28_10R_NP_162NW_34O 0 159600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_58 FreePDK45_38x28_10R_NP_162NW_34O 0 162400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_59 FreePDK45_38x28_10R_NP_162NW_34O 0 165200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_60 FreePDK45_38x28_10R_NP_162NW_34O 0 168000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_61 FreePDK45_38x28_10R_NP_162NW_34O 0 170800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_62 FreePDK45_38x28_10R_NP_162NW_34O 0 173600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_63 FreePDK45_38x28_10R_NP_162NW_34O 0 176400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_64 FreePDK45_38x28_10R_NP_162NW_34O 0 179200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_65 FreePDK45_38x28_10R_NP_162NW_34O 0 182000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_66 FreePDK45_38x28_10R_NP_162NW_34O 0 184800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_67 FreePDK45_38x28_10R_NP_162NW_34O 0 187600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_68 FreePDK45_38x28_10R_NP_162NW_34O 0 190400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_69 FreePDK45_38x28_10R_NP_162NW_34O 0 193200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_70 FreePDK45_38x28_10R_NP_162NW_34O 0 196000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_71 FreePDK45_38x28_10R_NP_162NW_34O 0 198800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_72 FreePDK45_38x28_10R_NP_162NW_34O 0 201600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_73 FreePDK45_38x28_10R_NP_162NW_34O 0 204400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_74 FreePDK45_38x28_10R_NP_162NW_34O 0 207200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_75 FreePDK45_38x28_10R_NP_162NW_34O 0 210000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_76 FreePDK45_38x28_10R_NP_162NW_34O 0 212800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_77 FreePDK45_38x28_10R_NP_162NW_34O 0 215600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_78 FreePDK45_38x28_10R_NP_162NW_34O 0 218400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_79 FreePDK45_38x28_10R_NP_162NW_34O 0 221200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_80 FreePDK45_38x28_10R_NP_162NW_34O 0 224000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_81 FreePDK45_38x28_10R_NP_162NW_34O 0 226800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_82 FreePDK45_38x28_10R_NP_162NW_34O 0 229600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_83 FreePDK45_38x28_10R_NP_162NW_34O 0 232400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_84 FreePDK45_38x28_10R_NP_162NW_34O 0 235200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_85 FreePDK45_38x28_10R_NP_162NW_34O 0 238000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_86 FreePDK45_38x28_10R_NP_162NW_34O 0 240800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_87 FreePDK45_38x28_10R_NP_162NW_34O 0 243600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_88 FreePDK45_38x28_10R_NP_162NW_34O 0 246400 N DO 789 BY 1 STEP 380 0 ; +TRACKS X 190 DO 2368 STEP 380 LAYER metal1 ; +TRACKS Y 140 DO 3214 STEP 280 LAYER metal1 ; +TRACKS X 190 DO 2368 STEP 380 LAYER metal2 ; +TRACKS Y 140 DO 3214 STEP 280 LAYER metal2 ; +TRACKS X 190 DO 2368 STEP 380 LAYER metal3 ; +TRACKS Y 140 DO 3214 STEP 280 LAYER metal3 ; +TRACKS X 190 DO 1607 STEP 560 LAYER metal4 ; +TRACKS Y 140 DO 1607 STEP 560 LAYER metal4 ; +TRACKS X 190 DO 1607 STEP 560 LAYER metal5 ; +TRACKS Y 140 DO 1607 STEP 560 LAYER metal5 ; +TRACKS X 190 DO 1607 STEP 560 LAYER metal6 ; +TRACKS Y 140 DO 1607 STEP 560 LAYER metal6 ; +TRACKS X 190 DO 563 STEP 1600 LAYER metal7 ; +TRACKS Y 140 DO 563 STEP 1600 LAYER metal7 ; +TRACKS X 190 DO 563 STEP 1600 LAYER metal8 ; +TRACKS Y 140 DO 563 STEP 1600 LAYER metal8 ; +TRACKS X 190 DO 282 STEP 3200 LAYER metal9 ; +TRACKS Y 140 DO 282 STEP 3200 LAYER metal9 ; +TRACKS X 190 DO 282 STEP 3200 LAYER metal10 ; +TRACKS Y 140 DO 282 STEP 3200 LAYER metal10 ; +COMPONENTS 401 ; + - MACRO_1 HM_100x100_1x1 + FIXED ( 8000 41330 ) S ; + - _001_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _002_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _003_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _004_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _005_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _006_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _007_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _008_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _009_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _010_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _011_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _012_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _013_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _014_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _015_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _016_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _017_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _018_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _019_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _020_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _021_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _022_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _023_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _024_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _025_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _026_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _027_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _028_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _029_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _030_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _031_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _032_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _033_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _034_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _035_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _036_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _037_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _038_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _039_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _040_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _041_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _042_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _043_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _044_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _045_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _046_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _047_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _048_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _049_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _050_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _051_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _052_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _053_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _054_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _055_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _056_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _057_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _058_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _059_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _060_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _061_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _062_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _063_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _064_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _065_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _066_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _067_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _068_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _069_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _070_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _071_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _072_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _073_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _074_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _075_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _076_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _077_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _078_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _079_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _080_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _081_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _082_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _083_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _084_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _085_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _086_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _087_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _088_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _089_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _090_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _091_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _092_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _093_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _094_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _095_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _096_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _097_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _098_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _099_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _100_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _101_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _102_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _103_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _104_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _105_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _106_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _107_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _108_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _109_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _110_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _111_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _112_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _113_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _114_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _115_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _116_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _117_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _118_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _119_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _120_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _121_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _122_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _123_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _124_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _125_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _126_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _127_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _128_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _129_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _130_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _131_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _132_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _133_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _134_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _135_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _136_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _137_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _138_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _139_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _140_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _141_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _142_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _143_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _144_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _145_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _146_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _147_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _148_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _149_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _150_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _151_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _152_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _153_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _154_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _155_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _156_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _157_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _158_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _159_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _160_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _161_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _162_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _163_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _164_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _165_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _166_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _167_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _168_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _169_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _170_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _171_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _172_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _173_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _174_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _175_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _176_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _177_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _178_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _179_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _180_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _181_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _182_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _183_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _184_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _185_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _186_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _187_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _188_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _189_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _190_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _191_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _192_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _193_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _194_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _195_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _196_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _197_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _198_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _199_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _200_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _201_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _202_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _203_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _204_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _205_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _206_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _207_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _208_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _209_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _210_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _211_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _212_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _213_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _214_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _215_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _216_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _217_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _218_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _219_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _220_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _221_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _222_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _223_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _224_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _225_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _226_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _227_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _228_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _229_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _230_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _231_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _232_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _233_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _234_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _235_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _236_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _237_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _238_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _239_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _240_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _241_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _242_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _243_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _244_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _245_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _246_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _247_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _248_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _249_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _250_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _251_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _252_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _253_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _254_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _255_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _256_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _257_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _258_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _259_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _260_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _261_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _262_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _263_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _264_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _265_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _266_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _267_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _268_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _269_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _270_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _271_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _272_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _273_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _274_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _275_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _276_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _277_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _278_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _279_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _280_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _281_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _282_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _283_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _284_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _285_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _286_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _287_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _288_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _289_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _290_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _291_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _292_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _293_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _294_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _295_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _296_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _297_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _298_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _299_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _300_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _301_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _302_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _303_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _304_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _305_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _306_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _307_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _308_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _309_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _310_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _311_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _312_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _313_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _314_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _315_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _316_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _317_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _318_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _319_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _320_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _321_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _322_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _323_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _324_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _325_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _326_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _327_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _328_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _329_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _330_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _331_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _332_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _333_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _334_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _335_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _336_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _337_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _338_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _339_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _340_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _341_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _342_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _343_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _344_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _345_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _346_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _347_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _348_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _349_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _350_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _351_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _352_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _353_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _354_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _355_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _356_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _357_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _358_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _359_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _360_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _361_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _362_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _363_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _364_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _365_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _366_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _367_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _368_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _369_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _370_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _371_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _372_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _373_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _374_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _375_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _376_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _377_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _378_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _379_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _380_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _381_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _382_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _383_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _384_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _385_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _386_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _387_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _388_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _389_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _390_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _391_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _392_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _393_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _394_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _395_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _396_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _397_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _398_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _399_ DFF_X1 + PLACED ( 146680 15234 ) N ; + - _400_ DFF_X1 + PLACED ( 146680 15234 ) N ; +END COMPONENTS +PINS 3 ; + - io_1 + NET io_1 + DIRECTION INPUT + USE SIGNAL + + PORT + + LAYER metal6 ( -140 -140 ) ( 140 140 ) + + PLACED ( 187230 140 ) N ; + - io_2 + NET io_2 + DIRECTION INPUT + USE SIGNAL + + PORT + + LAYER metal6 ( -140 -140 ) ( 140 140 ) + + PLACED ( 121150 140 ) N ; + - io_3 + NET io_3 + DIRECTION INPUT + USE SIGNAL + + PORT + + LAYER metal6 ( -140 -140 ) ( 140 140 ) + + PLACED ( 275710 140 ) N ; +END PINS +NETS 3 ; + - io_1 ( PIN io_1 ) + USE SIGNAL ; + - io_2 ( PIN io_2 ) + USE SIGNAL ; + - io_3 ( PIN io_3 ) + USE SIGNAL ; +END NETS +END DESIGN diff --git a/src/mpl2/test/io_constraints2.ok b/src/mpl2/test/io_constraints2.ok new file mode 100644 index 00000000000..aab6bf1871a --- /dev/null +++ b/src/mpl2/test/io_constraints2.ok @@ -0,0 +1,30 @@ +[INFO ODB-0227] LEF file: ./Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells +[INFO ODB-0227] LEF file: ./testcases/macro_only.lef, created 9 library cells +[WARNING STA-1171] ./testcases/macro_only.lib line 32, default_max_transition is 0.0. +[WARNING ORD-2011] LEF master DFF_X1 has no liberty cell. +[INFO ODB-0128] Design: io_constraints1 +[INFO ODB-0252] Updated 3 pins. +[INFO ODB-0253] Updated 401 components. +Found 1 macro blocks. +Using 2 tracks default min distance between IO pins. +[INFO PPL-0001] Number of slots 974 +[INFO PPL-0002] Number of I/O 3 +[INFO PPL-0003] Number of I/O w/sink 0 +[INFO PPL-0004] Number of I/O w/o sink 3 +[INFO PPL-0012] I/O nets HPWL: 0.00 um. +Die Area: (0, 0) (150, 125), Floorplan Area: (0, 0) (149.91, 124.6) + Number of std cell instances: 400 + Area of std cell instances: 1808.79 + Number of macros: 1 + Area of macros: 10000.00 + Halo width: 4.00 + Halo height: 4.00 + Area of macros with halos: 11664.00 + Area of std cell instances + Area of macros: 11808.79 + Floorplan area: 18678.79 + Design Utilization: 0.63 + Floorplan Utilization: 0.21 + Manufacturing Grid: 10 + +[WARNING MPL-0014] No Liberty data found for std cells. Continuing without dataflow. +No differences found. diff --git a/src/mpl2/test/io_constraints2.tcl b/src/mpl2/test/io_constraints2.tcl new file mode 100644 index 00000000000..17e7fbe7cb5 --- /dev/null +++ b/src/mpl2/test/io_constraints2.tcl @@ -0,0 +1,25 @@ +# Test if pin access blockage is generated correctly for a case +# with all boundaries blocked except one. +source "helpers.tcl" + +# We're not interested in the connections, so don't include the lib. +read_lef "./Nangate45/Nangate45.lef" + +read_lef "./testcases/macro_only.lef" +read_liberty "./testcases/macro_only.lib" + +read_verilog "./testcases/io_constraints1.v" +link_design "io_constraints1" +read_def "./testcases/io_constraints1.def" -floorplan_initialize + +# Run random PPL to incorporate the -exclude constraints into ODB +place_pins -annealing -random -hor_layers metal5 -ver_layer metal6 \ + -exclude left:* -exclude right:* -exclude top:* + +set_thread_count 0 +rtl_macro_placer -report_directory results/io_constraints2 -halo_width 4.0 + +set def_file [make_result_file io_constraints2.def] +write_def $def_file + +diff_files io_constraints2.defok $def_file \ No newline at end of file diff --git a/src/mpl2/test/testcases/io_constraints1.def b/src/mpl2/test/testcases/io_constraints1.def new file mode 100644 index 00000000000..53b434d551d --- /dev/null +++ b/src/mpl2/test/testcases/io_constraints1.def @@ -0,0 +1,526 @@ +VERSION 5.8 ; +DIVIDERCHAR "/" ; +BUSBITCHARS "[]" ; +DESIGN io_constraints1 ; +UNITS DISTANCE MICRONS 2000 ; +DIEAREA ( 0 0 ) ( 300000 250000 ) ; +ROW ROW_0 FreePDK45_38x28_10R_NP_162NW_34O 0 0 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_1 FreePDK45_38x28_10R_NP_162NW_34O 0 2800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_2 FreePDK45_38x28_10R_NP_162NW_34O 0 5600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_3 FreePDK45_38x28_10R_NP_162NW_34O 0 8400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_4 FreePDK45_38x28_10R_NP_162NW_34O 0 11200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_5 FreePDK45_38x28_10R_NP_162NW_34O 0 14000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_6 FreePDK45_38x28_10R_NP_162NW_34O 0 16800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_7 FreePDK45_38x28_10R_NP_162NW_34O 0 19600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_8 FreePDK45_38x28_10R_NP_162NW_34O 0 22400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_9 FreePDK45_38x28_10R_NP_162NW_34O 0 25200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_10 FreePDK45_38x28_10R_NP_162NW_34O 0 28000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_11 FreePDK45_38x28_10R_NP_162NW_34O 0 30800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_12 FreePDK45_38x28_10R_NP_162NW_34O 0 33600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_13 FreePDK45_38x28_10R_NP_162NW_34O 0 36400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_14 FreePDK45_38x28_10R_NP_162NW_34O 0 39200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_15 FreePDK45_38x28_10R_NP_162NW_34O 0 42000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_16 FreePDK45_38x28_10R_NP_162NW_34O 0 44800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_17 FreePDK45_38x28_10R_NP_162NW_34O 0 47600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_18 FreePDK45_38x28_10R_NP_162NW_34O 0 50400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_19 FreePDK45_38x28_10R_NP_162NW_34O 0 53200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_20 FreePDK45_38x28_10R_NP_162NW_34O 0 56000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_21 FreePDK45_38x28_10R_NP_162NW_34O 0 58800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_22 FreePDK45_38x28_10R_NP_162NW_34O 0 61600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_23 FreePDK45_38x28_10R_NP_162NW_34O 0 64400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_24 FreePDK45_38x28_10R_NP_162NW_34O 0 67200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_25 FreePDK45_38x28_10R_NP_162NW_34O 0 70000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_26 FreePDK45_38x28_10R_NP_162NW_34O 0 72800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_27 FreePDK45_38x28_10R_NP_162NW_34O 0 75600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_28 FreePDK45_38x28_10R_NP_162NW_34O 0 78400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_29 FreePDK45_38x28_10R_NP_162NW_34O 0 81200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_30 FreePDK45_38x28_10R_NP_162NW_34O 0 84000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_31 FreePDK45_38x28_10R_NP_162NW_34O 0 86800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_32 FreePDK45_38x28_10R_NP_162NW_34O 0 89600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_33 FreePDK45_38x28_10R_NP_162NW_34O 0 92400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_34 FreePDK45_38x28_10R_NP_162NW_34O 0 95200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_35 FreePDK45_38x28_10R_NP_162NW_34O 0 98000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_36 FreePDK45_38x28_10R_NP_162NW_34O 0 100800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_37 FreePDK45_38x28_10R_NP_162NW_34O 0 103600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_38 FreePDK45_38x28_10R_NP_162NW_34O 0 106400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_39 FreePDK45_38x28_10R_NP_162NW_34O 0 109200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_40 FreePDK45_38x28_10R_NP_162NW_34O 0 112000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_41 FreePDK45_38x28_10R_NP_162NW_34O 0 114800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_42 FreePDK45_38x28_10R_NP_162NW_34O 0 117600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_43 FreePDK45_38x28_10R_NP_162NW_34O 0 120400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_44 FreePDK45_38x28_10R_NP_162NW_34O 0 123200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_45 FreePDK45_38x28_10R_NP_162NW_34O 0 126000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_46 FreePDK45_38x28_10R_NP_162NW_34O 0 128800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_47 FreePDK45_38x28_10R_NP_162NW_34O 0 131600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_48 FreePDK45_38x28_10R_NP_162NW_34O 0 134400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_49 FreePDK45_38x28_10R_NP_162NW_34O 0 137200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_50 FreePDK45_38x28_10R_NP_162NW_34O 0 140000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_51 FreePDK45_38x28_10R_NP_162NW_34O 0 142800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_52 FreePDK45_38x28_10R_NP_162NW_34O 0 145600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_53 FreePDK45_38x28_10R_NP_162NW_34O 0 148400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_54 FreePDK45_38x28_10R_NP_162NW_34O 0 151200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_55 FreePDK45_38x28_10R_NP_162NW_34O 0 154000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_56 FreePDK45_38x28_10R_NP_162NW_34O 0 156800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_57 FreePDK45_38x28_10R_NP_162NW_34O 0 159600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_58 FreePDK45_38x28_10R_NP_162NW_34O 0 162400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_59 FreePDK45_38x28_10R_NP_162NW_34O 0 165200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_60 FreePDK45_38x28_10R_NP_162NW_34O 0 168000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_61 FreePDK45_38x28_10R_NP_162NW_34O 0 170800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_62 FreePDK45_38x28_10R_NP_162NW_34O 0 173600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_63 FreePDK45_38x28_10R_NP_162NW_34O 0 176400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_64 FreePDK45_38x28_10R_NP_162NW_34O 0 179200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_65 FreePDK45_38x28_10R_NP_162NW_34O 0 182000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_66 FreePDK45_38x28_10R_NP_162NW_34O 0 184800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_67 FreePDK45_38x28_10R_NP_162NW_34O 0 187600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_68 FreePDK45_38x28_10R_NP_162NW_34O 0 190400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_69 FreePDK45_38x28_10R_NP_162NW_34O 0 193200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_70 FreePDK45_38x28_10R_NP_162NW_34O 0 196000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_71 FreePDK45_38x28_10R_NP_162NW_34O 0 198800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_72 FreePDK45_38x28_10R_NP_162NW_34O 0 201600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_73 FreePDK45_38x28_10R_NP_162NW_34O 0 204400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_74 FreePDK45_38x28_10R_NP_162NW_34O 0 207200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_75 FreePDK45_38x28_10R_NP_162NW_34O 0 210000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_76 FreePDK45_38x28_10R_NP_162NW_34O 0 212800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_77 FreePDK45_38x28_10R_NP_162NW_34O 0 215600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_78 FreePDK45_38x28_10R_NP_162NW_34O 0 218400 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_79 FreePDK45_38x28_10R_NP_162NW_34O 0 221200 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_80 FreePDK45_38x28_10R_NP_162NW_34O 0 224000 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_81 FreePDK45_38x28_10R_NP_162NW_34O 0 226800 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_82 FreePDK45_38x28_10R_NP_162NW_34O 0 229600 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_83 FreePDK45_38x28_10R_NP_162NW_34O 0 232400 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_84 FreePDK45_38x28_10R_NP_162NW_34O 0 235200 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_85 FreePDK45_38x28_10R_NP_162NW_34O 0 238000 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_86 FreePDK45_38x28_10R_NP_162NW_34O 0 240800 N DO 789 BY 1 STEP 380 0 ; +ROW ROW_87 FreePDK45_38x28_10R_NP_162NW_34O 0 243600 FS DO 789 BY 1 STEP 380 0 ; +ROW ROW_88 FreePDK45_38x28_10R_NP_162NW_34O 0 246400 N DO 789 BY 1 STEP 380 0 ; +TRACKS X 190 DO 2368 STEP 380 LAYER metal1 ; +TRACKS Y 140 DO 3214 STEP 280 LAYER metal1 ; +TRACKS X 190 DO 2368 STEP 380 LAYER metal2 ; +TRACKS Y 140 DO 3214 STEP 280 LAYER metal2 ; +TRACKS X 190 DO 2368 STEP 380 LAYER metal3 ; +TRACKS Y 140 DO 3214 STEP 280 LAYER metal3 ; +TRACKS X 190 DO 1607 STEP 560 LAYER metal4 ; +TRACKS Y 140 DO 1607 STEP 560 LAYER metal4 ; +TRACKS X 190 DO 1607 STEP 560 LAYER metal5 ; +TRACKS Y 140 DO 1607 STEP 560 LAYER metal5 ; +TRACKS X 190 DO 1607 STEP 560 LAYER metal6 ; +TRACKS Y 140 DO 1607 STEP 560 LAYER metal6 ; +TRACKS X 190 DO 563 STEP 1600 LAYER metal7 ; +TRACKS Y 140 DO 563 STEP 1600 LAYER metal7 ; +TRACKS X 190 DO 563 STEP 1600 LAYER metal8 ; +TRACKS Y 140 DO 563 STEP 1600 LAYER metal8 ; +TRACKS X 190 DO 282 STEP 3200 LAYER metal9 ; +TRACKS Y 140 DO 282 STEP 3200 LAYER metal9 ; +TRACKS X 190 DO 282 STEP 3200 LAYER metal10 ; +TRACKS Y 140 DO 282 STEP 3200 LAYER metal10 ; +COMPONENTS 401 ; + - MACRO_1 HM_100x100_1x1 ; + - _001_ DFF_X1 ; + - _002_ DFF_X1 ; + - _003_ DFF_X1 ; + - _004_ DFF_X1 ; + - _005_ DFF_X1 ; + - _006_ DFF_X1 ; + - _007_ DFF_X1 ; + - _008_ DFF_X1 ; + - _009_ DFF_X1 ; + - _010_ DFF_X1 ; + - _011_ DFF_X1 ; + - _012_ DFF_X1 ; + - _013_ DFF_X1 ; + - _014_ DFF_X1 ; + - _015_ DFF_X1 ; + - _016_ DFF_X1 ; + - _017_ DFF_X1 ; + - _018_ DFF_X1 ; + - _019_ DFF_X1 ; + - _020_ DFF_X1 ; + - _021_ DFF_X1 ; + - _022_ DFF_X1 ; + - _023_ DFF_X1 ; + - _024_ DFF_X1 ; + - _025_ DFF_X1 ; + - _026_ DFF_X1 ; + - _027_ DFF_X1 ; + - _028_ DFF_X1 ; + - _029_ DFF_X1 ; + - _030_ DFF_X1 ; + - _031_ DFF_X1 ; + - _032_ DFF_X1 ; + - _033_ DFF_X1 ; + - _034_ DFF_X1 ; + - _035_ DFF_X1 ; + - _036_ DFF_X1 ; + - _037_ DFF_X1 ; + - _038_ DFF_X1 ; + - _039_ DFF_X1 ; + - _040_ DFF_X1 ; + - _041_ DFF_X1 ; + - _042_ DFF_X1 ; + - _043_ DFF_X1 ; + - _044_ DFF_X1 ; + - _045_ DFF_X1 ; + - _046_ DFF_X1 ; + - _047_ DFF_X1 ; + - _048_ DFF_X1 ; + - _049_ DFF_X1 ; + - _050_ DFF_X1 ; + - _051_ DFF_X1 ; + - _052_ DFF_X1 ; + - _053_ DFF_X1 ; + - _054_ DFF_X1 ; + - _055_ DFF_X1 ; + - _056_ DFF_X1 ; + - _057_ DFF_X1 ; + - _058_ DFF_X1 ; + - _059_ DFF_X1 ; + - _060_ DFF_X1 ; + - _061_ DFF_X1 ; + - _062_ DFF_X1 ; + - _063_ DFF_X1 ; + - _064_ DFF_X1 ; + - _065_ DFF_X1 ; + - _066_ DFF_X1 ; + - _067_ DFF_X1 ; + - _068_ DFF_X1 ; + - _069_ DFF_X1 ; + - _070_ DFF_X1 ; + - _071_ DFF_X1 ; + - _072_ DFF_X1 ; + - _073_ DFF_X1 ; + - _074_ DFF_X1 ; + - _075_ DFF_X1 ; + - _076_ DFF_X1 ; + - _077_ DFF_X1 ; + - _078_ DFF_X1 ; + - _079_ DFF_X1 ; + - _080_ DFF_X1 ; + - _081_ DFF_X1 ; + - _082_ DFF_X1 ; + - _083_ DFF_X1 ; + - _084_ DFF_X1 ; + - _085_ DFF_X1 ; + - _086_ DFF_X1 ; + - _087_ DFF_X1 ; + - _088_ DFF_X1 ; + - _089_ DFF_X1 ; + - _090_ DFF_X1 ; + - _091_ DFF_X1 ; + - _092_ DFF_X1 ; + - _093_ DFF_X1 ; + - _094_ DFF_X1 ; + - _095_ DFF_X1 ; + - _096_ DFF_X1 ; + - _097_ DFF_X1 ; + - _098_ DFF_X1 ; + - _099_ DFF_X1 ; + - _100_ DFF_X1 ; + - _101_ DFF_X1 ; + - _102_ DFF_X1 ; + - _103_ DFF_X1 ; + - _104_ DFF_X1 ; + - _105_ DFF_X1 ; + - _106_ DFF_X1 ; + - _107_ DFF_X1 ; + - _108_ DFF_X1 ; + - _109_ DFF_X1 ; + - _110_ DFF_X1 ; + - _111_ DFF_X1 ; + - _112_ DFF_X1 ; + - _113_ DFF_X1 ; + - _114_ DFF_X1 ; + - _115_ DFF_X1 ; + - _116_ DFF_X1 ; + - _117_ DFF_X1 ; + - _118_ DFF_X1 ; + - _119_ DFF_X1 ; + - _120_ DFF_X1 ; + - _121_ DFF_X1 ; + - _122_ DFF_X1 ; + - _123_ DFF_X1 ; + - _124_ DFF_X1 ; + - _125_ DFF_X1 ; + - _126_ DFF_X1 ; + - _127_ DFF_X1 ; + - _128_ DFF_X1 ; + - _129_ DFF_X1 ; + - _130_ DFF_X1 ; + - _131_ DFF_X1 ; + - _132_ DFF_X1 ; + - _133_ DFF_X1 ; + - _134_ DFF_X1 ; + - _135_ DFF_X1 ; + - _136_ DFF_X1 ; + - _137_ DFF_X1 ; + - _138_ DFF_X1 ; + - _139_ DFF_X1 ; + - _140_ DFF_X1 ; + - _141_ DFF_X1 ; + - _142_ DFF_X1 ; + - _143_ DFF_X1 ; + - _144_ DFF_X1 ; + - _145_ DFF_X1 ; + - _146_ DFF_X1 ; + - _147_ DFF_X1 ; + - _148_ DFF_X1 ; + - _149_ DFF_X1 ; + - _150_ DFF_X1 ; + - _151_ DFF_X1 ; + - _152_ DFF_X1 ; + - _153_ DFF_X1 ; + - _154_ DFF_X1 ; + - _155_ DFF_X1 ; + - _156_ DFF_X1 ; + - _157_ DFF_X1 ; + - _158_ DFF_X1 ; + - _159_ DFF_X1 ; + - _160_ DFF_X1 ; + - _161_ DFF_X1 ; + - _162_ DFF_X1 ; + - _163_ DFF_X1 ; + - _164_ DFF_X1 ; + - _165_ DFF_X1 ; + - _166_ DFF_X1 ; + - _167_ DFF_X1 ; + - _168_ DFF_X1 ; + - _169_ DFF_X1 ; + - _170_ DFF_X1 ; + - _171_ DFF_X1 ; + - _172_ DFF_X1 ; + - _173_ DFF_X1 ; + - _174_ DFF_X1 ; + - _175_ DFF_X1 ; + - _176_ DFF_X1 ; + - _177_ DFF_X1 ; + - _178_ DFF_X1 ; + - _179_ DFF_X1 ; + - _180_ DFF_X1 ; + - _181_ DFF_X1 ; + - _182_ DFF_X1 ; + - _183_ DFF_X1 ; + - _184_ DFF_X1 ; + - _185_ DFF_X1 ; + - _186_ DFF_X1 ; + - _187_ DFF_X1 ; + - _188_ DFF_X1 ; + - _189_ DFF_X1 ; + - _190_ DFF_X1 ; + - _191_ DFF_X1 ; + - _192_ DFF_X1 ; + - _193_ DFF_X1 ; + - _194_ DFF_X1 ; + - _195_ DFF_X1 ; + - _196_ DFF_X1 ; + - _197_ DFF_X1 ; + - _198_ DFF_X1 ; + - _199_ DFF_X1 ; + - _200_ DFF_X1 ; + - _201_ DFF_X1 ; + - _202_ DFF_X1 ; + - _203_ DFF_X1 ; + - _204_ DFF_X1 ; + - _205_ DFF_X1 ; + - _206_ DFF_X1 ; + - _207_ DFF_X1 ; + - _208_ DFF_X1 ; + - _209_ DFF_X1 ; + - _210_ DFF_X1 ; + - _211_ DFF_X1 ; + - _212_ DFF_X1 ; + - _213_ DFF_X1 ; + - _214_ DFF_X1 ; + - _215_ DFF_X1 ; + - _216_ DFF_X1 ; + - _217_ DFF_X1 ; + - _218_ DFF_X1 ; + - _219_ DFF_X1 ; + - _220_ DFF_X1 ; + - _221_ DFF_X1 ; + - _222_ DFF_X1 ; + - _223_ DFF_X1 ; + - _224_ DFF_X1 ; + - _225_ DFF_X1 ; + - _226_ DFF_X1 ; + - _227_ DFF_X1 ; + - _228_ DFF_X1 ; + - _229_ DFF_X1 ; + - _230_ DFF_X1 ; + - _231_ DFF_X1 ; + - _232_ DFF_X1 ; + - _233_ DFF_X1 ; + - _234_ DFF_X1 ; + - _235_ DFF_X1 ; + - _236_ DFF_X1 ; + - _237_ DFF_X1 ; + - _238_ DFF_X1 ; + - _239_ DFF_X1 ; + - _240_ DFF_X1 ; + - _241_ DFF_X1 ; + - _242_ DFF_X1 ; + - _243_ DFF_X1 ; + - _244_ DFF_X1 ; + - _245_ DFF_X1 ; + - _246_ DFF_X1 ; + - _247_ DFF_X1 ; + - _248_ DFF_X1 ; + - _249_ DFF_X1 ; + - _250_ DFF_X1 ; + - _251_ DFF_X1 ; + - _252_ DFF_X1 ; + - _253_ DFF_X1 ; + - _254_ DFF_X1 ; + - _255_ DFF_X1 ; + - _256_ DFF_X1 ; + - _257_ DFF_X1 ; + - _258_ DFF_X1 ; + - _259_ DFF_X1 ; + - _260_ DFF_X1 ; + - _261_ DFF_X1 ; + - _262_ DFF_X1 ; + - _263_ DFF_X1 ; + - _264_ DFF_X1 ; + - _265_ DFF_X1 ; + - _266_ DFF_X1 ; + - _267_ DFF_X1 ; + - _268_ DFF_X1 ; + - _269_ DFF_X1 ; + - _270_ DFF_X1 ; + - _271_ DFF_X1 ; + - _272_ DFF_X1 ; + - _273_ DFF_X1 ; + - _274_ DFF_X1 ; + - _275_ DFF_X1 ; + - _276_ DFF_X1 ; + - _277_ DFF_X1 ; + - _278_ DFF_X1 ; + - _279_ DFF_X1 ; + - _280_ DFF_X1 ; + - _281_ DFF_X1 ; + - _282_ DFF_X1 ; + - _283_ DFF_X1 ; + - _284_ DFF_X1 ; + - _285_ DFF_X1 ; + - _286_ DFF_X1 ; + - _287_ DFF_X1 ; + - _288_ DFF_X1 ; + - _289_ DFF_X1 ; + - _290_ DFF_X1 ; + - _291_ DFF_X1 ; + - _292_ DFF_X1 ; + - _293_ DFF_X1 ; + - _294_ DFF_X1 ; + - _295_ DFF_X1 ; + - _296_ DFF_X1 ; + - _297_ DFF_X1 ; + - _298_ DFF_X1 ; + - _299_ DFF_X1 ; + - _300_ DFF_X1 ; + - _301_ DFF_X1 ; + - _302_ DFF_X1 ; + - _303_ DFF_X1 ; + - _304_ DFF_X1 ; + - _305_ DFF_X1 ; + - _306_ DFF_X1 ; + - _307_ DFF_X1 ; + - _308_ DFF_X1 ; + - _309_ DFF_X1 ; + - _310_ DFF_X1 ; + - _311_ DFF_X1 ; + - _312_ DFF_X1 ; + - _313_ DFF_X1 ; + - _314_ DFF_X1 ; + - _315_ DFF_X1 ; + - _316_ DFF_X1 ; + - _317_ DFF_X1 ; + - _318_ DFF_X1 ; + - _319_ DFF_X1 ; + - _320_ DFF_X1 ; + - _321_ DFF_X1 ; + - _322_ DFF_X1 ; + - _323_ DFF_X1 ; + - _324_ DFF_X1 ; + - _325_ DFF_X1 ; + - _326_ DFF_X1 ; + - _327_ DFF_X1 ; + - _328_ DFF_X1 ; + - _329_ DFF_X1 ; + - _330_ DFF_X1 ; + - _331_ DFF_X1 ; + - _332_ DFF_X1 ; + - _333_ DFF_X1 ; + - _334_ DFF_X1 ; + - _335_ DFF_X1 ; + - _336_ DFF_X1 ; + - _337_ DFF_X1 ; + - _338_ DFF_X1 ; + - _339_ DFF_X1 ; + - _340_ DFF_X1 ; + - _341_ DFF_X1 ; + - _342_ DFF_X1 ; + - _343_ DFF_X1 ; + - _344_ DFF_X1 ; + - _345_ DFF_X1 ; + - _346_ DFF_X1 ; + - _347_ DFF_X1 ; + - _348_ DFF_X1 ; + - _349_ DFF_X1 ; + - _350_ DFF_X1 ; + - _351_ DFF_X1 ; + - _352_ DFF_X1 ; + - _353_ DFF_X1 ; + - _354_ DFF_X1 ; + - _355_ DFF_X1 ; + - _356_ DFF_X1 ; + - _357_ DFF_X1 ; + - _358_ DFF_X1 ; + - _359_ DFF_X1 ; + - _360_ DFF_X1 ; + - _361_ DFF_X1 ; + - _362_ DFF_X1 ; + - _363_ DFF_X1 ; + - _364_ DFF_X1 ; + - _365_ DFF_X1 ; + - _366_ DFF_X1 ; + - _367_ DFF_X1 ; + - _368_ DFF_X1 ; + - _369_ DFF_X1 ; + - _370_ DFF_X1 ; + - _371_ DFF_X1 ; + - _372_ DFF_X1 ; + - _373_ DFF_X1 ; + - _374_ DFF_X1 ; + - _375_ DFF_X1 ; + - _376_ DFF_X1 ; + - _377_ DFF_X1 ; + - _378_ DFF_X1 ; + - _379_ DFF_X1 ; + - _380_ DFF_X1 ; + - _381_ DFF_X1 ; + - _382_ DFF_X1 ; + - _383_ DFF_X1 ; + - _384_ DFF_X1 ; + - _385_ DFF_X1 ; + - _386_ DFF_X1 ; + - _387_ DFF_X1 ; + - _388_ DFF_X1 ; + - _389_ DFF_X1 ; + - _390_ DFF_X1 ; + - _391_ DFF_X1 ; + - _392_ DFF_X1 ; + - _393_ DFF_X1 ; + - _394_ DFF_X1 ; + - _395_ DFF_X1 ; + - _396_ DFF_X1 ; + - _397_ DFF_X1 ; + - _398_ DFF_X1 ; + - _399_ DFF_X1 ; + - _400_ DFF_X1 ; +END COMPONENTS + +PINS 1 ; + - io_1 + NET io_1 ; + - io_2 + NET io_2 ; + - io_3 + NET io_3 ; +END PINS + +END DESIGN \ No newline at end of file diff --git a/src/mpl2/test/testcases/io_constraints1.v b/src/mpl2/test/testcases/io_constraints1.v new file mode 100644 index 00000000000..4fa7267b58c --- /dev/null +++ b/src/mpl2/test/testcases/io_constraints1.v @@ -0,0 +1,409 @@ +module io_constraints1 ( \io_1 , \io_2 , \io_3 ); + HM_100x100_1x1 MACRO_1 ( ) ; + + DFF_X1 _001_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _002_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _003_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _004_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _005_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _006_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _007_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _008_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _009_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _010_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _011_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _012_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _013_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _014_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _015_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _016_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _017_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _018_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _019_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _020_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _021_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _022_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _023_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _024_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _025_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _026_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _027_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _028_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _029_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _030_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _031_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _032_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _033_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _034_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _035_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _036_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _037_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _038_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _039_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _040_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _041_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _042_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _043_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _044_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _045_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _046_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _047_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _048_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _049_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _050_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _051_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _052_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _053_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _054_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _055_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _056_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _057_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _058_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _059_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _060_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _061_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _062_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _063_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _064_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _065_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _066_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _067_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _068_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _069_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _070_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _071_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _072_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _073_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _074_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _075_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _076_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _077_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _078_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _079_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _080_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _081_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _082_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _083_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _084_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _085_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _086_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _087_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _088_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _089_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _090_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _091_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _092_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _093_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _094_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _095_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _096_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _097_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _098_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _099_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _100_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _101_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _102_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _103_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _104_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _105_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _106_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _107_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _108_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _109_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _110_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _111_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _112_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _113_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _114_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _115_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _116_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _117_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _118_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _119_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _120_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _121_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _122_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _123_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _124_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _125_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _126_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _127_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _128_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _129_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _130_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _131_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _132_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _133_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _134_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _135_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _136_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _137_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _138_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _139_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _140_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _141_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _142_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _143_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _144_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _145_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _146_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _147_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _148_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _149_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _150_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _151_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _152_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _153_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _154_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _155_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _156_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _157_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _158_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _159_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _160_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _161_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _162_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _163_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _164_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _165_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _166_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _167_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _168_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _169_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _170_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _171_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _172_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _173_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _174_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _175_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _176_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _177_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _178_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _179_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _180_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _181_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _182_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _183_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _184_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _185_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _186_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _187_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _188_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _189_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _190_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _191_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _192_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _193_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _194_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _195_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _196_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _197_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _198_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _199_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _200_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _201_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _202_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _203_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _204_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _205_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _206_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _207_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _208_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _209_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _210_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _211_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _212_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _213_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _214_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _215_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _216_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _217_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _218_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _219_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _220_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _221_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _222_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _223_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _224_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _225_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _226_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _227_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _228_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _229_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _230_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _231_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _232_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _233_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _234_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _235_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _236_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _237_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _238_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _239_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _240_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _241_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _242_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _243_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _244_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _245_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _246_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _247_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _248_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _249_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _250_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _251_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _252_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _253_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _254_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _255_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _256_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _257_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _258_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _259_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _260_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _261_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _262_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _263_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _264_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _265_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _266_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _267_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _268_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _269_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _270_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _271_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _272_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _273_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _274_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _275_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _276_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _277_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _278_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _279_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _280_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _281_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _282_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _283_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _284_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _285_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _286_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _287_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _288_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _289_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _290_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _291_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _292_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _293_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _294_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _295_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _296_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _297_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _298_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _299_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _300_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _301_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _302_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _303_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _304_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _305_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _306_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _307_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _308_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _309_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _310_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _311_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _312_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _313_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _314_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _315_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _316_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _317_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _318_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _319_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _320_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _321_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _322_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _323_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _324_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _325_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _326_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _327_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _328_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _329_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _330_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _331_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _332_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _333_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _334_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _335_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _336_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _337_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _338_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _339_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _340_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _341_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _342_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _343_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _344_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _345_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _346_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _347_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _348_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _349_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _350_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _351_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _352_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _353_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _354_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _355_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _356_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _357_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _358_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _359_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _360_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _361_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _362_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _363_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _364_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _365_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _366_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _367_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _368_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _369_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _370_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _371_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _372_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _373_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _374_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _375_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _376_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _377_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _378_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _379_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _380_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _381_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _382_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _383_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _384_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _385_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _386_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _387_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _388_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _389_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _390_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _391_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _392_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _393_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _394_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _395_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _396_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _397_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _398_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _399_ ( .CK(), .D(), .Q(), .QN() ); + DFF_X1 _400_ ( .CK(), .D(), .Q(), .QN() ); + + input io_1; + input io_2; + input io_3; +endmodule +