Skip to content

Commit d2ebf62

Browse files
committed
rsz: Refactored Resizer::inferClockBufferList()
Signed-off-by: Jaehyun Kim <[email protected]>
1 parent 40209e7 commit d2ebf62

File tree

1 file changed

+112
-112
lines changed

1 file changed

+112
-112
lines changed

src/rsz/src/Resizer.cc

Lines changed: 112 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -5272,157 +5272,157 @@ bool Resizer::isClockCellCandidate(sta::LibertyCell* cell)
52725272
void Resizer::inferClockBufferList(const char* lib_name,
52735273
std::vector<std::string>& buffers)
52745274
{
5275-
sta::Vector<sta::LibertyCell*> selected_buffers;
5276-
5277-
// first, look for buffers with "is_clock_cell: true" cell attribute
5278-
sta::LibertyLibraryIterator* lib_iter = network_->libertyLibraryIterator();
5275+
// Lists to store different types of clock buffer candidates based on several
5276+
// criteria.
5277+
sta::Vector<sta::LibertyCell*> clock_cell_attribute_buffers;
5278+
sta::Vector<sta::LibertyCell*> lef_use_clock_buffers;
5279+
sta::Vector<sta::LibertyCell*> clkbuf_pattern_buffers;
5280+
sta::Vector<sta::LibertyCell*> buf_pattern_buffers;
5281+
sta::Vector<sta::LibertyCell*> all_candidate_buffers;
5282+
5283+
// Patterns for matching common clock buffer and general buffer naming
5284+
// conventions.
5285+
sta::PatternMatch patternClkBuf(".*CLKBUF.*",
5286+
/* is_regexp */ true,
5287+
/* nocase */ true,
5288+
/* Tcl_interp* */ sta_->tclInterp());
5289+
sta::PatternMatch patternBuf(".*BUF.*",
5290+
/* is_regexp */ true,
5291+
/* nocase */ true,
5292+
/* Tcl_interp* */ nullptr);
5293+
5294+
// 1. Iterate over all liberty libraries to find candidate cells.
5295+
std::unique_ptr<sta::LibertyLibraryIterator> lib_iter(
5296+
network_->libertyLibraryIterator());
52795297
while (lib_iter->hasNext()) {
52805298
sta::LibertyLibrary* lib = lib_iter->next();
5299+
// Filter by library name if provided.
52815300
if (lib_name != nullptr && strcmp(lib->name(), lib_name) != 0) {
52825301
continue;
52835302
}
5303+
5304+
// Collect candidates by checking cell attributes and LEF pin signal types.
52845305
for (sta::LibertyCell* buffer : *lib->buffers()) {
5285-
if (buffer->isClockCell() && isClockCellCandidate(buffer)) {
5286-
// "is_clock_cell: true"
5287-
selected_buffers.emplace_back(buffer);
5288-
debugPrint(logger_,
5289-
RSZ,
5290-
"inferClockBufferList",
5291-
1,
5292-
"{} has clock cell attribute",
5293-
buffer->name());
5306+
if (!isClockCellCandidate(buffer)) {
5307+
continue;
52945308
}
5295-
}
5296-
}
5297-
delete lib_iter;
5309+
all_candidate_buffers.emplace_back(buffer);
52985310

5299-
// second, look for buffers with an input port that has
5300-
// LEF USE as "CLOCK"
5301-
if (selected_buffers.empty()) {
5302-
sta::LibertyLibraryIterator* lib_iter = network_->libertyLibraryIterator();
5303-
while (lib_iter->hasNext()) {
5304-
sta::LibertyLibrary* lib = lib_iter->next();
5305-
if (lib_name != nullptr && strcmp(lib->name(), lib_name) != 0) {
5306-
continue;
5311+
// Priority 1: Check for explicit "is_clock_cell" attribute in liberty.
5312+
if (buffer->isClockCell()) {
5313+
clock_cell_attribute_buffers.emplace_back(buffer);
53075314
}
5308-
for (sta::LibertyCell* buffer : *lib->buffers()) {
5309-
odb::dbMaster* master = db_->findMaster(buffer->name());
5310-
for (odb::dbMTerm* mterm : master->getMTerms()) {
5311-
if (mterm->getIoType() == odb::dbIoType::INPUT
5312-
&& mterm->getSigType() == odb::dbSigType::CLOCK
5313-
&& isClockCellCandidate(buffer)) {
5314-
// input port with LEF USE as "CLOCK"
5315-
selected_buffers.emplace_back(buffer);
5316-
debugPrint(logger_,
5317-
RSZ,
5318-
"inferClockBufferList",
5319-
1,
5320-
"{} has input port {} with LEF USE as CLOCK",
5321-
buffer->name(),
5322-
mterm->getName());
5323-
}
5315+
5316+
// Priority 2: Check for any input pin with LEF signal type set to CLOCK.
5317+
odb::dbMaster* master = db_->findMaster(buffer->name());
5318+
for (odb::dbMTerm* mterm : master->getMTerms()) {
5319+
if (mterm->getIoType() == odb::dbIoType::INPUT
5320+
&& mterm->getSigType() == odb::dbSigType::CLOCK) {
5321+
lef_use_clock_buffers.emplace_back(buffer);
5322+
break; // Avoid duplicates for multiple clock pins
53245323
}
53255324
}
53265325
}
5327-
delete lib_iter;
5328-
}
53295326

5330-
// third, look for all buffers with name CLKBUF or clkbuf
5331-
if (selected_buffers.empty()) {
5332-
sta::PatternMatch patternClkBuf(".*CLKBUF.*",
5333-
/* is_regexp */ true,
5334-
/* nocase */ true,
5335-
/* Tcl_interp* */ sta_->tclInterp());
5336-
sta::LibertyLibraryIterator* lib_iter = network_->libertyLibraryIterator();
5337-
while (lib_iter->hasNext()) {
5338-
sta::LibertyLibrary* lib = lib_iter->next();
5339-
if (lib_name != nullptr && strcmp(lib->name(), lib_name) != 0) {
5340-
continue;
5327+
// Priority 3: Collections based on naming pattern matching (CLKBUF).
5328+
for (sta::LibertyCell* buffer :
5329+
lib->findLibertyCellsMatching(&patternClkBuf)) {
5330+
if (buffer->isBuffer() && isClockCellCandidate(buffer)) {
5331+
clkbuf_pattern_buffers.emplace_back(buffer);
53415332
}
5342-
for (sta::LibertyCell* buffer :
5343-
lib->findLibertyCellsMatching(&patternClkBuf)) {
5344-
if (buffer->isBuffer() && isClockCellCandidate(buffer)) {
5345-
debugPrint(logger_,
5346-
RSZ,
5347-
"inferClockBufferList",
5348-
1,
5349-
"{} found by 'CLKBUF' pattern match",
5350-
buffer->name());
5351-
selected_buffers.emplace_back(buffer);
5352-
}
5333+
}
5334+
5335+
// Priority 4: Collections based on naming pattern matching (BUF).
5336+
for (sta::LibertyCell* buffer :
5337+
lib->findLibertyCellsMatching(&patternBuf)) {
5338+
if (buffer->isBuffer() && isClockCellCandidate(buffer)) {
5339+
buf_pattern_buffers.emplace_back(buffer);
53535340
}
53545341
}
5355-
delete lib_iter;
53565342
}
53575343

5358-
// fourth, look for all buffers with name BUF or buf
5359-
if (selected_buffers.empty()) {
5360-
sta::PatternMatch patternBuf(".*BUF.*",
5361-
/* is_regexp */ true,
5362-
/* nocase */ true,
5363-
/* Tcl_interp* */ nullptr);
5364-
sta::LibertyLibraryIterator* lib_iter = network_->libertyLibraryIterator();
5365-
while (lib_iter->hasNext()) {
5366-
sta::LibertyLibrary* lib = lib_iter->next();
5367-
if (lib_name != nullptr && strcmp(lib->name(), lib_name) != 0) {
5368-
continue;
5369-
}
5370-
for (sta::LibertyCell* buffer :
5371-
lib->findLibertyCellsMatching(&patternBuf)) {
5372-
if (buffer->isBuffer() && isClockCellCandidate(buffer)) {
5344+
// 2. Select the final list of buffers based on the defined priority.
5345+
// We take the first non-empty set found.
5346+
sta::Vector<sta::LibertyCell*>* selected_ptr = nullptr;
5347+
if (!clock_cell_attribute_buffers.empty()) {
5348+
selected_ptr = &clock_cell_attribute_buffers;
5349+
for (sta::LibertyCell* buffer : *selected_ptr) {
5350+
debugPrint(logger_,
5351+
RSZ,
5352+
"inferClockBufferList",
5353+
1,
5354+
"{} has clock cell attribute",
5355+
buffer->name());
5356+
}
5357+
} else if (!lef_use_clock_buffers.empty()) {
5358+
selected_ptr = &lef_use_clock_buffers;
5359+
for (sta::LibertyCell* buffer : *selected_ptr) {
5360+
odb::dbMaster* master = db_->findMaster(buffer->name());
5361+
for (odb::dbMTerm* mterm : master->getMTerms()) {
5362+
if (mterm->getIoType() == odb::dbIoType::INPUT
5363+
&& mterm->getSigType() == odb::dbSigType::CLOCK) {
53735364
debugPrint(logger_,
53745365
RSZ,
53755366
"inferClockBufferList",
53765367
1,
5377-
"{} found by 'BUF' pattern match",
5378-
buffer->name());
5379-
selected_buffers.emplace_back(buffer);
5368+
"{} has input port {} with LEF USE as CLOCK",
5369+
buffer->name(),
5370+
mterm->getName());
5371+
break;
53805372
}
53815373
}
53825374
}
5383-
delete lib_iter;
5384-
}
5385-
5386-
// abandon attributes & name patterns, just look for all buffers
5387-
if (selected_buffers.empty()) {
5375+
} else if (!clkbuf_pattern_buffers.empty()) {
5376+
selected_ptr = &clkbuf_pattern_buffers;
5377+
for (sta::LibertyCell* buffer : *selected_ptr) {
5378+
debugPrint(logger_,
5379+
RSZ,
5380+
"inferClockBufferList",
5381+
1,
5382+
"{} found by 'CLKBUF' pattern match",
5383+
buffer->name());
5384+
}
5385+
} else if (!buf_pattern_buffers.empty()) {
5386+
selected_ptr = &buf_pattern_buffers;
5387+
for (sta::LibertyCell* buffer : *selected_ptr) {
5388+
debugPrint(logger_,
5389+
RSZ,
5390+
"inferClockBufferList",
5391+
1,
5392+
"{} found by 'BUF' pattern match",
5393+
buffer->name());
5394+
}
5395+
} else {
5396+
// Priority 5: Fallback to all buffers that are valid clock cell candidates.
53885397
debugPrint(logger_,
53895398
RSZ,
53905399
"inferClockBufferList",
53915400
1,
53925401
"No buffers with clock attributes or name patterns found, using "
53935402
"all buffers");
5394-
sta::LibertyLibraryIterator* lib_iter = network_->libertyLibraryIterator();
5395-
while (lib_iter->hasNext()) {
5396-
sta::LibertyLibrary* lib = lib_iter->next();
5397-
if (lib_name != nullptr && strcmp(lib->name(), lib_name) != 0) {
5398-
continue;
5399-
}
5400-
for (sta::LibertyCell* buffer : *lib->buffers()) {
5401-
if (isClockCellCandidate(buffer)) {
5402-
selected_buffers.emplace_back(buffer);
5403-
}
5404-
}
5405-
}
5406-
delete lib_iter;
5407-
5408-
if (selected_buffers.empty()) {
5403+
selected_ptr = &all_candidate_buffers;
5404+
if (selected_ptr->empty()) {
54095405
logger_->error(
54105406
RSZ,
54115407
110,
54125408
"No clock buffer candidates could be found from any libraries.");
54135409
}
54145410
}
54155411

5416-
setClockBuffersList(selected_buffers);
5412+
// 3. Finalize the inferred list: store it in Resizer and populate the output
5413+
// vector of buffer names.
5414+
if (selected_ptr != nullptr) {
5415+
setClockBuffersList(*selected_ptr);
54175416

5418-
for (sta::LibertyCell* buffer : selected_buffers) {
5419-
buffers.emplace_back(buffer->name());
5420-
debugPrint(logger_,
5421-
RSZ,
5422-
"inferClockBufferList",
5423-
1,
5424-
"{} has been inferred as clock buffer",
5425-
buffer->name());
5417+
for (sta::LibertyCell* buffer : *selected_ptr) {
5418+
buffers.emplace_back(buffer->name());
5419+
debugPrint(logger_,
5420+
RSZ,
5421+
"inferClockBufferList",
5422+
1,
5423+
"{} has been inferred as clock buffer",
5424+
buffer->name());
5425+
}
54265426
}
54275427
}
54285428

0 commit comments

Comments
 (0)