Skip to content

Commit 53ec684

Browse files
authored
Merge pull request #10497 from The-OpenROAD-Project-staging/cts-ndr-spacing-fix
CTS: clock NDR spacing fix
2 parents 184f1c1 + 1b8ec38 commit 53ec684

11 files changed

Lines changed: 705 additions & 337 deletions

src/cts/include/cts/TritonCTS.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@ class TritonCTS
117117
void writeClockNetsToDb(TreeBuilder* builder,
118118
odb::PtrSet<odb::dbNet>& clkLeafNets);
119119
void writeClockNDRsToDb(TreeBuilder* builder);
120-
int getNetSpacing(odb::dbTechLayer* layer, int width1, int width2);
121120
void incrementNumClocks() { ++numberOfClocks_; }
122121
void clearNumClocks() { numberOfClocks_ = 0; }
123122
unsigned getNumClocks() const { return numberOfClocks_; }

src/cts/src/TritonCTS.cpp

Lines changed: 21 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1837,10 +1837,9 @@ int TritonCTS::applyNDRToClockLevels(Clock& clockNet,
18371837
{
18381838
int ndrAppliedNets = 0;
18391839

1840-
debugPrint(
1841-
logger_, CTS, "clustering", 1, "Applying NDR to clock tree levels: ");
1840+
debugPrint(logger_, CTS, "ndr", 1, "Applying NDR to clock tree levels: ");
18421841
for (int level : targetLevels) {
1843-
debugPrint(logger_, CTS, "clustering", 1, "{} ", level);
1842+
debugPrint(logger_, CTS, "ndr", 1, "{} ", level);
18441843
}
18451844

18461845
// Check if the main clock net (level 0) is in the level list
@@ -1849,7 +1848,7 @@ int TritonCTS::applyNDRToClockLevels(Clock& clockNet,
18491848
clk_net->setNonDefaultRule(clockNDR);
18501849
ndrAppliedNets++;
18511850
// clang-format off
1852-
debugPrint(logger_, CTS, "clustering", 1,
1851+
debugPrint(logger_, CTS, "ndr", 1,
18531852
"Applied NDR to: {} (level {})", clockNet.getName(), 0);
18541853
// clang-format on
18551854
}
@@ -1864,7 +1863,7 @@ int TritonCTS::applyNDRToClockLevels(Clock& clockNet,
18641863
ndrAppliedNets++;
18651864
std::string net_name = net->getName();
18661865
// clang-format off
1867-
debugPrint(logger_, CTS, "clustering", 1,
1866+
debugPrint(logger_, CTS, "ndr", 1,
18681867
"Applied NDR to: {} (level {})", net_name, level);
18691868
// clang-format on
18701869
}
@@ -1903,49 +1902,14 @@ int TritonCTS::applyNDRToFirstHalfLevels(Clock& clockNet,
19031902
allLevels.begin() + halfCount);
19041903

19051904
// clang-format off
1906-
debugPrint(logger_, CTS, "clustering", 1, "Total clock tree levels found: {}"
1905+
debugPrint(logger_, CTS, "ndr", 1, "Total clock tree levels found: {}"
19071906
" Applying NDR to first {} levels", allLevels.size(), halfCount);
19081907
// clang-format on
19091908

19101909
// Apply NDR to the first half
19111910
return applyNDRToClockLevels(clockNet, clockNDR, firstHalfLevels);
19121911
}
19131912

1914-
// Priority for minSpc rule is SPACINGTABLE TWOWIDTHS > SPACINGTABLE PRL >
1915-
// SPACING
1916-
int TritonCTS::getNetSpacing(odb::dbTechLayer* layer,
1917-
const int width1,
1918-
const int width2)
1919-
{
1920-
int min_spc = 0;
1921-
if (layer->hasTwoWidthsSpacingRules()) {
1922-
min_spc = layer->findTwSpacing(width1, width2, 0);
1923-
} else if (layer->hasV55SpacingRules()) {
1924-
min_spc = layer->findV55Spacing(std::max(width1, width2), 0);
1925-
} else if (!layer->getV54SpacingRules().empty()) {
1926-
for (auto rule : layer->getV54SpacingRules()) {
1927-
if (rule->hasRange()) {
1928-
uint32_t rmin;
1929-
uint32_t rmax;
1930-
rule->getRange(rmin, rmax);
1931-
if (width1 < rmin || width2 > rmax) {
1932-
continue;
1933-
}
1934-
}
1935-
min_spc = std::max<int>(min_spc, rule->getSpacing());
1936-
}
1937-
} else {
1938-
min_spc = layer->getSpacing();
1939-
}
1940-
1941-
// Last resort, get pitch - minWidth
1942-
if (min_spc == 0) {
1943-
min_spc = layer->getPitch() - layer->getMinWidth();
1944-
}
1945-
1946-
return min_spc;
1947-
}
1948-
19491913
void TritonCTS::writeClockNDRsToDb(TreeBuilder* builder)
19501914
{
19511915
char ruleName[64];
@@ -1973,38 +1937,38 @@ void TritonCTS::writeClockNDRsToDb(TreeBuilder* builder)
19731937
}
19741938
assert(layerRule != nullptr);
19751939

1976-
int defaultWidth = layer->getWidth();
1977-
int defaultSpace = getNetSpacing(layer, defaultWidth, defaultWidth);
1940+
const int default_width = layer->getWidth();
1941+
const int default_space = layer->getPitch() - default_width;
19781942

19791943
// If width or space is 0, something is not right
1980-
if (defaultWidth == 0 || defaultSpace == 0) {
1981-
logger_->warn(CTS,
1982-
208,
1983-
"Clock NDR settings for layer {}: defaultSpace: {} - "
1984-
"defaultWidth: {}",
1985-
layer->getName(),
1986-
defaultSpace,
1987-
defaultWidth);
1944+
if (default_width <= 0 || default_space <= 0) {
1945+
logger_->error(CTS,
1946+
208,
1947+
"Clock NDR settings for layer {}: defaultSpace: {}, "
1948+
"defaultWidth: {}",
1949+
layer->getName(),
1950+
default_space,
1951+
default_width);
19881952
}
19891953

19901954
// Set NDR settings
1991-
int ndr_width = defaultWidth;
1955+
const int ndr_width = default_width;
19921956
layerRule->setWidth(ndr_width);
1993-
int ndr_space = 2 * getNetSpacing(layer, ndr_width, ndr_width);
1957+
const int ndr_space = 2 * default_space;
19941958
layerRule->setSpacing(ndr_space);
19951959

19961960
debugPrint(logger_,
19971961
CTS,
1998-
"clustering",
1962+
"ndr",
19991963
1,
20001964
" NDR rule set to layer {} {} as space={} width={} vs. default "
20011965
"space={} width={}",
20021966
i,
20031967
layer->getName(),
20041968
layerRule->getSpacing(),
20051969
layerRule->getWidth(),
2006-
defaultSpace,
2007-
defaultWidth);
1970+
default_space,
1971+
default_width);
20081972
}
20091973

20101974
int clkNets = 0;
@@ -2028,7 +1992,7 @@ void TritonCTS::writeClockNDRsToDb(TreeBuilder* builder)
20281992

20291993
debugPrint(logger_,
20301994
CTS,
2031-
"clustering",
1995+
"ndr",
20321996
1,
20331997
"Non-default rule {} for double spacing has been applied to {} "
20341998
"clock nets",

src/cts/test/array_max_wl.defok

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52289,8 +52289,8 @@ TRACKS X 3390 DO 3087 STEP 3200 LAYER metal10 ;
5228952289
TRACKS Y 3340 DO 3087 STEP 3200 LAYER metal10 ;
5229052290
NONDEFAULTRULES 2 ;
5229152291
- CTS_NDR_0
52292-
+ LAYER metal1 WIDTH 140 SPACING 260
52293-
+ LAYER metal2 WIDTH 140 SPACING 280
52292+
+ LAYER metal1 WIDTH 140 SPACING 280
52293+
+ LAYER metal2 WIDTH 140 SPACING 480
5229452294
+ LAYER metal3 WIDTH 140 SPACING 280
5229552295
+ LAYER metal4 WIDTH 280 SPACING 560
5229652296
+ LAYER metal5 WIDTH 280 SPACING 560
@@ -52301,8 +52301,8 @@ NONDEFAULTRULES 2 ;
5230152301
+ LAYER metal10 WIDTH 1600 SPACING 3200
5230252302
;
5230352303
- CTS_NDR_1
52304-
+ LAYER metal1 WIDTH 140 SPACING 260
52305-
+ LAYER metal2 WIDTH 140 SPACING 280
52304+
+ LAYER metal1 WIDTH 140 SPACING 280
52305+
+ LAYER metal2 WIDTH 140 SPACING 480
5230652306
+ LAYER metal3 WIDTH 140 SPACING 280
5230752307
+ LAYER metal4 WIDTH 280 SPACING 560
5230852308
+ LAYER metal5 WIDTH 280 SPACING 560

src/cts/test/simple_test_out.defok

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ UNITS DISTANCE MICRONS 2000 ;
66
DIEAREA ( 0 0 ) ( 20000 20000 ) ;
77
NONDEFAULTRULES 1 ;
88
- CTS_NDR_0
9-
+ LAYER metal1 WIDTH 140 SPACING 260
10-
+ LAYER metal2 WIDTH 140 SPACING 280
9+
+ LAYER metal1 WIDTH 140 SPACING 280
10+
+ LAYER metal2 WIDTH 140 SPACING 480
1111
+ LAYER metal3 WIDTH 140 SPACING 280
1212
+ LAYER metal4 WIDTH 280 SPACING 560
1313
+ LAYER metal5 WIDTH 280 SPACING 560

src/cts/test/twice.defok

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ UNITS DISTANCE MICRONS 2000 ;
66
DIEAREA ( 0 0 ) ( 20000 20000 ) ;
77
NONDEFAULTRULES 1 ;
88
- CTS_NDR_0
9-
+ LAYER metal1 WIDTH 140 SPACING 260
10-
+ LAYER metal2 WIDTH 140 SPACING 280
9+
+ LAYER metal1 WIDTH 140 SPACING 280
10+
+ LAYER metal2 WIDTH 140 SPACING 480
1111
+ LAYER metal3 WIDTH 140 SPACING 280
1212
+ LAYER metal4 WIDTH 280 SPACING 560
1313
+ LAYER metal5 WIDTH 280 SPACING 560

0 commit comments

Comments
 (0)