Skip to content

Commit 5937486

Browse files
committed
cts: update NDR functions to use new clock tree level information
Signed-off-by: Jonas Gava <[email protected]>
1 parent d88fb03 commit 5937486

File tree

4 files changed

+64
-130
lines changed

4 files changed

+64
-130
lines changed

src/cts/include/cts/TritonCTS.h

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -94,32 +94,24 @@ class TritonCTS
9494
void writeDataToDb();
9595

9696
// NDR functions
97-
int extractClockTreeLevelFromNetName(const std::string& netName);
98-
std::vector<int> getAllClockTreeLevels(
99-
odb::dbBlock* block_,
100-
const std::set<odb::dbNet*>& clkLeafNets);
101-
int applyNDRToClockLevels(Clock& clockNet, odb::dbTechNonDefaultRule* clockNDR, const std::vector<int>& targetLevels);
97+
std::vector<int> getAllClockTreeLevels(Clock& clockNet);
98+
int applyNDRToClockLevels(Clock& clockNet,
99+
odb::dbTechNonDefaultRule* clockNDR,
100+
const std::vector<int>& targetLevels);
102101

103-
// int applyNDRToClockLevels(Clock& clockNet,
104-
// odb::dbBlock* block_,
105-
// odb::dbTechNonDefaultRule* clockNDR,
106-
// const std::set<odb::dbNet*>& clkLeafNets,
107-
// const std::vector<int>& targetLevels);
108-
int applyNDRToClockLevelRange(odb::dbBlock* block_,
102+
int applyNDRToClockLevelRange(Clock& clockNet,
109103
odb::dbTechNonDefaultRule* clockNDR,
110-
const std::set<odb::dbNet*>& clkLeafNets,
111104
int minLevel,
112105
int maxLevel);
113-
int applyNDRToFirstHalfLevels(odb::dbBlock* block_,
114-
odb::dbTechNonDefaultRule* clockNDR,
115-
const std::set<odb::dbNet*>& clkLeafNets);
106+
int applyNDRToFirstHalfLevels(Clock& clockNet,
107+
odb::dbTechNonDefaultRule* clockNDR);
116108

117109
// db functions
118110
bool masterExists(const std::string& master) const;
119111
void populateTritonCTS();
120112
void writeClockNetsToDb(TreeBuilder* builder,
121113
std::set<odb::dbNet*>& clkLeafNets);
122-
void writeClockNDRsToDb(TreeBuilder* builder, const std::set<odb::dbNet*>& clkLeafNets);
114+
void writeClockNDRsToDb(TreeBuilder* builder);
123115
void incrementNumClocks() { ++numberOfClocks_; }
124116
void clearNumClocks() { numberOfClocks_ = 0; }
125117
unsigned getNumClocks() const { return numberOfClocks_; }

src/cts/src/HTreeBuilder.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1953,8 +1953,8 @@ void HTreeBuilder::createClockSubNets()
19531953
this);
19541954

19551955
// Set clock tree level the first time only.
1956-
if (builder.getSubNetTreeLevel() < 0)
1957-
builder.setSubNetTreeLevel(levelIdx);
1956+
if (builder.getDrivingSubNet()->getTreeLevel() < 0)
1957+
builder.getDrivingSubNet()->setTreeLevel(levelIdx);
19581958

19591959
if (!options_->getTreeBuffer().empty()) {
19601960
builder.build(options_->getTreeBuffer());

src/cts/src/HTreeBuilder.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ class SegmentBuilder
3838
ClockSubNet* getDrivingSubNet() const { return drivingSubNet_; }
3939
unsigned getNumBufferLevels() const { return numBufferLevels_; }
4040
TreeBuilder* getTree() const { return tree_; }
41-
void setSubNetTreeLevel(int level){drivingSubNet_->setTreeLevel(level);}
42-
int getSubNetTreeLevel(){return drivingSubNet_->getTreeLevel();}
4341

4442
private:
4543
const std::string instPrefix_;

src/cts/src/TritonCTS.cpp

Lines changed: 54 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)