Skip to content

Commit 4fa65c3

Browse files
authored
Merge pull request #8360 from The-OpenROAD-Project-staging/cts-ndr-spacing-fix
cts: fix spacing extraction for layers with no default spacing defined
2 parents 9dcbceb + a6bd4ff commit 4fa65c3

File tree

2 files changed

+56
-3
lines changed

2 files changed

+56
-3
lines changed

src/cts/include/cts/TritonCTS.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ class TritonCTS
119119
void writeClockNetsToDb(TreeBuilder* builder,
120120
std::set<odb::dbNet*>& clkLeafNets);
121121
void writeClockNDRsToDb(TreeBuilder* builder);
122+
int getNetSpacing(odb::dbTechLayer* layer, int width1, int width2);
122123
void incrementNumClocks() { ++numberOfClocks_; }
123124
void clearNumClocks() { numberOfClocks_ = 0; }
124125
unsigned getNumClocks() const { return numberOfClocks_; }

src/cts/src/TritonCTS.cpp

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <ctime>
1212
#include <fstream>
1313
#include <functional>
14+
#include <iostream>
1415
#include <limits>
1516
#include <map>
1617
#include <memory>
@@ -1674,6 +1675,41 @@ int TritonCTS::applyNDRToFirstHalfLevels(Clock& clockNet,
16741675
return applyNDRToClockLevels(clockNet, clockNDR, firstHalfLevels);
16751676
}
16761677

1678+
// Priority for minSpc rule is SPACINGTABLE TWOWIDTHS > SPACINGTABLE PRL >
1679+
// SPACING
1680+
int TritonCTS::getNetSpacing(odb::dbTechLayer* layer,
1681+
const int width1,
1682+
const int width2)
1683+
{
1684+
int min_spc = 0;
1685+
if (layer->hasTwoWidthsSpacingRules()) {
1686+
min_spc = layer->findTwSpacing(width1, width2, 0);
1687+
} else if (layer->hasV55SpacingRules()) {
1688+
min_spc = layer->findV55Spacing(std::max(width1, width2), 0);
1689+
} else if (!layer->getV54SpacingRules().empty()) {
1690+
for (auto rule : layer->getV54SpacingRules()) {
1691+
if (rule->hasRange()) {
1692+
uint rmin;
1693+
uint rmax;
1694+
rule->getRange(rmin, rmax);
1695+
if (width1 < rmin || width2 > rmax) {
1696+
continue;
1697+
}
1698+
}
1699+
min_spc = std::max<int>(min_spc, rule->getSpacing());
1700+
}
1701+
} else {
1702+
min_spc = layer->getSpacing();
1703+
}
1704+
1705+
// Last resort, get pitch - minWidth
1706+
if (min_spc == 0) {
1707+
min_spc = layer->getPitch() - layer->getMinWidth();
1708+
}
1709+
1710+
return min_spc;
1711+
}
1712+
16771713
void TritonCTS::writeClockNDRsToDb(TreeBuilder* builder)
16781714
{
16791715
char ruleName[64];
@@ -1700,10 +1736,26 @@ void TritonCTS::writeClockNDRsToDb(TreeBuilder* builder)
17001736
layerRule = odb::dbTechLayerRule::create(clockNDR, layer);
17011737
}
17021738
assert(layerRule != nullptr);
1703-
int defaultSpace = layer->getSpacing();
1739+
17041740
int defaultWidth = layer->getWidth();
1705-
layerRule->setSpacing(defaultSpace * 2);
1706-
layerRule->setWidth(defaultWidth);
1741+
int defaultSpace = getNetSpacing(layer, defaultWidth, defaultWidth);
1742+
1743+
// If width or space is 0, something is not right
1744+
if (defaultWidth == 0 || defaultSpace == 0) {
1745+
logger_->warn(CTS,
1746+
208,
1747+
"Clock NDR settings for layer {}: defaultSpace: {} - "
1748+
"defaultWidth: {}",
1749+
layer->getName(),
1750+
defaultSpace,
1751+
defaultWidth);
1752+
}
1753+
1754+
// Set NDR settings
1755+
int ndr_width = defaultWidth;
1756+
layerRule->setWidth(ndr_width);
1757+
int ndr_space = 2 * getNetSpacing(layer, ndr_width, ndr_width);
1758+
layerRule->setSpacing(ndr_space);
17071759

17081760
debugPrint(logger_,
17091761
CTS,

0 commit comments

Comments
 (0)