Skip to content

Commit 2c2fb34

Browse files
committed
Plumbed API for stream-based LibertyParser to LibertyReader.
Signed-off-by: Ted Hong <tedhong@google.com>
1 parent 34905e6 commit 2c2fb34

8 files changed

Lines changed: 135 additions & 3 deletions

File tree

include/sta/Sta.hh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#pragma once
2626

27+
#include <iosfwd>
2728
#include <map>
2829
#include <string>
2930
#include <string_view>
@@ -148,10 +149,25 @@ public:
148149
ModeSeq findModes(const std::string &mode_name) const;
149150
Sdc *cmdSdc() const;
150151

152+
// Read a Liberty file from a file.
153+
//
154+
// filename should be the path to the file, if ZLIB is included it may be
155+
// either compressed or uncompressed.
151156
virtual LibertyLibrary *readLiberty(std::string_view filename,
152157
Scene *scene,
153158
const MinMaxAll *min_max,
154159
bool infer_latches);
160+
// Read a Liberty file from an input stream.
161+
//
162+
// filename is used only as a label in diagnostic messages; it may but need
163+
// not correspond to a file on disk.
164+
//
165+
// The input stream should provide uncompressed text.
166+
virtual LibertyLibrary *readLiberty(std::istream& stream,
167+
std::string_view filename,
168+
Scene *scene,
169+
const MinMaxAll *min_max,
170+
bool infer_latches);
155171
// tmp public
156172
void readLibertyAfter(LibertyLibrary *liberty,
157173
Scene *scene,
@@ -1516,6 +1532,11 @@ protected:
15161532
Scene *scene,
15171533
const MinMaxAll *min_max,
15181534
bool infer_latches);
1535+
LibertyLibrary *readLibertyFile(std::istream& stream,
1536+
std::string_view filename,
1537+
Scene *scene,
1538+
const MinMaxAll *min_max,
1539+
bool infer_latches);
15191540
void delayCalcPreamble();
15201541
void delaysInvalidFrom(const Port *port);
15211542
void delaysInvalidFromFanin(const Port *port);

liberty/LibertyParser.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ parseLibertyFile(std::istream& file_contents,
6161
LibertyGroupVisitor *library_visitor,
6262
Report *report)
6363
{
64-
6564
LibertyParser reader(filename, library_visitor, report);
6665
LibertyScanner scanner(&file_contents, filename, &reader, report);
6766
LibertyParse parser(&scanner, &reader);

liberty/LibertyParser.hh

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#pragma once
2626

2727
#include <functional>
28-
#include <istream>
28+
#include <iosfwd>
2929
#include <string_view>
3030
#include <vector>
3131
#include <map>
@@ -278,11 +278,22 @@ public:
278278
virtual void visitVariable(LibertyVariable *variable) = 0;
279279
};
280280

281+
// Parse a Liberty file from an input stream.
282+
//
283+
// filename is used only as a label in diagnostic messages; it may but need not
284+
// correspond to a file on disk.
285+
//
286+
// The input stream should provide uncompressed text.
281287
void
282288
parseLibertyFile(std::istream& file_contents,
283289
std::string_view filename,
284290
LibertyGroupVisitor *library_visitor,
285291
Report *report);
292+
293+
// Parse a Liberty file from a file.
294+
//
295+
// filename should be the path to the file, if ZLIB is included it may be
296+
// either compressed or uncompressed.
286297
void
287298
parseLibertyFile(std::string_view filename,
288299
LibertyGroupVisitor *library_visitor,

liberty/LibertyReader.cc

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <cctype>
2828
#include <cstdlib>
2929
#include <functional>
30+
#include <istream>
3031
#include <memory>
3132
#include <set>
3233
#include <string>
@@ -79,6 +80,12 @@ readLibertyFile(std::string_view filename,
7980
return reader.readLibertyFile(filename);
8081
}
8182

83+
LibertyLibrary* readLibertyFile(std::istream& stream, std::string_view filename,
84+
bool infer_latches, Network* network) {
85+
LibertyReader reader(filename, infer_latches, network);
86+
return reader.readLibertyFile(stream);
87+
}
88+
8289
LibertyReader::LibertyReader(std::string_view filename,
8390
bool infer_latches,
8491
Network *network) :
@@ -100,6 +107,11 @@ LibertyReader::readLibertyFile(std::string_view filename)
100107
return library_;
101108
}
102109

