Skip to content

Commit

Permalink
Merge pull request #5287 from The-OpenROAD-Project-staging/TR-maxspacing
Browse files Browse the repository at this point in the history
Add support to LEF58_MAXSPACING in ODB and DRT
  • Loading branch information
maliberty authored Aug 6, 2024
2 parents 16ee4c3 + b40dfbc commit 28f8d02
Show file tree
Hide file tree
Showing 53 changed files with 1,404 additions and 271 deletions.
1 change: 1 addition & 0 deletions src/drt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ target_sources(drt
src/db/drObj/drVia.cpp
src/db/infra/frTime_helper.cpp
src/db/infra/frTime.cpp
src/db/infra/KDTree.cpp
src/db/taObj/taShape.cpp
src/db/obj/frShape.cpp
src/db/obj/frInst.cpp
Expand Down
1 change: 1 addition & 0 deletions src/drt/include/triton_route/TritonRoute.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ class TritonRoute
void prep();
void processBTermsAboveTopLayer(bool has_routing = false);
odb::dbDatabase* getDb() const { return db_; }
void fixMaxSpacing();

private:
std::unique_ptr<frDesign> design_;
Expand Down
12 changes: 12 additions & 0 deletions src/drt/src/TritonRoute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,18 @@ void TritonRoute::pinAccess(const std::vector<odb::dbInst*>& target_insts)
writer.updateDb(db_, true);
}

void TritonRoute::fixMaxSpacing()
{
initDesign();
initGuide();
prep();
dr_ = std::make_unique<FlexDR>(this, getDesign(), logger_, db_);
dr_->init();
dr_->fixMaxSpacing();
io::Writer writer(this, logger_);
writer.updateDb(db_);
}

void TritonRoute::getDRCMarkers(frList<std::unique_ptr<frMarker>>& markers,
const Rect& requiredDrcBox)
{
Expand Down
6 changes: 5 additions & 1 deletion src/drt/src/TritonRoute.i
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,11 @@ void detailed_route_step_drt(int size,
workerMarkerCost, workerFixedShapeCost,
workerMarkerDecay, ripupMode, followGuide);
}

void fix_max_spacing_cmd()
{
auto* router = ord::OpenRoad::openRoad()->getTritonRoute();
router->fixMaxSpacing();
}
void step_end()
{
auto* router = ord::OpenRoad::openRoad()->getTritonRoute();
Expand Down
5 changes: 5 additions & 0 deletions src/drt/src/TritonRoute.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -496,4 +496,9 @@ proc check_drc { args } {
drt::check_drc_cmd $output_file $x1 $y1 $x2 $y2
}

proc fix_max_spacing { args } {
sta::check_argc_eq0 "fix_max_spacing" $args
drt::fix_max_spacing_cmd
}

}
3 changes: 2 additions & 1 deletion src/drt/src/db/drObj/drVia.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ drVia::drVia(const frVia& in)
viaDef_(in.getViaDef()),
tapered_(in.isTapered()),
bottomConnected_(in.isBottomConnected()),
topConnected_(in.isTopConnected())
topConnected_(in.isTopConnected()),
isLonely_(in.isLonely())
{
}

Expand Down
3 changes: 3 additions & 0 deletions src/drt/src/db/drObj/drVia.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ class drVia : public drRef
bool isTopConnected() const { return topConnected_; }
void setBottomConnected(bool c) { bottomConnected_ = c; }
void setTopConnected(bool c) { topConnected_ = c; }
void setIsLonely(bool in) { isLonely_ = in; }
bool isLonely() const { return isLonely_; }

protected:
Point origin_;
Expand All @@ -170,6 +172,7 @@ class drVia : public drRef
bool tapered_{false};
bool bottomConnected_{false};
bool topConnected_{false};
bool isLonely_{false};

template <class Archive>
void serialize(Archive& ar, unsigned int version);
Expand Down
131 changes: 131 additions & 0 deletions src/drt/src/db/infra/KDTree.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2024, Precision Innovations Inc.
// All rights reserved.
//
// BSD 3-Clause License
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
///////////////////////////////////////////////////////////////////////////////

