diff --git a/src/dpl/src/NegotiationLegalizer.cpp b/src/dpl/src/NegotiationLegalizer.cpp index 61683997c74..9389dfa81ce 100644 --- a/src/dpl/src/NegotiationLegalizer.cpp +++ b/src/dpl/src/NegotiationLegalizer.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -523,13 +524,8 @@ bool NegotiationLegalizer::initFromDb() die_xhi_ = core_area.xMax(); die_yhi_ = core_area.yMax(); - // Site width from the DPL grid; row height from the first DB row. site_width_ = dpl_grid->getSiteWidth().v; - for (auto* row : block->getRows()) { - row_height_ = row->getSite()->getHeight(); - break; - } - assert(site_width_ > 0 && row_height_ > 0); + assert(site_width_ > 0); // Grid dimensions from the DPL grid (accounts for actual DB rows). grid_w_ = dpl_grid->getRowSiteCount().v; @@ -578,10 +574,7 @@ bool NegotiationLegalizer::initFromDb() 1, static_cast( std::round(static_cast(master->getWidth()) / site_width_))); - cell.height = std::max( - 1, - static_cast(std::round(static_cast(master->getHeight()) - / row_height_))); + cell.height = dpl_grid->gridHeight(master).v; // Clamp to valid grid range – gridRoundY can return grid_h_ when the // instance is near the top edge. Use (grid_w_ - width) so the full @@ -647,9 +640,9 @@ bool NegotiationLegalizer::initFromDb() for (auto* box : odb_region->getBoundaries()) { RegionRectInline r; r.xlo = (box->xMin() - die_xlo_) / site_width_; - r.ylo = (box->yMin() - die_ylo_) / row_height_; + r.ylo = dpl_grid->gridEndY(DbuY{box->yMin() - die_ylo_}).v; r.xhi = (box->xMax() - die_xlo_) / site_width_; - r.yhi = (box->yMax() - die_ylo_) / row_height_; + r.yhi = dpl_grid->gridSnapDownY(DbuY{box->yMax() - die_ylo_}).v; rects.push_back(r); } it = region_rect_cache.emplace(odb_region, std::move(rects)).first; @@ -684,11 +677,12 @@ bool NegotiationLegalizer::initFromDb() db_x, db_y, die_xlo_ + cell.init_x * site_width_, - die_ylo_ + cell.init_y * row_height_); + die_ylo_ + dpl_grid->gridYToDbu(GridY{cell.init_y}).v); // Priority queue keyed on physical Manhattan distance (DBU) so the // search expands in true physical proximity, not grid-unit proximity. - // One step in X = site_width_ DBU; one step in Y = row_height_ DBU. + // One step in X = site_width_ DBU; Y distance is computed via the + // DPL grid since pixel rows may have non-uniform heights. using PQEntry = std::tuple; // physDist, gx, gy std:: priority_queue, std::greater> @@ -704,8 +698,10 @@ bool NegotiationLegalizer::initFromDb() if (!visited.insert(gy * grid_w_ + gx).second) { return; } - const int dist = std::abs(gx - cell.init_x) * site_width_ - + std::abs(gy - cell.init_y) * row_height_; + const int dy_dbu = dpl_grid->gridYToDbu(GridY{gy}).v + - dpl_grid->gridYToDbu(GridY{cell.init_y}).v; + const int dist + = std::abs(gx - cell.init_x) * site_width_ + std::abs(dy_dbu); pq.emplace(dist, gx, gy); }; @@ -745,6 +741,19 @@ bool NegotiationLegalizer::initFromDb() cells_.push_back(cell); } + std::map neg_height_counts; + for (const NegCell& c : cells_) { + neg_height_counts[c.height]++; + } + logger_->info( + utl::DPL, + 392, + "Negotiation cell height distribution ({} unique row-count(s)):", + neg_height_counts.size()); + for (const auto& [height, count] : neg_height_counts) { + logger_->info(utl::DPL, 393, " height {} row(s): {} cells", height, count); + } + return true; } @@ -813,12 +822,13 @@ void NegotiationLegalizer::initFenceRegions() FenceRegion fr; fr.id = region->getId(); + const Grid* dpl_grid = opendp_->grid_.get(); for (auto* box : region->getBoundaries()) { FenceRect r; r.xlo = (box->xMin() - die_xlo_) / site_width_; - r.ylo = (box->yMin() - die_ylo_) / row_height_; + r.ylo = dpl_grid->gridEndY(DbuY{box->yMin() - die_ylo_}).v; r.xhi = (box->xMax() - die_xlo_) / site_width_; - r.yhi = (box->yMax() - die_ylo_) / row_height_; + r.yhi = dpl_grid->gridSnapDownY(DbuY{box->yMax() - die_ylo_}).v; fr.rects.push_back(r); } diff --git a/src/dpl/src/NegotiationLegalizer.h b/src/dpl/src/NegotiationLegalizer.h index b85b7fb4fa9..a9162b931c1 100644 --- a/src/dpl/src/NegotiationLegalizer.h +++ b/src/dpl/src/NegotiationLegalizer.h @@ -233,7 +233,6 @@ class NegotiationLegalizer Network* network_{nullptr}; int site_width_{0}; - int row_height_{0}; int die_xlo_{0}; int die_ylo_{0}; int die_xhi_{0}; diff --git a/src/dpl/src/NegotiationLegalizerPass.cpp b/src/dpl/src/NegotiationLegalizerPass.cpp index 1a6c8b8053d..39c99ed1a8c 100644 --- a/src/dpl/src/NegotiationLegalizerPass.cpp +++ b/src/dpl/src/NegotiationLegalizerPass.cpp @@ -418,9 +418,10 @@ void NegotiationLegalizer::place(int cell_idx, int x, int y) pushNegotiationPixels(); const NegCell& c = cells_[cell_idx]; const int orig_x_dbu = die_xlo_ + c.init_x * site_width_; - const int orig_y_dbu = die_ylo_ + c.init_y * row_height_; + const int orig_y_dbu + = die_ylo_ + opendp_->grid_->gridYToDbu(GridY{c.init_y}).v; const int tgt_x_dbu = die_xlo_ + c.x * site_width_; - const int tgt_y_dbu = die_ylo_ + c.y * row_height_; + const int tgt_y_dbu = die_ylo_ + opendp_->grid_->gridYToDbu(GridY{c.y}).v; logger_->report( "Pause at placing of cell {}. orig=({},{}) target=({},{}) dbu. " "rowidx={}.", diff --git a/src/dpl/src/dbToOpendp.cpp b/src/dpl/src/dbToOpendp.cpp index 2f306777bff..6a7428e8e1a 100644 --- a/src/dpl/src/dbToOpendp.cpp +++ b/src/dpl/src/dbToOpendp.cpp @@ -187,6 +187,22 @@ void Opendp::importDb() createNetwork(); createArchitecture(); setUpPlacementGroups(); + + if (logger_->debugCheck(utl::DPL, "hybrid", 1)) { + std::map height_counts; + for (const auto& node : network_->getNodes()) { + if (node->getType() != Node::CELL) { + continue; + } + height_counts[node->getHeight().v]++; + } + logger_->report("Cell height distribution ({} unique micron height(s)):", + height_counts.size()); + for (const auto& [height, count] : height_counts) { + logger_->report( + " height {:.3f} um: {} cells", block_->dbuToMicrons(height), count); + } + } } void Opendp::importClear() diff --git a/src/dpl/test/negotiation01.ok b/src/dpl/test/negotiation01.ok index 276c84c743d..caed153b62d 100644 --- a/src/dpl/test/negotiation01.ok +++ b/src/dpl/test/negotiation01.ok @@ -6,6 +6,8 @@ [INFO DPL-0006] Core area: 14266.91 um^2, Instances area: 637.60 um^2, Utilization: 4.5% [INFO DPL-0005] Diamond search max displacement: +/- 500 sites horizontally, +/- 100 rows vertically. [INFO DPL-1102] Legalizing using negotiation legalizer. +[INFO DPL-0392] Negotiation cell height distribution (1 unique row-count(s)): +[INFO DPL-0393] height 1 row(s): 549 cells Negotiation iteration 0: total overflow 12. Negotiation iteration 1: total overflow 0. Placement Analysis diff --git a/src/dpl/test/negotiation_one_site_gap.ok b/src/dpl/test/negotiation_one_site_gap.ok index d2e8327ce58..3957a3ef5b0 100644 --- a/src/dpl/test/negotiation_one_site_gap.ok +++ b/src/dpl/test/negotiation_one_site_gap.ok @@ -6,6 +6,8 @@ [INFO DPL-0006] Core area: 16.49 um^2, Instances area: 3.72 um^2, Utilization: 22.6% [INFO DPL-0005] Diamond search max displacement: +/- 500 sites horizontally, +/- 100 rows vertically. [INFO DPL-1102] Legalizing using negotiation legalizer. +[INFO DPL-0392] Negotiation cell height distribution (1 unique row-count(s)): +[INFO DPL-0393] height 1 row(s): 4 cells Negotiation iteration 0: total overflow 0. Placement Analysis --------------------------------- diff --git a/src/dpl/test/negotiation_regions.ok b/src/dpl/test/negotiation_regions.ok index b80d8b8b557..f6cb7bbd8ee 100644 --- a/src/dpl/test/negotiation_regions.ok +++ b/src/dpl/test/negotiation_regions.ok @@ -6,6 +6,8 @@ [INFO DPL-0006] Core area: 16.49 um^2, Instances area: 2.93 um^2, Utilization: 17.7% [INFO DPL-0005] Diamond search max displacement: +/- 500 sites horizontally, +/- 100 rows vertically. [INFO DPL-1102] Legalizing using negotiation legalizer. +[INFO DPL-0392] Negotiation cell height distribution (1 unique row-count(s)): +[INFO DPL-0393] height 1 row(s): 5 cells Negotiation iteration 0: total overflow 0. Placement Analysis ---------------------------------