Skip to content

Commit f23ef1e

Browse files
authored
Merge pull request The-OpenROAD-Project#9274 from rafaelmoresco/symmetry
dpl: add LEF symmetry to dpl and dpo
2 parents 49a3138 + dcd1c85 commit f23ef1e

File tree

5 files changed

+167
-88
lines changed

5 files changed

+167
-88
lines changed

src/dpl/include/dpl/Opendp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ class Opendp
198198
GridY y,
199199
GridX x_end,
200200
GridY y_end) const;
201+
bool checkMasterSym(unsigned masterSym, unsigned cellOri) const;
201202
bool shiftMove(Node* cell);
202203
bool mapMove(Node* cell);
203204
bool mapMove(Node* cell, const GridPt& grid_pt);

src/dpl/src/Place.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131
#include "odb/db.h"
3232
#include "odb/dbTransform.h"
3333
#include "odb/geom.h"
34+
#include "optimization/detailed_orient.h"
3435
#include "util/journal.h"
36+
#include "util/symmetry.h"
3537
#include "utl/Logger.h"
3638
// #define ODP_DEBUG
3739

@@ -55,6 +57,7 @@ std::string Opendp::printBgBox(
5557
queryBox.max_corner().x(),
5658
queryBox.max_corner().y());
5759
}
60+
5861
void Opendp::detailedPlacement()
5962
{
6063
if (debug_observer_) {
@@ -1011,9 +1014,41 @@ bool Opendp::checkPixels(const Node* cell,
10111014
}
10121015

10131016
const auto orient = grid_->getSiteOrientation(x, y, site).value();
1017+
1018+
// Check for symmetry
1019+
auto* dbMaster = cell->getDbInst()->getMaster();
1020+
unsigned masterSym = dpl::DetailedOrient::getMasterSymmetry(dbMaster);
1021+
if (!checkMasterSym(masterSym, orient)) {
1022+
return false;
1023+
}
1024+
10141025
return drc_engine_->checkDRC(cell, x, y, orient);
10151026
}
10161027

1028+
bool Opendp::checkMasterSym(unsigned masterSym, unsigned cellOri) const
1029+
{
1030+
using odb::dbOrientType;
1031+
switch (cellOri) {
1032+
case dbOrientType::R0:
1033+
return true;
1034+
case dbOrientType::MX:
1035+
return (masterSym & Symmetry_X) != 0;
1036+
case dbOrientType::MY:
1037+
return (masterSym & Symmetry_Y) != 0;
1038+
case dbOrientType::R180:
1039+
return (masterSym & Symmetry_X) && (masterSym & Symmetry_Y);
1040+
case dbOrientType::R90:
1041+
case dbOrientType::R270:
1042+
return (masterSym & Symmetry_ROT90) != 0;
1043+
case dbOrientType::MXR90:
1044+
case dbOrientType::MYR90:
1045+
return (masterSym & Symmetry_ROT90) && (masterSym & Symmetry_X)
1046+
&& (masterSym & Symmetry_Y);
1047+
default:
1048+
return false;
1049+
}
1050+
}
1051+
10171052
////////////////////////////////////////////////////////////////
10181053

10191054
// Legalize cell origin

src/dpl/src/optimization/detailed_manager.cxx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,33 @@
2424
#include "odb/dbTransform.h"
2525
#include "odb/geom.h"
2626
#include "util/journal.h"
27+
#include "util/symmetry.h"
2728
#include "util/utility.h"
2829
#include "utl/Logger.h"
2930

3031
using utl::DPL;
3132

3233
namespace dpl {
3334

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+
3454
DetailedMgr::DetailedMgr(Architecture* arch,
3555
Network* network,
3656
Grid* grid,
@@ -512,6 +532,9 @@ DetailedSeg* DetailedMgr::findClosestSegment(const Node* nd)
512532
if (nd->getGroupId() != curr->getRegId()) {
513533
continue;
514534
}
535+
if (!checkMasterSymmetry(arch_, nd, curr->getRowId())) {
536+
continue;
537+
}
515538

516539
// Work with left edge.
517540
const DbuX x1 = curr->getMinX();
@@ -551,6 +574,9 @@ DetailedSeg* DetailedMgr::findClosestSegment(const Node* nd)
551574
if (nd->getGroupId() != curr->getRegId()) {
552575
continue;
553576
}
577+
if (!checkMasterSymmetry(arch_, nd, curr->getRowId())) {
578+
continue;
579+
}
554580

555581
// Work with left edge.
556582
const DbuX x1 = curr->getMinX();
@@ -591,6 +617,9 @@ DetailedSeg* DetailedMgr::findClosestSegment(const Node* nd)
591617
if (nd->getGroupId() != curr->getRegId()) {
592618
continue;
593619
}
620+
if (!checkMasterSymmetry(arch_, nd, curr->getRowId())) {
621+
continue;
622+
}
594623

595624
// Work with left edge.
596625
const DbuX x1 = curr->getMinX();
@@ -698,6 +727,10 @@ bool DetailedMgr::findClosestSpanOfSegments(Node* nd,
698727
continue;
699728
}
700729

730+
if (!checkMasterSymmetry(arch_, nd, r)) {
731+
continue;
732+
}
733+
701734
// Scan the segments in this row and look for segments in the required
702735
// number of rows above and below that result in non-zero interval.
703736
const int b = r;
@@ -2193,6 +2226,11 @@ bool DetailedMgr::tryMove(Node* ndi,
21932226
{
21942227
// Based on the input, call an appropriate routine to try
21952228
// and generate a move.
2229+
if (!checkMasterSymmetry(arch_, ndi, segments_[sj]->getRowId())) {
2230+
rejectMove();
2231+
return false;
2232+
}
2233+
21962234
if (arch_->getCellHeightInRows(ndi) == 1) {
21972235
// Single height cell.
21982236
if (si != sj) {
@@ -2227,6 +2265,10 @@ bool DetailedMgr::trySwap(Node* ndi,
22272265
const DbuY yj,
22282266
const int sj)
22292267
{
2268+
if (!checkMasterSymmetry(arch_, ndi, segments_[sj]->getRowId())) {
2269+
rejectMove();
2270+
return false;
2271+
}
22302272
if (trySwap1(ndi, xi, yi, si, xj, yj, sj)) {
22312273
return verifyMove();
22322274
}
@@ -2702,6 +2744,10 @@ bool DetailedMgr::trySwap1(Node* ndi,
27022744
if (ndj == ndi || ndj == nullptr) {
27032745
return false;
27042746
}
2747+
if (!checkMasterSymmetry(arch_, ndj, segments_[si]->getRowId())) {
2748+
return false;
2749+
}
2750+
27052751
if (arch_->getCellHeightInRows(ndi) != 1
27062752
|| arch_->getCellHeightInRows(ndj) != 1) {
27072753
return false;

0 commit comments

Comments
 (0)