From 4df2cd406c094d409106740e89aa34104d15a603 Mon Sep 17 00:00:00 2001 From: Ted Hong Date: Mon, 6 Jul 2026 18:48:59 +0000 Subject: [PATCH] Add stream interface for parseLibertyFile and readLibertyFile. Signed-off-by: Ted Hong --- include/sta/Sta.hh | 21 +++++++++++++++++++ liberty/LibertyParser.cc | 17 +++++++++++---- liberty/LibertyParser.hh | 17 +++++++++++++++ liberty/LibertyReader.cc | 20 +++++++++++++++++- liberty/LibertyReader.hh | 7 +++++++ liberty/LibertyReaderPvt.hh | 1 + search/Sta.cc | 41 +++++++++++++++++++++++++++++++++++++ 7 files changed, 119 insertions(+), 5 deletions(-) diff --git a/include/sta/Sta.hh b/include/sta/Sta.hh index bf482f55a..cc7245b8f 100644 --- a/include/sta/Sta.hh +++ b/include/sta/Sta.hh @@ -24,6 +24,7 @@ #pragma once +#include #include #include #include @@ -148,10 +149,25 @@ public: ModeSeq findModes(const std::string &mode_name) const; Sdc *cmdSdc() const; + // Read a Liberty file from a file. + // + // filename should be the path to the file, if ZLIB is included it may be + // either compressed or uncompressed. virtual LibertyLibrary *readLiberty(std::string_view filename, Scene *scene, const MinMaxAll *min_max, bool infer_latches); + // Read a Liberty file from an input stream. + // + // filename is used only as a label in diagnostic messages; it may but need + // not correspond to a file on disk. + // + // The input stream should provide uncompressed text. + virtual LibertyLibrary *readLiberty(std::istream& stream, + std::string_view filename, + Scene *scene, + const MinMaxAll *min_max, + bool infer_latches); // tmp public void readLibertyAfter(LibertyLibrary *liberty, Scene *scene, @@ -1516,6 +1532,11 @@ protected: Scene *scene, const MinMaxAll *min_max, bool infer_latches); + LibertyLibrary *readLibertyFile(std::istream& stream, + std::string_view filename, + Scene *scene, + const MinMaxAll *min_max, + bool infer_latches); void delayCalcPreamble(); void delaysInvalidFrom(const Port *port); void delaysInvalidFromFanin(const Port *port); diff --git a/liberty/LibertyParser.cc b/liberty/LibertyParser.cc index 26c0fefc1..e0029f9d0 100644 --- a/liberty/LibertyParser.cc +++ b/liberty/LibertyParser.cc @@ -49,15 +49,24 @@ parseLibertyFile(std::string_view filename, std::string fn(filename); gzstream::igzstream stream(fn.c_str()); if (stream.is_open()) { - LibertyParser reader(filename, library_visitor, report); - LibertyScanner scanner(&stream, filename, &reader, report); - LibertyParse parser(&scanner, &reader); - parser.parse(); + parseLibertyFile(stream, filename, library_visitor, report); } else throw FileNotReadable(filename); } +void +parseLibertyFile(std::istream& file_contents, + std::string_view filename, + LibertyGroupVisitor *library_visitor, + Report *report) +{ + LibertyParser reader(filename, library_visitor, report); + LibertyScanner scanner(&file_contents, filename, &reader, report); + LibertyParse parser(&scanner, &reader); + parser.parse(); +} + LibertyParser::LibertyParser(std::string_view filename, LibertyGroupVisitor *library_visitor, Report *report) : diff --git a/liberty/LibertyParser.hh b/liberty/LibertyParser.hh index 607e9d716..e3b334995 100644 --- a/liberty/LibertyParser.hh +++ b/liberty/LibertyParser.hh @@ -25,6 +25,7 @@ #pragma once #include +#include #include #include #include @@ -277,6 +278,22 @@ public: virtual void visitVariable(LibertyVariable *variable) = 0; }; +// Parse a Liberty file from an input stream. +// +// filename is used only as a label in diagnostic messages; it may but need not +// correspond to a file on disk. +// +// The input stream should provide uncompressed text. +void +parseLibertyFile(std::istream& file_contents, + std::string_view filename, + LibertyGroupVisitor *library_visitor, + Report *report); + +// Parse a Liberty file from a file. +// +// filename should be the path to the file, if ZLIB is included it may be +// either compressed or uncompressed. void parseLibertyFile(std::string_view filename, LibertyGroupVisitor *library_visitor, diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index 09733ca87..3c80c904a 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -79,6 +80,16 @@ readLibertyFile(std::string_view filename, return reader.readLibertyFile(filename); } +LibertyLibrary * +readLibertyFile(std::istream& stream, + std::string_view filename, + bool infer_latches, + Network* network) +{ + LibertyReader reader(filename, infer_latches, network); + return reader.readLibertyFile(stream); +} + LibertyReader::LibertyReader(std::string_view filename, bool infer_latches, Network *network) : @@ -100,6 +111,13 @@ LibertyReader::readLibertyFile(std::string_view filename) return library_; } +LibertyLibrary * +LibertyReader::readLibertyFile(std::istream& stream) +{ + parseLibertyFile(stream, filename_, this, report_); + return library_; +} + void LibertyReader::defineGroupVisitor(std::string_view type, LibraryGroupVisitor begin_visitor, @@ -1665,7 +1683,7 @@ LibertyReader::makeSequentials(LibertyCell *cell, makeSequentials(cell, cell_group, false, "latch", "enable", "data_in"); makeSequentials(cell, cell_group, false, "latch_bank", "enable", "data_in"); - const LibertyGroup *lut_group = cell_group->findSubgroup("lut");; + const LibertyGroup *lut_group = cell_group->findSubgroup("lut"); if (lut_group) { LibertyPort *out_port = nullptr; LibertyPort *out_port_inv = nullptr; diff --git a/liberty/LibertyReader.hh b/liberty/LibertyReader.hh index 030c42e82..297801889 100644 --- a/liberty/LibertyReader.hh +++ b/liberty/LibertyReader.hh @@ -25,6 +25,7 @@ #pragma once #include +#include namespace sta { @@ -36,4 +37,10 @@ readLibertyFile(std::string_view filename, bool infer_latches, Network *network); +LibertyLibrary * +readLibertyFile(std::istream& stream, + std::string_view filename, + bool infer_latches, + Network *network); + } // namespace sta diff --git a/liberty/LibertyReaderPvt.hh b/liberty/LibertyReaderPvt.hh index eabdc2cc8..b8a371b6a 100644 --- a/liberty/LibertyReaderPvt.hh +++ b/liberty/LibertyReaderPvt.hh @@ -70,6 +70,7 @@ public: bool infer_latches, Network *network); LibertyLibrary *readLibertyFile(std::string_view filename); + LibertyLibrary *readLibertyFile(std::istream& stream); LibertyLibrary *library() { return library_; } const LibertyLibrary *library() const { return library_; } diff --git a/search/Sta.cc b/search/Sta.cc index 61f9a2747..70a4dc617 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -709,6 +709,28 @@ Sta::readLiberty(std::string_view filename, return library; } +LibertyLibrary * +Sta::readLiberty(std::istream& stream, + std::string_view filename, + Scene* scene, + const MinMaxAll* min_max, + bool infer_latches) +{ + Stats stats(debug_, report_); + LibertyLibrary* library = + readLibertyFile(stream, filename, scene, min_max, infer_latches); + if (library + // The default library is the first library read. + // This corresponds to a link_path of '*'. + && network_->defaultLibertyLibrary() == nullptr) { + network_->setDefaultLibertyLibrary(library); + // Set units from default (first) library. + *units_ = *library->units(); + } + stats.report("Read liberty"); + return library; +} + LibertyLibrary * Sta::readLibertyFile(std::string_view filename, Scene *scene, @@ -725,6 +747,25 @@ Sta::readLibertyFile(std::string_view filename, return liberty; } + +LibertyLibrary * +Sta::readLibertyFile(std::istream& stream, + std::string_view filename, + Scene* scene, + const MinMaxAll* min_max, + bool infer_latches) +{ + LibertyLibrary* liberty = + sta::readLibertyFile(stream, filename, infer_latches, network_); + if (liberty) { + // Don't map liberty cells if they are redefined by reading another + // library with the same cell names. + readLibertyAfter(liberty, scene, min_max); + network_->readLibertyAfter(liberty); + } + return liberty; +} + void Sta::readLibertyAfter(LibertyLibrary *liberty, Scene *scene,