#include "KDTree.hpp"

#include <algorithm>
#include <cmath>
using odb::horizontal;
namespace drt {
KDTree::KDTree(const std::vector<Point>& points)
{
std::vector<std::pair<int, Point>> points_with_ids;
points_with_ids.reserve(points.size());
for (int i = 0; i < points.size(); ++i) {
points_with_ids.emplace_back(i, points[i]);
}
root_ = buildTree(points_with_ids, horizontal);
}

std::unique_ptr<KDTreeNode> KDTree::buildTree(
const std::vector<std::pair<int, Point>>& points,
const Orientation2D& orient)
{
if (points.empty()) {
return nullptr;
}

auto sorted_points = points;
std::sort(
sorted_points.begin(),
sorted_points.end(),
[orient](const std::pair<int, Point>& a, const std::pair<int, Point>& b) {
return orient == horizontal ? a.second.x() < b.second.x()
: a.second.y() < b.second.y();
});

const size_t median_index = sorted_points.size() / 2;
std::unique_ptr<KDTreeNode> node = std::make_unique<KDTreeNode>(
sorted_points[median_index].first, sorted_points[median_index].second);

std::vector<std::pair<int, Point>> left_points(
sorted_points.begin(), sorted_points.begin() + median_index);
std::vector<std::pair<int, Point>> right_points(
sorted_points.begin() + median_index + 1, sorted_points.end());
const auto next_orient = orient.turn_90();
node->left = buildTree(left_points, next_orient);
node->right = buildTree(right_points, next_orient);

return node;
}

std::vector<int> KDTree::radiusSearch(const Point& target, int radius) const
{
std::vector<int> result;
const frSquaredDistance radius_square
= radius * static_cast<frSquaredDistance>(radius);
radiusSearchHelper(root_.get(), target, radius_square, horizontal, result);
return result;
}

void KDTree::radiusSearchHelper(KDTreeNode* node,
const Point& target,
const frSquaredDistance radius_square,
const Orientation2D& orient,
std::vector<int>& result) const
{
if (!node) {
return;
}
const frCoord dx = target.x() - node->point.x();
const frCoord dy = target.y() - node->point.y();
const frSquaredDistance distance_square
= dx * static_cast<frSquaredDistance>(dx)
+ dy * static_cast<frSquaredDistance>(dy);
if (distance_square <= radius_square) {
result.push_back(node->id);
}

const frCoord diff = (orient == horizontal) ? dx : dy;
const frSquaredDistance diff_square
= diff * static_cast<frSquaredDistance>(diff);

const auto next_orient = orient.turn_90();

if (diff < 0) {
radiusSearchHelper(
node->left.get(), target, radius_square, next_orient, result);
if (diff_square <= radius_square) {
radiusSearchHelper(
node->right.get(), target, radius_square, next_orient, result);
}
} else {
radiusSearchHelper(
node->right.get(), target, radius_square, next_orient, result);
if (diff_square <= radius_square) {
radiusSearchHelper(
node->left.get(), target, radius_square, next_orient, result);
}
}
}
} // namespace drt
78 changes: 78 additions & 0 deletions src/drt/src/db/infra/KDTree.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2024, Precision Innovations Inc.
// All rights reserved.
//
// BSD 3-Clause License
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
///////////////////////////////////////////////////////////////////////////////

#pragma once

#include <memory>
#include <vector>

#include "frBaseTypes.h"
#include "odb/geom.h"

using odb::Orientation2D;
using odb::Point;
namespace drt {

struct KDTreeNode
{
int id;
Point point;
std::unique_ptr<KDTreeNode> left;
std::unique_ptr<KDTreeNode> right;

KDTreeNode(const int idIn, const Point& pt) : id(idIn), point(pt) {}
};

class KDTree
{
public:
KDTree(const std::vector<Point>& points);

~KDTree() = default;

std::vector<int> radiusSearch(const Point& target, int radius) const;

private:
std::unique_ptr<KDTreeNode> buildTree(
const std::vector<std::pair<int, Point>>& points,
const Orientation2D& orient);

void radiusSearchHelper(KDTreeNode* node,
const Point& target,
const frSquaredDistance radius_square,
const Orientation2D& orient,
std::vector<int>& result) const;

std::unique_ptr<KDTreeNode> root_;
};
} // namespace drt
1 change: 1 addition & 0 deletions src/drt/src/db/obj/frVia.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ frVia::frVia(const drVia& in)
setTapered(in.isTapered());
setBottomConnected(in.isBottomConnected());
setTopConnected(in.isTopConnected());
setIsLonely(in.isLonely());
}

