Skip to content

Commit

Permalink
Merge pull request The-OpenROAD-Project#6204 from The-OpenROAD-Projec…
Browse files Browse the repository at this point in the history
…t-staging/drt-support-width-table-orth

DRT: Support LEF58_WIDTHTABLE ORTHOGONAL constraint
  • Loading branch information
osamahammad21 authored Nov 26, 2024
2 parents 9658d57 + d0bbaa8 commit 75f3458
Show file tree
Hide file tree
Showing 13 changed files with 217 additions and 12 deletions.
8 changes: 8 additions & 0 deletions src/drt/src/db/gcObj/gcShape.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ class gcCorner : public gtl::point_data<frCoord>
frCornerTypeEnum getType() const { return cornerType_; }
frCornerDirEnum getDir() const { return cornerDir_; }
bool isFixed() const { return fixed_; }
bool hasPin() const { return pin_; }
gcPin* getPin() const { return pin_; }
frLayerNum getLayerNum() const { return layer_num_; }

// setters
void setPrevCorner(gcCorner* in) { prevCorner_ = in; }
Expand All @@ -85,8 +88,12 @@ class gcCorner : public gtl::point_data<frCoord>
void setType(frCornerTypeEnum in) { cornerType_ = in; }
void setDir(frCornerDirEnum in) { cornerDir_ = in; }
void setFixed(bool in) { fixed_ = in; }
void addToPin(gcPin* in) { pin_ = in; }
void removeFromPin() { pin_ = nullptr; }
void setLayerNum(const frLayerNum in) { layer_num_ = in; }

private:
gcPin* pin_{nullptr};
gcCorner* prevCorner_{nullptr};
gcCorner* nextCorner_{nullptr};
gcSegment* prevEdge_{nullptr};
Expand All @@ -95,6 +102,7 @@ class gcCorner : public gtl::point_data<frCoord>
// points away from poly for convex and concave
frCornerDirEnum cornerDir_{frCornerDirEnum::UNKNOWN};
bool fixed_{false};
frLayerNum layer_num_{-1};
};

class gcSegment : public gtl::segment_data<frCoord>, public gcShape
Expand Down
2 changes: 2 additions & 0 deletions src/drt/src/db/tech/frConstraint.cc
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ std::string frConstraint::getViolName() const
return "Lef58MaxSpacing";
case frConstraintTypeEnum::frcSpacingTableOrth:
return "SpacingTableOrth";
case frConstraintTypeEnum::frcLef58WidthTableOrth:
return "WidthTableOrth";
}
return "";
}
Expand Down
25 changes: 25 additions & 0 deletions src/drt/src/db/tech/frConstraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -2323,6 +2323,31 @@ class frLef58MaxSpacingConstraint : public frConstraint
int cut_class_idx_{-1};
};

class frLef58WidthTableOrthConstraint : public frConstraint
{
public:
frLef58WidthTableOrthConstraint(const frCoord horz_spc,
const frCoord vert_spc)
: horz_spc_(horz_spc), vert_spc_(vert_spc)
{
}
frCoord getHorzSpc() const { return horz_spc_; }
frCoord getVertSpc() const { return vert_spc_; }
void report(utl::Logger* logger) const override
{
logger->report("LEF58_WIDTHTABLE ORTH");
}
// typeId
frConstraintTypeEnum typeId() const override
{
return frConstraintTypeEnum::frcLef58WidthTableOrth;
}

private:
frCoord horz_spc_;
frCoord vert_spc_;
};