110+
LibertyLibrary* LibertyReader::readLibertyFile(std::istream& stream) {
111+
parseLibertyFile(stream, filename_, this, report_);
112+
return library_;
113+
}
114+
103115
void
104116
LibertyReader::defineGroupVisitor(std::string_view type,
105117
LibraryGroupVisitor begin_visitor,
@@ -1665,7 +1677,7 @@ LibertyReader::makeSequentials(LibertyCell *cell,
16651677
makeSequentials(cell, cell_group, false, "latch", "enable", "data_in");
16661678
makeSequentials(cell, cell_group, false, "latch_bank", "enable", "data_in");
16671679

1668-
const LibertyGroup *lut_group = cell_group->findSubgroup("lut");;
1680+
const LibertyGroup *lut_group = cell_group->findSubgroup("lut");
16691681
if (lut_group) {
16701682
LibertyPort *out_port = nullptr;
16711683
LibertyPort *out_port_inv = nullptr;

liberty/LibertyReader.hh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#pragma once
2626

2727
#include <string_view>
28+
#include <iosfwd>
2829

2930
namespace sta {
3031

@@ -36,4 +37,10 @@ readLibertyFile(std::string_view filename,
3637
bool infer_latches,
3738
Network *network);
3839

40+
LibertyLibrary *
41+
readLibertyFile(std::istream& stream,
42+
std::string_view filename,
43+
bool infer_latches,
44+
Network *network);
45+
3946
} // namespace sta

liberty/LibertyReaderPvt.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ public:
7070
bool infer_latches,
7171
Network *network);
7272
LibertyLibrary *readLibertyFile(std::string_view filename);
73+
LibertyLibrary *readLibertyFile(std::istream& stream);
7374
LibertyLibrary *library() { return library_; }
7475
const LibertyLibrary *library() const { return library_; }
7576

liberty/test/cpp/TestLibertyStaCallbacks.cc

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <string>
33
#include <cmath>
44
#include <atomic>
5+
#include <sstream>
56
#include <unistd.h>
67
#include "Units.hh"
78
#include "TimingRole.hh"
@@ -4344,4 +4345,50 @@ library(test_mbff_statetable) {
43444345
"combinational";
43454346
}
43464347

4348+
// Verifies in-memory parsing via std::istream& without touching the filesystem.
4349+
TEST_F(StaLibertyTest,
4350+
ParserStreamOverload)
4351+
{
4352+
const char *content = R"(
4353+
library(test_stream_overload) {
4354+
delay_model : table_lookup ;
4355+
time_unit : "1ns" ;
4356+
voltage_unit : "1V" ;
4357+
current_unit : "1mA" ;
4358+
capacitive_load_unit(1, ff) ;
4359+
define(custom_attr, cell, float) ;
4360+
my_variable = 42.0 ;
4361+
cell(SV1) {
4362+
area : 1.0 ;
4363+
pin(A) { direction : input ; capacitance : 0.01 ; }
4364+
pin(Z) { direction : output ; function : "A" ; }
4365+
}
4366+
}
4367+
)";
4368+
4369+
// Feed the parser directly from memory — no temp file involved.
4370+
std::stringstream stream(content);
4371+
RecordingLibertyVisitor visitor;
4372+
parseLibertyFile(stream, "<in-memory>", &visitor, sta_->report());
4373+
4374+
// Same expectations as the file-path variant: the visitor saw a library
4375+
// group with one define, one variable, and a cell with area=1.0.
4376+
EXPECT_GT(visitor.begin_count, 0);
4377+
EXPECT_EQ(visitor.begin_count, visitor.end_count);
4378+
ASSERT_EQ(visitor.root_groups.size(), 1u);
4379+
const LibertyGroup *library = visitor.root_groups.front();
4380+
ASSERT_NE(library, nullptr);
4381+
EXPECT_EQ(library->defineMap().size(), 1u);
4382+
EXPECT_EQ(visitor.variables.size(), 1u);
4383+
EXPECT_GT(visitor.simple_attrs.size(), 0u);
4384+
4385+
const LibertyGroup *cell = library->findSubgroup("cell");
4386+
ASSERT_NE(cell, nullptr);
4387+
float area = 0.0f;
4388+
bool exists = false;
4389+
cell->findAttrFloat("area", area, exists);
4390+
EXPECT_TRUE(exists);
4391+
EXPECT_FLOAT_EQ(area, 1.0f);
4392+
}
4393+
43474394
} // namespace sta

search/Sta.cc

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,24 @@ Sta::readLiberty(std::string_view filename,
707707
return library;
708708
}
709709

710+
LibertyLibrary* Sta::readLiberty(std::istream& stream,
711+
std::string_view filename, Scene* scene,
712+
const MinMaxAll* min_max, bool infer_latches) {
713+
Stats stats(debug_, report_);
714+
LibertyLibrary* library =
715+
readLibertyFile(stream, filename, scene, min_max, infer_latches);
716+
if (library
717+
// The default library is the first library read.
718+
// This corresponds to a link_path of '*'.
719+
&& network_->defaultLibertyLibrary() == nullptr) {
720+
network_->setDefaultLibertyLibrary(library);
721+
// Set units from default (first) library.
722+
*units_ = *library->units();
723+
}
724+
stats.report("Read liberty");
725+
return library;
726+
}
727+
710728
LibertyLibrary *
711729
Sta::readLibertyFile(std::string_view filename,
712730
Scene *scene,
@@ -723,6 +741,22 @@ Sta::readLibertyFile(std::string_view filename,
723741
return liberty;
724742
}
725743

744+
745+
LibertyLibrary* Sta::readLibertyFile(std::istream& stream,
746+
std::string_view filename, Scene* scene,
747+
const MinMaxAll* min_max,
748+
bool infer_latches) {
749+
LibertyLibrary* liberty =
750+
sta::readLibertyFile(stream, filename, infer_latches, network_);
751+
if (liberty) {
752+
// Don't map liberty cells if they are redefined by reading another
753+
// library with the same cell names.
754+
readLibertyAfter(liberty, scene, min_max);
755+
network_->readLibertyAfter(liberty);
756+
}
757+
return liberty;
758+
}
759+
726760
void
727761
Sta::readLibertyAfter(LibertyLibrary *liberty,
728762
Scene *scene,

0 commit comments

Comments
 (0)