template <class Archive>
Expand Down
6 changes: 5 additions & 1 deletion src/drt/src/db/obj/frVia.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ class frVia : public frRef
owner_(in.owner_),
tapered_(in.tapered_),
bottomConnected_(in.bottomConnected_),
topConnected_(in.topConnected_)
topConnected_(in.topConnected_),
isLonely_(in.isLonely_)
{
}
frVia(const drVia& in);
Expand Down Expand Up @@ -228,6 +229,8 @@ class frVia : public frRef
void setTopConnected(bool c) { topConnected_ = c; }
void setIndexInOwner(int idx) { index_in_owner_ = idx; }
int getIndexInOwner() const { return index_in_owner_; }
void setIsLonely(bool in) { isLonely_ = in; }
bool isLonely() const { return isLonely_; }

private:
Point origin_;
Expand All @@ -238,6 +241,7 @@ class frVia : public frRef
bool tapered_{false};
bool bottomConnected_{false};
bool topConnected_{false};
bool isLonely_{false};

template <class Archive>
void serialize(Archive& ar, unsigned int version);
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 @@ -160,6 +160,8 @@ std::string frConstraint::getViolName() const
return "ForbiddenSpc";
case frConstraintTypeEnum::frcLef58EnclosureConstraint:
return "Lef58Enclosure";
case frConstraintTypeEnum::frcLef58MaxSpacingConstraint:
return "Lef58MaxSpacing";
}
return "";
}
Expand Down
37 changes: 37 additions & 0 deletions src/drt/src/db/tech/frConstraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -2247,6 +2247,14 @@ class frLef58EnclosureConstraint : public frConstraint
&& sideOverhang >= db_rule_->getFirstOverhang());
}
frCoord getWidth() const { return db_rule_->getMinWidth(); }
bool isEol() const
{
return db_rule_->getType() == odb::dbTechLayerCutEnclosureRule::EOL;
}
bool isEolOnly() const { return db_rule_->isEolOnly(); }
frCoord getFirstOverhang() const { return db_rule_->getFirstOverhang(); }
frCoord getSecondOverhang() const { return db_rule_->getSecondOverhang(); }
frCoord getEolLength() const { return db_rule_->getEolWidth(); }
void report(utl::Logger* logger) const override
{
logger->report("LEF58_ENCLOSURE");
Expand All @@ -2261,6 +2269,35 @@ class frLef58EnclosureConstraint : public frConstraint
int cut_class_idx_;
};

// LEF58_MAXSPACING rule
class frLef58MaxSpacingConstraint : public frConstraint
{
public:
frLef58MaxSpacingConstraint(odb::dbTechLayerMaxSpacingRule* ruleIn)
: db_rule_(ruleIn)
{
}
void setCutClassIdx(int in) { cut_class_idx_ = in; }
int getCutClassIdx() const { return cut_class_idx_; }
frCoord getMaxSpacing() const { return db_rule_->getMaxSpacing(); }
std::string getCutClass() const { return db_rule_->getCutClass(); }
bool hasCutClass() const { return db_rule_->hasCutClass(); }

void report(utl::Logger* logger) const override
{
logger->report("LEF58_MAXSPACING");
}
// typeId
frConstraintTypeEnum typeId() const override
{
return frConstraintTypeEnum::frcLef58MaxSpacingConstraint;
}

private:
odb::dbTechLayerMaxSpacingRule* db_rule_{nullptr};
int cut_class_idx_{-1};
};

class frNonDefaultRule
{
public:
Expand Down
Loading

0 comments on commit 28f8d02

Please sign in to comment.