class frNonDefaultRule
{
public:
Expand Down
10 changes: 10 additions & 0 deletions src/drt/src/db/tech/frLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,15 @@ class frLayer

void printAllConstraints(utl::Logger* logger);

void setWidthTblOrthCon(frLef58WidthTableOrthConstraint* con)
{
width_tbl_orth_con_ = con;
}
frLef58WidthTableOrthConstraint* getWidthTblOrthCon() const
{
return width_tbl_orth_con_;
}

protected:
odb::dbTechLayer* db_layer_{nullptr};
bool fakeCut_{false};
Expand Down Expand Up @@ -929,6 +938,7 @@ class frLayer

frOrthSpacingTableConstraint* spc_tbl_orth_con_{nullptr};
drEolSpacingConstraint drEolCon_;
frLef58WidthTableOrthConstraint* width_tbl_orth_con_{nullptr};

friend class io::Parser;
};
Expand Down
2 changes: 2 additions & 0 deletions src/drt/src/frBaseTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,8 @@ std::ostream& operator<<(std::ostream& os, frConstraintTypeEnum type)
return os << "frcLef58MaxSpacingConstraint";
case frConstraintTypeEnum::frcSpacingTableOrth:
return os << "frcSpacingTableOrth";
case frConstraintTypeEnum::frcLef58WidthTableOrth:
return os << "frcLef58WidthTableOrth";
}
return os << "Bad frConstraintTypeEnum";
}
Expand Down
3 changes: 2 additions & 1 deletion src/drt/src/frBaseTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,8 @@ enum class frConstraintTypeEnum
frcLef58EnclosureConstraint,
frcSpacingRangeConstraint,
frcLef58MaxSpacingConstraint,
frcSpacingTableOrth
frcSpacingTableOrth,
frcLef58WidthTableOrth
};

std::ostream& operator<<(std::ostream& os, frConstraintTypeEnum type);
Expand Down
6 changes: 4 additions & 2 deletions src/drt/src/gc/FlexGC_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,8 @@ class FlexGCWorker::Impl
gcRect* rect,
frLef58TwoWiresForbiddenSpcConstraint* con);
box_t checkMetalCornerSpacing_getQueryBox(gcCorner* corner,
frCoord& maxSpcValX,
frCoord& maxSpcValY);
frCoord maxSpcValX,
frCoord maxSpcValY);
void checkMetalCornerSpacing();
void checkMetalCornerSpacing_getMaxSpcVal(frLayerNum layerNum,
frCoord& maxSpcValX,
Expand All @@ -307,6 +307,8 @@ class FlexGCWorker::Impl
gcRect* rect,
frLef58CornerSpacingConstraint* con);

