Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions include/sta/Sta.hh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#pragma once

#include <iosfwd>
#include <map>
#include <string>
#include <string_view>
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down
17 changes: 13 additions & 4 deletions liberty/LibertyParser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) :
Expand Down
17 changes: 17 additions & 0 deletions liberty/LibertyParser.hh
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#pragma once

#include <functional>
#include <iosfwd>
#include <string_view>
#include <vector>
#include <map>
Expand Down Expand Up @@ -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,
Expand Down
14 changes: 13 additions & 1 deletion liberty/LibertyReader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <cctype>
#include <cstdlib>
#include <functional>
#include <istream>
#include <memory>
#include <set>
#include <string>
Expand Down Expand Up @@ -79,6 +80,12 @@ 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) :
Expand All @@ -100,6 +107,11 @@ 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,
Expand Down Expand Up @@ -1665,7 +1677,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;
Expand Down
7 changes: 7 additions & 0 deletions liberty/LibertyReader.hh
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#pragma once

#include <string_view>
#include <iosfwd>

namespace sta {

Expand All @@ -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
1 change: 1 addition & 0 deletions liberty/LibertyReaderPvt.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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_; }

Expand Down
47 changes: 47 additions & 0 deletions liberty/test/cpp/TestLibertyStaCallbacks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <string>
#include <cmath>
#include <atomic>
#include <sstream>
#include <unistd.h>
#include "Units.hh"
#include "TimingRole.hh"
Expand Down Expand Up @@ -4344,4 +4345,50 @@ library(test_mbff_statetable) {
"combinational";
}

// Verifies in-memory parsing via std::istream& without touching the filesystem.
TEST_F(StaLibertyTest,
ParserStreamOverload)
{
const char *content = R"(
library(test_stream_overload) {
delay_model : table_lookup ;
time_unit : "1ns" ;
voltage_unit : "1V" ;
current_unit : "1mA" ;
capacitive_load_unit(1, ff) ;
define(custom_attr, cell, float) ;
my_variable = 42.0 ;
cell(SV1) {
area : 1.0 ;
pin(A) { direction : input ; capacitance : 0.01 ; }
pin(Z) { direction : output ; function : "A" ; }
}
}
)";

// Feed the parser directly from memory — no temp file involved.
std::stringstream stream(content);
RecordingLibertyVisitor visitor;
parseLibertyFile(stream, "<in-memory>", &visitor, sta_->report());

// Same expectations as the file-path variant: the visitor saw a library
// group with one define, one variable, and a cell with area=1.0.
EXPECT_GT(visitor.begin_count, 0);
EXPECT_EQ(visitor.begin_count, visitor.end_count);
ASSERT_EQ(visitor.root_groups.size(), 1u);
const LibertyGroup *library = visitor.root_groups.front();
ASSERT_NE(library, nullptr);
EXPECT_EQ(library->defineMap().size(), 1u);
EXPECT_EQ(visitor.variables.size(), 1u);
EXPECT_GT(visitor.simple_attrs.size(), 0u);

const LibertyGroup *cell = library->findSubgroup("cell");
ASSERT_NE(cell, nullptr);
float area = 0.0f;
bool exists = false;
cell->findAttrFloat("area", area, exists);
EXPECT_TRUE(exists);
EXPECT_FLOAT_EQ(area, 1.0f);
}

} // namespace sta
34 changes: 34 additions & 0 deletions search/Sta.cc
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,24 @@ 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,
Expand All @@ -723,6 +741,22 @@ 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,
Expand Down