Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRT: Support LEF58_WIDTHTABLE ORTHOGONAL constraint #6204

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
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
31 changes: 31 additions & 0 deletions src/drt/src/io/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1665,6 +1665,37 @@ 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 frCoord horz_spc
= layer->getDirection() == odb::dbTechLayerDir::HORIZONTAL
? wrongway_width
: width;
const frCoord vert_spc
= layer->getDirection() == odb::dbTechLayerDir::HORIZONTAL
? width
: wrongway_width;
Comment on lines +1685 to +1692
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const frCoord horz_spc
= layer->getDirection() == odb::dbTechLayerDir::HORIZONTAL
? wrongway_width
: width;
const frCoord vert_spc
= layer->getDirection() == odb::dbTechLayerDir::HORIZONTAL
? width
: wrongway_width;
const bool isH = layer->getDirection() == odb::dbTechLayerDir::HORIZONTAL;
const frCoord horz_spc = isH ? wrongway_width : width;
const frCoord vert_spc = isH ? 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
Loading