@@ -474,7 +474,7 @@ void TritonCTS::writeDataToDb()
474474 for (auto & builder : builders_) {
475475 writeClockNetsToDb (builder.get (), clkLeafNets);
476476 if (options_->applyNDR ()) {
477- writeClockNDRsToDb (builder.get (), clkLeafNets );
477+ writeClockNDRsToDb (builder.get ());
478478 }
479479 if (options_->dummyLoadEnabled ()) {
480480 writeDummyLoadsToDb (builder->getClock (), clkDummies);
@@ -1539,39 +1539,19 @@ void TritonCTS::writeClockNetsToDb(TreeBuilder* builder,
15391539 CTS, 17 , " Max level of the clock tree: {}." , clockNet.getMaxLevel ());
15401540}
15411541
1542- // Function to extract level number from clock net name
1543- // int TritonCTS::extractClockTreeLevelFromNetName(const std::string& netName)
1544- // {
1545- // // Pattern to find number between underscores (e.g., "clknet_2_clk_i")
1546- // std::regex pattern("_([0-9]+)_");
1547- // std::smatch match;
1548-
1549- // if (std::regex_search(netName, match, pattern)) {
1550- // return std::stoi(match[1]);
1551- // }
1552-
1553- // // If no number found between underscores, it's level 0
1554- // return 0;
1555- // }
1556-
1557- // // Utility function to get all unique clock tree levels in the design
1558- // std::vector<int> TritonCTS::getAllClockTreeLevels(
1559- // odb::dbBlock* block_,
1560- // const std::set<odb::dbNet*>& clkLeafNets)
1561- // {
1562- // std::set<int> uniqueLevels;
1563-
1564- // for (odb::dbNet* net : block_->getNets()) {
1565- // if (net->getSigType() == odb::dbSigType::CLOCK
1566- // && (clkLeafNets.find(net) == clkLeafNets.end())) {
1567- // int level = extractClockTreeLevelFromNetName(net->getConstName());
1568- // uniqueLevels.insert(level);
1569- // }
1570- // }
1571-
1572- // return std::vector<int>(uniqueLevels.begin(), uniqueLevels.end());
1573- // ;
1574- // }
1542+ // Utility function to get all unique clock tree levels
1543+ std::vector<int > TritonCTS::getAllClockTreeLevels (Clock& clockNet)
1544+ {
1545+ std::set<int > uniqueLevels;
1546+
1547+ clockNet.forEachSubNet ([&](ClockSubNet& subNet) {
1548+ if (!subNet.isLeafLevel ()){
1549+ uniqueLevels.insert (subNet.getTreeLevel ());
1550+ }
1551+ });
1552+
1553+ return std::vector<int >(uniqueLevels.begin (), uniqueLevels.end ());
1554+ }
15751555
15761556// Function to apply NDR to specific clock tree levels and return the number of
15771557// NDR applied nets
@@ -1600,12 +1580,9 @@ int TritonCTS::applyNDRToClockLevels(Clock& clockNet,
16001580 // clang-format on
16011581 }
16021582
1603- // //////////////////////////////////
16041583 // Check clock sub nets list and apply NDR if level matches
16051584 clockNet.forEachSubNet ([&](ClockSubNet& subNet) {
16061585 int level = subNet.getTreeLevel ();
1607- if (!subNet.isLeafLevel ())
1608- logger_->report (" Net {} - Level: {}" ,subNet.getName (), level);
16091586 if (std::find (targetLevels.begin (), targetLevels.end (), level)
16101587 != targetLevels.end ())
16111588 {
@@ -1623,73 +1600,46 @@ int TritonCTS::applyNDRToClockLevels(Clock& clockNet,
16231600 }
16241601 });
16251602
1626- // ////////////////////////////////////
1627-
1628- // Single pass: check clock nets and apply NDR if level matches
1629- // for (odb::dbNet* net : block_->getNets()) {
1630- // if (net->getSigType() == odb::dbSigType::CLOCK
1631- // && (clkLeafNets.find(net) == clkLeafNets.end())) {
1632- // const std::string netName = net->getConstName();
1633- // const int level = extractClockTreeLevelFromNetName(netName);
1634-
1635- // // Apply NDR if this level is in the target list
1636- // if (std::find(targetLevels.begin(), targetLevels.end(), level)
1637- // != targetLevels.end()) {
1638- // net->setNonDefaultRule(clockNDR);
1639- // ndrAppliedNets++;
1640- // // clang-format off
1641- // debugPrint(logger_, CTS, "clustering", 1,
1642- // "Applied NDR to: {} (level {})", netName, level);
1643- // // clang-format on
1644- // }
1645- // }
1646- // }
1647-
16481603 return ndrAppliedNets;
16491604}
16501605
16511606// Alternative function to apply NDR to a range of clock tree levels
1652- // int TritonCTS::applyNDRToClockLevelRange(
1653- // odb::dbBlock* block_,
1654- // odb::dbTechNonDefaultRule* clockNDR,
1655- // const std::set<odb::dbNet*>& clkLeafNets,
1656- // const int minLevel,
1657- // const int maxLevel)
1658- // {
1659- // std::vector<int> targetLevels;
1660- // for (int i = minLevel; i <= maxLevel; i++) {
1661- // targetLevels.push_back(i);
1662- // }
1663-
1664- // return applyNDRToClockLevels(block_, clockNDR, clkLeafNets, targetLevels);
1665- // }
1666-
1667- // // Function to apply NDR to the first half of clock tree levels
1668- // int TritonCTS::applyNDRToFirstHalfLevels(
1669- // odb::dbBlock* block_,
1670- // odb::dbTechNonDefaultRule* clockNDR,
1671- // const std::set<odb::dbNet*>& clkLeafNets)
1672- // {
1673- // // Get all unique levels in the design
1674- // const std::vector<int> allLevels = getAllClockTreeLevels(block_, clkLeafNets);
1675-
1676- // // Calculate first half (rounding up if odd number of levels)
1677- // const size_t halfCount = (allLevels.size() + 1) / 2;
1678-
1679- // // Create vector with first half of levels
1680- // std::vector<int> firstHalfLevels(allLevels.begin(),
1681- // allLevels.begin() + halfCount);
1682-
1683- // // clang-format off
1684- // debugPrint(logger_, CTS, "clustering", 1, "Total clock tree levels found: {}"
1685- // "Applying NDR to first {} levels", allLevels.size(), halfCount);
1686- // // clang-format on
1687-
1688- // // Apply NDR to the first half
1689- // return applyNDRToClockLevels(block_, clockNDR, clkLeafNets, firstHalfLevels);
1690- // }
1691-
1692- void TritonCTS::writeClockNDRsToDb (TreeBuilder* builder, const std::set<odb::dbNet*>& clkLeafNets)
1607+ int TritonCTS::applyNDRToClockLevelRange (Clock& clockNet,
1608+ odb::dbTechNonDefaultRule* clockNDR,
1609+ const int minLevel,
1610+ const int maxLevel)
1611+ {
1612+ std::vector<int > targetLevels;
1613+ for (int i = minLevel; i <= maxLevel; i++) {
1614+ targetLevels.push_back (i);
1615+ }
1616+
1617+ return applyNDRToClockLevels (clockNet, clockNDR, targetLevels);
1618+ }
1619+
1620+ // Function to apply NDR to the first half of clock tree levels
1621+ int TritonCTS::applyNDRToFirstHalfLevels (Clock& clockNet, odb::dbTechNonDefaultRule* clockNDR)
1622+ {
1623+ // Get all unique levels in the design
1624+ const std::vector<int > allLevels = getAllClockTreeLevels (clockNet);
1625+
1626+ // Calculate first half (rounding up if odd number of levels)
1627+ const int halfCount = (allLevels.size () + 1 ) / 2 ;
1628+
1629+ // Create vector with first half of levels
1630+ std::vector<int > firstHalfLevels (allLevels.begin (),
1631+ allLevels.begin () + halfCount);
1632+
1633+ // clang-format off
1634+ debugPrint (logger_, CTS, " clustering" , 1 , " Total clock tree levels found: {}"
1635+ " Applying NDR to first {} levels" , allLevels.size (), halfCount);
1636+ // clang-format on
1637+
1638+ // Apply NDR to the first half
1639+ return applyNDRToClockLevels (clockNet, clockNDR, firstHalfLevels);
1640+ }
1641+
1642+ void TritonCTS::writeClockNDRsToDb (TreeBuilder* builder)
16931643{
16941644 char ruleName[64 ];
16951645 int ruleIndex = 0 ;
@@ -1732,24 +1682,18 @@ void TritonCTS::writeClockNDRsToDb(TreeBuilder* builder, const std::set<odb::dbN
17321682
17331683 // TODO: Add user specified args to choose the NDR strategy
17341684 // Option 1: Apply NDR to specific levels
1735- std::vector<int > specificLevels = {0 , 1 , 2 }; // Apply to level 0
1736- clkNets = applyNDRToClockLevels (clockNet, clockNDR, specificLevels);
1685+ // const std::vector<int> specificLevels = {0}; // Apply to level 0
1686+ // clkNets = applyNDRToClockLevels(clockNet, clockNDR, specificLevels);
17371687
17381688 // Option 2: Apply NDR to a range of levels (e.g., Levels 0-3)
17391689 // clkNets = applyNDRToClockLevelRange(block_, clockNDR, clkLeafNets, 0, 3);
17401690
17411691 // Option 3: Apply NDR to the first half of the clk tree levels (higher
17421692 // levels)
1743- // clkNets = applyNDRToFirstHalfLevels(block_ , clockNDR, clkLeafNets );
1693+ // clkNets = applyNDRToFirstHalfLevels(clockNet , clockNDR);
17441694
17451695 // Option 4: Apply NDR to all non-leaf clock nets (default)
1746- // for (odb::dbNet* net : block_->getNets()) {
1747- // if (net->getSigType() == odb::dbSigType::CLOCK
1748- // && (clkLeafNets.find(net) == clkLeafNets.end())) {
1749- // net->setNonDefaultRule(clockNDR);
1750- // clkNets++;
1751- // }
1752- // }
1696+ clkNets = applyNDRToClockLevels (clockNet, clockNDR, getAllClockTreeLevels (clockNet));
17531697
17541698 logger_->info (CTS,
17551699 202 ,
0 commit comments