Skip to content

Commit 6cc7d33

Browse files
committed
dpl: more details for debugging initial snapping
Signed-off-by: Augusto Berndt <augusto.berndt@precisioninno.com>
1 parent 6e0141d commit 6cc7d33

1 file changed

Lines changed: 114 additions & 27 deletions

File tree

src/dpl/src/NegotiationLegalizer.cpp

Lines changed: 114 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -640,25 +640,106 @@ bool NegotiationLegalizer::initFromDb()
640640
// only check site existence and hard blockages here (both encoded in
641641
// pixel.is_valid). Soft blockages, routing-layer blockages, and
642642
// cell-vs-cell overlap are left to the negotiation loop.
643-
// if (!cell.fixed) {
644-
if (false) {
643+
if (!cell.fixed) {
644+
// if (false) {
645645
odb::dbSite* site = master->getSite();
646646
// Check that the full cell footprint (width x height) fits on valid
647647
// sites.
648-
auto isValidSite = [&](int gx, int gy) -> bool {
649-
if (gx < 0 || gx + cell.width > grid_w_ || gy < 0
650-
|| gy + cell.height > grid_h_) {
648+
auto isValidSite = [&](int pixel_left, int pixel_bottom) -> bool {
649+
const bool past_left = pixel_left < 0;
650+
const bool past_bottom = pixel_bottom < 0;
651+
const bool past_right = pixel_left + cell.width > grid_w_;
652+
const bool past_top = pixel_bottom + cell.height > grid_h_;
653+
if (past_left || past_right || past_bottom || past_top) {
654+
std::string detail;
655+
if (past_left) {
656+
detail += fmt::format(
657+
" left edge of footprint is at column {} (before grid "
658+
"column 0);",
659+
pixel_left);
660+
}
661+
if (past_bottom) {
662+
detail += fmt::format(
663+
" bottom edge of footprint is at row {} (below grid "
664+
"row 0);",
665+
pixel_bottom);
666+
}
667+
if (past_right) {
668+
detail += fmt::format(
669+
" right edge of footprint is at column {} (past grid "
670+
"width {});",
671+
pixel_left + cell.width,
672+
grid_w_);
673+
}
674+
if (past_top) {
675+
detail += fmt::format(
676+
" top edge of footprint is at row {} (past grid "
677+
"height {});",
678+
pixel_bottom + cell.height,
679+
grid_h_);
680+
}
681+
debugPrint(logger_,
682+
utl::DPL,
683+
"negotiation",
684+
1,
685+
"Position grid ({}, {}) rejected for instance '{}': "
686+
"cell footprint {}x{} sites does not fit in grid "
687+
"{}x{} sites.{}",
688+
pixel_left,
689+
pixel_bottom,
690+
cell.db_inst->getName(),
691+
cell.width,
692+
cell.height,
693+
grid_w_,
694+
grid_h_,
695+
detail);
651696
return false;
652697
}
653698
// Site type check at the anchor row is representative for all rows.
654699
if (site != nullptr
655-
&& !dpl_grid->getSiteOrientation(GridX{gx}, GridY{gy}, site)
700+
&& !dpl_grid->getSiteOrientation(GridX{pixel_left}, GridY{pixel_bottom}, site)
656701
.has_value()) {
702+
debugPrint(logger_,
703+
utl::DPL,
704+
"negotiation",
705+
1,
706+
"Position grid ({}, {}) rejected for instance '{}': "
707+
"the row at this Y has no site matching the master's "
708+
"site '{}' (master='{}', class={}). The row is either "
709+
"missing here or uses a different site definition.",
710+
pixel_left,
711+
pixel_bottom,
712+
cell.db_inst->getName(),
713+
site->getName(),
714+
master->getName(),
715+
master->getType().getString());
657716
return false;
658717
}
659-
for (int dy = 0; dy < cell.height; ++dy) {
660-
for (int dx = 0; dx < cell.width; ++dx) {
661-
if (!dpl_grid->pixel(GridY{gy + dy}, GridX{gx + dx}).is_valid) {
718+
for (int row_offset = 0; row_offset < cell.height; ++row_offset) {
719+
for (int col_offset = 0; col_offset < cell.width; ++col_offset) {
720+
const auto& p = dpl_grid->pixel(
721+
GridY{pixel_bottom + row_offset},
722+
GridX{pixel_left + col_offset});
723+
if (!p.is_valid) {
724+
debugPrint(logger_,
725+
utl::DPL,
726+
"negotiation",
727+
1,
728+
"Position grid ({}, {}) rejected for instance "
729+
"'{}': pixel ({}, {}) inside the {}x{} footprint "
730+
"is marked invalid (hopeless={}, "
731+
"blocked_layers=0x{:x}). This pixel is under a "
732+
"macro, a hard blockage, or not covered by any "
733+
"row.",
734+
pixel_left,
735+
pixel_bottom,
736+
cell.db_inst->getName(),
737+
pixel_left + col_offset,
738+
pixel_bottom + row_offset,
739+
cell.width,
740+
cell.height,
741+
p.is_hopeless,
742+
p.blocked_layers);
662743
return false;
663744
}
664745
}
@@ -714,18 +795,18 @@ bool NegotiationLegalizer::initFromDb()
714795

715796
if (!isValidSite(cell.init_x, cell.init_y)
716797
|| !isInRegionOk(cell.init_x, cell.init_y)) {
717-
// debugPrint(logger_,
718-
// utl::DPL,
719-
// "negotiation",
720-
// 1,
721-
logger_->report(
722-
"Instance {} at ({}, {}) snaps to invalid site at "
723-
"({}, {}). Searching for nearest valid site.",
724-
cell.db_inst->getName(),
725-
db_x,
726-
db_y,
727-
die_xlo_ + cell.init_x * site_width_,
728-
die_ylo_ + dpl_grid->gridYToDbu(GridY{cell.init_y}).v);
798+
debugPrint(logger_,
799+
utl::DPL,
800+
"negotiation",
801+
1,
802+
"Instance '{}' initially at dbu ({}, {}) rounds to "
803+
"an invalid initial position at dbu ({}, {}). Will "
804+
"search for the nearest valid site.",
805+
cell.db_inst->getName(),
806+
db_x,
807+
db_y,
808+
die_xlo_ + cell.init_x * site_width_,
809+
die_ylo_ + dpl_grid->gridYToDbu(GridY{cell.init_y}).v);
729810

730811
// Linear scan in the four cardinal directions (same shape as
731812
// Opendp::moveHopeless).
@@ -814,12 +895,18 @@ bool NegotiationLegalizer::initFromDb()
814895
const int init_x_dbu = die_xlo_ + cell.init_x * site_width_;
815896
const int init_y_dbu
816897
= die_ylo_ + dpl_grid->gridYToDbu(GridY{cell.init_y}).v;
817-
logger_->report(
818-
"Could not find a valid site for instance {} (init ({}, {}) "
819-
"dbu).",
820-
cell.db_inst->getName(),
821-
init_x_dbu,
822-
init_y_dbu);
898+
debugPrint(logger_,
899+
utl::DPL,
900+
"negotiation",
901+
1,
902+
"No valid site found for instance '{}' near its "
903+
"initial position dbu ({}, {}). Linear scan in all "
904+
"four cardinal directions exhausted with no match. "
905+
"Leaving instance at its initial position; "
906+
"negotiation will need to legalize it.",
907+
cell.db_inst->getName(),
908+
init_x_dbu,
909+
init_y_dbu);
823910
}
824911
}
825912
}

0 commit comments

Comments
 (0)