void checkWidthTableOrth(gcCorner* corner);
void checkWidthTableOrth_main(gcCorner* corner1, gcCorner* corner2);
void checkMetalShape(bool allow_patching = false);
void checkMetalShape_main(gcPin* pin, bool allow_patching);
void checkMetalShape_minWidth(const gtl::rectangle_data<frCoord>& rect,
Expand Down
2 changes: 2 additions & 0 deletions src/drt/src/gc/FlexGC_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -759,8 +759,10 @@ void FlexGCWorker::Impl::initNet_pins_polygonCorners_helper(gcNet* net,
prevEdge->setHighCorner(currCorner);
nextEdge->setLowCorner(currCorner);
// set currCorner attributes
currCorner->addToPin(pin);
currCorner->setPrevEdge(prevEdge);
currCorner->setNextEdge(nextEdge.get());
currCorner->setLayerNum(layerNum);
currCorner->x(prevEdge->high().x());
currCorner->y(prevEdge->high().y());
int orient = gtl::orientation(*prevEdge, *nextEdge);
Expand Down
102 changes: 93 additions & 9 deletions src/drt/src/gc/FlexGC_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,12 @@ bool FlexGCWorker::Impl::isOppositeDir(gcCorner* corner, gcSegment* seg)

box_t FlexGCWorker::Impl::checkMetalCornerSpacing_getQueryBox(
gcCorner* corner,
frCoord& maxSpcValX,
frCoord& maxSpcValY)
const frCoord maxSpcValX,
const frCoord maxSpcValY)
{
box_t queryBox;
frCoord baseX = corner->getNextEdge()->low().x();
frCoord baseY = corner->getNextEdge()->low().y();
frCoord baseX = corner->x();
frCoord baseY = corner->y();
frCoord llx = baseX;
frCoord lly = baseY;
frCoord urx = baseX;
Expand Down Expand Up @@ -1384,14 +1384,20 @@ void FlexGCWorker::Impl::checkMetalCornerSpacing()
i++) {
auto currLayer = getTech()->getLayer(i);
if (currLayer->getType() != dbTechLayerType::ROUTING
|| !currLayer->hasLef58CornerSpacingConstraint()) {
|| (!currLayer->hasLef58CornerSpacingConstraint()
&& currLayer->getWidthTblOrthCon() == nullptr)) {
continue;
}
for (auto& pin : targetNet_->getPins(i)) {
for (auto& corners : pin->getPolygonCorners()) {
for (auto& corner : corners) {
// LEF58 corner spacing
checkMetalCornerSpacing_main(corner.get());
if (currLayer->hasLef58CornerSpacingConstraint()) {
checkMetalCornerSpacing_main(corner.get());
}
if (currLayer->getWidthTblOrthCon()) {
checkWidthTableOrth(corner.get());
}
}
}
}
Expand All @@ -1405,15 +1411,21 @@ void FlexGCWorker::Impl::checkMetalCornerSpacing()
i++) {
auto currLayer = getTech()->getLayer(i);
if (currLayer->getType() != dbTechLayerType::ROUTING
|| !currLayer->hasLef58CornerSpacingConstraint()) {
|| (!currLayer->hasLef58CornerSpacingConstraint()
&& currLayer->getWidthTblOrthCon() == nullptr)) {
continue;
}
for (auto& net : getNets()) {
for (auto& pin : net->getPins(i)) {
for (auto& corners : pin->getPolygonCorners()) {
for (auto& corner : corners) {
// LEF58 corner spacing
checkMetalCornerSpacing_main(corner.get());
if (currLayer->hasLef58CornerSpacingConstraint()) {
checkMetalCornerSpacing_main(corner.get());
}
if (currLayer->getWidthTblOrthCon()) {
checkWidthTableOrth(corner.get());
}
}
}
}
Expand All @@ -1422,6 +1434,78 @@ void FlexGCWorker::Impl::checkMetalCornerSpacing()
}
}

void FlexGCWorker::Impl::checkWidthTableOrth_main(gcCorner* corner1,
gcCorner* corner2)
{
if (corner2 == nullptr) {
return;
}
if (corner1 == corner2) {
return;
}
if (corner2->getType() != frCornerTypeEnum::CONCAVE) {
return;
}
if (corner1->isFixed() && corner2->isFixed()) {
return;
}
const auto layer_num = corner1->getLayerNum();
const auto layer = getTech()->getLayer(layer_num);
const auto con = layer->getWidthTblOrthCon();
const frCoord horz_spc = con->getHorzSpc();
const frCoord vert_spc = con->getVertSpc();

Rect marker_rect(corner1->x(), corner1->y(), corner2->x(), corner2->y());
if (marker_rect.dx() >= horz_spc || marker_rect.dy() >= vert_spc) {
return;
}
const auto owner = corner1->getPin()->getNet()->getOwner();
auto marker = std::make_unique<frMarker>();
marker->setBBox(marker_rect);
marker->setLayerNum(layer_num);
marker->setConstraint(con);
marker->addSrc(owner);
marker->addVictim(
owner,
std::make_tuple(
layer_num,
Rect(corner1->x(), corner1->y(), corner1->x(), corner1->y()),
corner1->isFixed()));
marker->addAggressor(
owner,
std::make_tuple(
layer_num,
Rect(corner2->x(), corner2->y(), corner2->x(), corner2->y()),
corner2->isFixed()));
addMarker(std::move(marker));
}

void FlexGCWorker::Impl::checkWidthTableOrth(gcCorner* corner)
{
// applied only to inside corners (CONCAVE)
if (corner->getType() != frCornerTypeEnum::CONCAVE) {
return;
}
auto layer_num = corner->getLayerNum();
auto layer = getTech()->getLayer(layer_num);
auto con = layer->getWidthTblOrthCon();
const frCoord horz_spc = con->getHorzSpc();
const frCoord vert_spc = con->getVertSpc();
Rect query_rect(corner->x() - horz_spc,
corner->y() - vert_spc,
corner->x() + horz_spc,
corner->y() + vert_spc);
std::vector<std::pair<segment_t, gcSegment*>> result;
getWorkerRegionQuery().queryPolygonEdge(query_rect, layer_num, result);
for (auto [_, edge] : result) {
if (edge->getPin() != corner->getPin()) {
continue;
}
checkWidthTableOrth_main(corner, edge->getLowCorner());
checkWidthTableOrth_main(corner, edge->getHighCorner());
}
}

void FlexGCWorker::Impl::checkMetalShape_minWidth(
const gtl::rectangle_data<frCoord>& rect,
frLayerNum layerNum,
Expand Down Expand Up @@ -4128,7 +4212,7 @@ int FlexGCWorker::Impl::main()
}
// clear existing markers
clearMarkers();
// check LEF58CornerSpacing
// check LEF58CornerSpacing and LEF58WidthTable ORTH
checkMetalCornerSpacing();
// check Short, NSMet, MetSpc based on max rectangles
checkMetalSpacing();
Expand Down
26 changes: 26 additions & 0 deletions src/drt/src/io/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1665,6 +1665,32 @@ void io::Parser::setRoutingLayerProperties(odb::dbTechLayer* layer,
tmpLayer->addForbiddenSpacingConstraint(con.get());
getTech()->addUConstraint(std::move(con));
}
if (!layer->getTechLayerWidthTableRules().empty()) {
frUInt4 width = 0;
frUInt4 wrongway_width = 0;
for (auto rule : layer->getTechLayerWidthTableRules()) {
if (!rule->isOrthogonal()) {
continue;
}
if (rule->isWrongDirection()) {
wrongway_width = rule->getWidthTable().at(0);
} else {
width = rule->getWidthTable().at(0);
}
}
if (wrongway_width == 0) {
wrongway_width = width;
}
if (width != 0 || wrongway_width != 0) {
const bool is_horz = tmpLayer->isHorizontal();
const frCoord horz_spc = is_horz ? wrongway_width : width;
const frCoord vert_spc = is_horz ? width : wrongway_width;
auto ucon = std::make_unique<frLef58WidthTableOrthConstraint>(horz_spc,
vert_spc);
tmpLayer->setWidthTblOrthCon(ucon.get());
getTech()->addUConstraint(std::move(ucon));
}
}
}

