|
24 | 24 | #include "odb/dbTransform.h" |
25 | 25 | #include "odb/geom.h" |
26 | 26 | #include "util/journal.h" |
| 27 | +#include "util/symmetry.h" |
27 | 28 | #include "util/utility.h" |
28 | 29 | #include "utl/Logger.h" |
29 | 30 |
|
30 | 31 | using utl::DPL; |
31 | 32 |
|
32 | 33 | namespace dpl { |
33 | 34 |
|
| 35 | +// Helper to check if a cell's master allows the orientation required by the row |
| 36 | +static bool checkMasterSymmetry(Architecture* arch, const Node* nd, int rowId) |
| 37 | +{ |
| 38 | + const auto* rowPtr = arch->getRow(rowId); |
| 39 | + const unsigned rowOri = rowPtr->getOrient(); |
| 40 | + |
| 41 | + auto* dbMaster = nd->getDbInst()->getMaster(); |
| 42 | + unsigned masterSym = DetailedOrient::getMasterSymmetry(dbMaster); |
| 43 | + |
| 44 | + using odb::dbOrientType; |
| 45 | + if (rowOri == dbOrientType::R0 || rowOri == dbOrientType::MY) { |
| 46 | + return true; |
| 47 | + } |
| 48 | + if (rowOri == dbOrientType::MX || rowOri == dbOrientType::R180) { |
| 49 | + return (masterSym & Symmetry_X) != 0; |
| 50 | + } |
| 51 | + return false; |
| 52 | +} |
| 53 | + |
34 | 54 | DetailedMgr::DetailedMgr(Architecture* arch, |
35 | 55 | Network* network, |
36 | 56 | Grid* grid, |
@@ -512,6 +532,9 @@ DetailedSeg* DetailedMgr::findClosestSegment(const Node* nd) |
512 | 532 | if (nd->getGroupId() != curr->getRegId()) { |
513 | 533 | continue; |
514 | 534 | } |
| 535 | + if (!checkMasterSymmetry(arch_, nd, curr->getRowId())) { |
| 536 | + continue; |
| 537 | + } |
515 | 538 |
|
516 | 539 | // Work with left edge. |
517 | 540 | const DbuX x1 = curr->getMinX(); |
@@ -551,6 +574,9 @@ DetailedSeg* DetailedMgr::findClosestSegment(const Node* nd) |
551 | 574 | if (nd->getGroupId() != curr->getRegId()) { |
552 | 575 | continue; |
553 | 576 | } |
| 577 | + if (!checkMasterSymmetry(arch_, nd, curr->getRowId())) { |
| 578 | + continue; |
| 579 | + } |
554 | 580 |
|
555 | 581 | // Work with left edge. |
556 | 582 | const DbuX x1 = curr->getMinX(); |
@@ -591,6 +617,9 @@ DetailedSeg* DetailedMgr::findClosestSegment(const Node* nd) |
591 | 617 | if (nd->getGroupId() != curr->getRegId()) { |
592 | 618 | continue; |
593 | 619 | } |
| 620 | + if (!checkMasterSymmetry(arch_, nd, curr->getRowId())) { |
| 621 | + continue; |
| 622 | + } |
594 | 623 |
|
595 | 624 | // Work with left edge. |
596 | 625 | const DbuX x1 = curr->getMinX(); |
@@ -698,6 +727,10 @@ bool DetailedMgr::findClosestSpanOfSegments(Node* nd, |
698 | 727 | continue; |
699 | 728 | } |
700 | 729 |
|
| 730 | + if (!checkMasterSymmetry(arch_, nd, r)) { |
| 731 | + continue; |
| 732 | + } |
| 733 | + |
701 | 734 | // Scan the segments in this row and look for segments in the required |
702 | 735 | // number of rows above and below that result in non-zero interval. |
703 | 736 | const int b = r; |
@@ -2193,6 +2226,11 @@ bool DetailedMgr::tryMove(Node* ndi, |
2193 | 2226 | { |
2194 | 2227 | // Based on the input, call an appropriate routine to try |
2195 | 2228 | // and generate a move. |
| 2229 | + if (!checkMasterSymmetry(arch_, ndi, segments_[sj]->getRowId())) { |
| 2230 | + rejectMove(); |
| 2231 | + return false; |
| 2232 | + } |
| 2233 | + |
2196 | 2234 | if (arch_->getCellHeightInRows(ndi) == 1) { |
2197 | 2235 | // Single height cell. |
2198 | 2236 | if (si != sj) { |
@@ -2227,6 +2265,10 @@ bool DetailedMgr::trySwap(Node* ndi, |
2227 | 2265 | const DbuY yj, |
2228 | 2266 | const int sj) |
2229 | 2267 | { |
| 2268 | + if (!checkMasterSymmetry(arch_, ndi, segments_[sj]->getRowId())) { |
| 2269 | + rejectMove(); |
| 2270 | + return false; |
| 2271 | + } |
2230 | 2272 | if (trySwap1(ndi, xi, yi, si, xj, yj, sj)) { |
2231 | 2273 | return verifyMove(); |
2232 | 2274 | } |
@@ -2702,6 +2744,10 @@ bool DetailedMgr::trySwap1(Node* ndi, |
2702 | 2744 | if (ndj == ndi || ndj == nullptr) { |
2703 | 2745 | return false; |
2704 | 2746 | } |
| 2747 | + if (!checkMasterSymmetry(arch_, ndj, segments_[si]->getRowId())) { |
| 2748 | + return false; |
| 2749 | + } |
| 2750 | + |
2705 | 2751 | if (arch_->getCellHeightInRows(ndi) != 1 |
2706 | 2752 | || arch_->getCellHeightInRows(ndj) != 1) { |
2707 | 2753 | return false; |
|
0 commit comments