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+
16771713void 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