void io::Parser::setCutLayerProperties(odb::dbTechLayer* layer,
Expand Down
15 changes: 15 additions & 0 deletions src/drt/test/fixture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,21 @@ frSpacingTableTwConstraint* Fixture::makeSpacingTableTwConstraint(
return rptr;
}

frLef58WidthTableOrthConstraint* Fixture::makeWidthTblOrthConstraint(
frLayerNum layer_num,
frCoord horz_spc,
frCoord vert_spc)
{
frTechObject* tech = design->getTech();
frLayer* layer = tech->getLayer(layer_num);
std::unique_ptr<frConstraint> uCon
= std::make_unique<frLef58WidthTableOrthConstraint>(horz_spc, vert_spc);
auto rptr = static_cast<frLef58WidthTableOrthConstraint*>(uCon.get());
tech->addUConstraint(std::move(uCon));
layer->setWidthTblOrthCon(rptr);
return rptr;
}

void Fixture::makeLef58EolKeepOutConstraint(frLayerNum layer_num,
bool cornerOnly,
bool exceptWithin,
Expand Down
5 changes: 5 additions & 0 deletions src/drt/test/fixture.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,11 @@ class Fixture
std::vector<frCoord> widthTbl,
std::vector<frCoord> prlTbl,
std::vector<std::vector<frCoord>> spacingTbl);

frLef58WidthTableOrthConstraint* makeWidthTblOrthConstraint(
frLayerNum layer_num,
frCoord horz_spc,
frCoord vert_spc);
void initRegionQuery();
frLef58CutSpacingConstraint* makeLef58CutSpacingConstraint_parallelOverlap(
frLayerNum layer_num,
Expand Down
23 changes: 23 additions & 0 deletions src/drt/test/gcTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1496,6 +1496,29 @@ BOOST_DATA_TEST_CASE(cut_spc_tbl_orth,
}
}

BOOST_DATA_TEST_CASE(width_tbl_orth,
(bdata::make({40, 50, 60}) * bdata::make({40, 50, 60})),
horz_spc,
vert_spc)
{
makeWidthTblOrthConstraint(2, horz_spc, vert_spc);
design->getTech()->getLayer(2)->setMinWidth(
10); // to ignore NSMetal violations
frNet* n1 = makeNet("n1");
makePathseg(n1, 2, {0, 100}, {200, 100}, 100);
makePathseg(n1, 2, {150, 50}, {350, 50}, 100);
const frCoord dx = 50;
const frCoord dy = 50;
const bool violating = dx < horz_spc && dy < vert_spc;
runGC();
auto& markers = worker.getMarkers();
if (violating) {
BOOST_TEST(markers.size() == 1);
} else {
BOOST_TEST(markers.size() == 0);
}
}

BOOST_AUTO_TEST_SUITE_END();

} // namespace drt

0 comments on commit 75f3458

Please sign in to comment.