Skip to content

Commit

Permalink
Merge pull request #5752 from AcKoucher/rsz-clock-buffers
Browse files Browse the repository at this point in the history
rsz: use adequate buffers for each operation
  • Loading branch information
maliberty authored Oct 1, 2024
2 parents eb794ae + ee7fca9 commit 7d17168
Show file tree
Hide file tree
Showing 48 changed files with 1,617 additions and 1,522 deletions.
24 changes: 16 additions & 8 deletions src/cts/src/TritonCTS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,8 @@ void TritonCTS::setBufferList(const char* buffers)

void TritonCTS::inferBufferList(std::vector<std::string>& buffers)
{
sta::Vector<sta::LibertyCell*> selected_buffers;

// first, look for buffers with "is_clock_cell: true" cell attribute
sta::LibertyLibraryIterator* lib_iter = network_->libertyLibraryIterator();
while (lib_iter->hasNext()) {
Expand All @@ -614,7 +616,7 @@ void TritonCTS::inferBufferList(std::vector<std::string>& buffers)
}
for (sta::LibertyCell* buffer : *lib->buffers()) {
if (buffer->isClockCell() && isClockCellCandidate(buffer)) {
buffers.emplace_back(buffer->name());
selected_buffers.emplace_back(buffer);
// clang-format off
debugPrint(logger_, CTS, "buffering", 1, "{} has clock cell attribute",
buffer->name());
Expand All @@ -625,7 +627,7 @@ void TritonCTS::inferBufferList(std::vector<std::string>& buffers)
delete lib_iter;

// second, look for all buffers with name CLKBUF or clkbuf
if (buffers.empty()) {
if (selected_buffers.empty()) {
sta::PatternMatch patternClkBuf(".*CLKBUF.*",
/* is_regexp */ true,
/* nocase */ true,
Expand All @@ -640,15 +642,15 @@ void TritonCTS::inferBufferList(std::vector<std::string>& buffers)
for (sta::LibertyCell* buffer :
lib->findLibertyCellsMatching(&patternClkBuf)) {
if (buffer->isBuffer() && isClockCellCandidate(buffer)) {
buffers.emplace_back(buffer->name());
selected_buffers.emplace_back(buffer);
}
}
}
delete lib_iter;
}

// third, look for all buffers with name BUF or buf
if (buffers.empty()) {
if (selected_buffers.empty()) {
sta::PatternMatch patternBuf(".*BUF.*",
/* is_regexp */ true,
/* nocase */ true,
Expand All @@ -663,15 +665,15 @@ void TritonCTS::inferBufferList(std::vector<std::string>& buffers)
for (sta::LibertyCell* buffer :
lib->findLibertyCellsMatching(&patternBuf)) {
if (buffer->isBuffer() && isClockCellCandidate(buffer)) {
buffers.emplace_back(buffer->name());
selected_buffers.emplace_back(buffer);
}
}
}
delete lib_iter;
}

// abandon attributes & name patterns, just look for all buffers
if (buffers.empty()) {
if (selected_buffers.empty()) {
lib_iter = network_->libertyLibraryIterator();
while (lib_iter->hasNext()) {
sta::LibertyLibrary* lib = lib_iter->next();
Expand All @@ -681,20 +683,26 @@ void TritonCTS::inferBufferList(std::vector<std::string>& buffers)
}
for (sta::LibertyCell* buffer : *lib->buffers()) {
if (isClockCellCandidate(buffer)) {
buffers.emplace_back(buffer->name());
selected_buffers.emplace_back(buffer);
}
}
}
delete lib_iter;

if (buffers.empty()) {
if (selected_buffers.empty()) {
logger_->error(
CTS,
110,
"No clock buffer candidates could be found from any libraries.");
}
}

resizer_->setClockBuffersList(selected_buffers);

for (sta::LibertyCell* buffer : selected_buffers) {
buffers.emplace_back(buffer->name());
}

options_->setBufferListInferred(true);
if (logger_->debugCheck(utl::CTS, "buffering", 1)) {
for (const std::string& bufName : buffers) {
Expand Down
22 changes: 22 additions & 0 deletions src/dbSta/include/db_sta/dbSta.hh
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class dbStaReport;
class dbStaCbk;
class AbstractPathRenderer;
class AbstractPowerDensityDataSource;
class PatternMatch;

using utl::Logger;

Expand All @@ -83,6 +84,23 @@ class dbStaState : public sta::StaState
dbSta* sta_ = nullptr;
};

enum BufferUse
{
DATA,
CLOCK
};

class BufferUseAnalyser
{
public:
BufferUseAnalyser();

BufferUse getBufferUse(sta::LibertyCell* buffer);

private:
std::unique_ptr<sta::PatternMatch> clkbuf_pattern_;
};

class dbSta : public Sta, public ord::OpenRoadObserver
{
public:
Expand Down Expand Up @@ -172,6 +190,8 @@ class dbSta : public Sta, public ord::OpenRoadObserver
InstType getInstanceType(odb::dbInst* inst);
void report_cell_usage(bool verbose);

BufferUse getBufferUse(sta::LibertyCell* buffer);

using Sta::netSlack;
using Sta::replaceCell;

Expand All @@ -192,6 +212,8 @@ class dbSta : public Sta, public ord::OpenRoadObserver
std::unique_ptr<dbStaCbk> db_cbk_;
std::set<dbStaState*> sta_states_;

std::unique_ptr<BufferUseAnalyser> buffer_use_analyser_;

std::unique_ptr<AbstractPathRenderer> path_renderer_;
std::unique_ptr<AbstractPowerDensityDataSource> power_density_data_source_;
};
Expand Down
29 changes: 29 additions & 0 deletions src/dbSta/src/dbSta.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#include "sta/Liberty.hh"
#include "sta/PathExpanded.hh"
#include "sta/PathRef.hh"
#include "sta/PatternMatch.hh"
#include "sta/ReportTcl.hh"
#include "sta/Sdc.hh"
#include "sta/Search.hh"
Expand Down Expand Up @@ -188,6 +189,7 @@ void dbSta::initVars(Tcl_Interp* tcl_interp,
db_report_->setLogger(logger);
db_network_->init(db, logger);
db_cbk_ = std::make_unique<dbStaCbk>(this, logger);
buffer_use_analyser_ = std::make_unique<BufferUseAnalyser>();
}

void dbSta::updateComponentsState()
Expand Down Expand Up @@ -539,6 +541,11 @@ void dbSta::report_cell_usage(const bool verbose)
}
}

BufferUse dbSta::getBufferUse(sta::LibertyCell* buffer)
{
return buffer_use_analyser_->getBufferUse(buffer);
}

////////////////////////////////////////////////////////////////

// Network edit functions.
Expand Down Expand Up @@ -869,4 +876,26 @@ void dbSta::highlight(PathRef* path)
path_renderer_->highlight(path);
}

////////////////////////////////////////////////////////////////

BufferUseAnalyser::BufferUseAnalyser()
{
clkbuf_pattern_
= std::make_unique<sta::PatternMatch>(".*CLKBUF.*",
/* is_regexp */ true,
/* nocase */ true,
/* Tcl_interp* */ nullptr);
}

BufferUse BufferUseAnalyser::getBufferUse(sta::LibertyCell* buffer)
{
// is_clock_cell is a custom lib attribute that may not exist,
// so we also use the name pattern to help
if (buffer->isClockCell() || clkbuf_pattern_->match(buffer->name())) {
return CLOCK;
}

return DATA;
}

} // namespace sta
Loading

0 comments on commit 7d17168

Please sign in to comment.