Skip to content

Commit 8575070

Browse files
authored
Merge pull request #363 from The-OpenROAD-Project-staging/sta_update_latest_0514
Sta update latest 0514
2 parents 6766779 + 337c738 commit 8575070

23 files changed

Lines changed: 467 additions & 394 deletions

.gitignore

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,5 @@ doc/messages.txt
3131
# clangd turds
3232
.cache/
3333

34-
# test artifacts
35-
*/test/*.log
36-
**/Testing/
34+
# openroad ctest turds
35+
cmake_test*

include/sta/LevelizeObserver.hh

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// OpenSTA, Static Timing Analyzer
2+
// Copyright (c) 2026, Parallax Software, Inc.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
//
17+
// The origin of this software must not be misrepresented; you must not
18+
// claim that you wrote the original software.
19+
//
20+
// Altered source versions must be plainly marked as such, and must not be
21+
// misrepresented as being the original software.
22+
//
23+
// This notice may not be removed or altered from any source distribution.
24+
25+
#pragma once
26+
27+
namespace sta {
28+
29+
class Vertex;
30+
class Search;
31+
class GraphDelayCalc;
32+
33+
// Observer fired by Levelize during (re)levelization. Downstream consumers
34+
// override the two hooks to invalidate caches that depend on vertex levels.
35+
class LevelizeObserver
36+
{
37+
public:
38+
virtual ~LevelizeObserver() = default;
39+
virtual void levelsChangedBefore() = 0;
40+
virtual void levelChangedBefore(Vertex *vertex) = 0;
41+
};
42+
43+
// Default observer installed by Sta::makeObservers. Forwards level-change
44+
// events to Search and GraphDelayCalc so their internal caches stay
45+
// consistent. Subclass and override to extend (call the base methods first,
46+
// then add your own invalidation).
47+
class StaLevelizeObserver : public LevelizeObserver
48+
{
49+
public:
50+
StaLevelizeObserver(Search *search, GraphDelayCalc *graph_delay_calc);
51+
void levelsChangedBefore() override;
52+
void levelChangedBefore(Vertex *vertex) override;
53+
54+
private:
55+
Search *search_;
56+
GraphDelayCalc *graph_delay_calc_;
57+
};
58+
59+
} // namespace sta

include/sta/Sta.hh

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class ClkSkews;
7373
class ReportField;
7474
class EquivCells;
7575
class StaSimObserver;
76+
class LevelizeObserver;
7677
class GraphLoop;
7778

7879
using ModeNameMap = std::map<std::string, Mode*, std::less<>>;
@@ -83,6 +84,8 @@ using CheckErrorSeq = std::vector<CheckError*>;
8384
enum class CmdNamespace { sta, sdc };
8485
using ParasiticsNameMap = std::map<std::string, Parasitics*, std::less<>>;
8586
using GraphLoopSeq = std::vector<GraphLoop*>;
87+
using ReportFieldGetValue = std::function<std::string (const Path *path,
88+
const StaState *sta)>;
8689

8790
// Initialize sta functions that are not part of the Sta class.
8891
void initSta();
@@ -982,16 +985,16 @@ public:
982985
bool clk_gating_hold);
983986
void setReportPathFormat(ReportPathFormat format);
984987
void setReportPathFieldOrder(const StringSeq &field_names);
985-
void setReportPathFields(bool report_input_pin,
986-
bool report_hier_pins,
987-
bool report_net,
988-
bool report_cap,
989-
bool report_slew,
990-
bool report_fanout,
991-
bool report_variation,
992-
bool report_src_attr,
993-
bool report_orig_name);
988+
void setReportPathFields(const StringSeq &fields);
994989
ReportField *findReportPathField(std::string_view name);
990+
ReportField *findReportPathFieldAbrev(std::string_view name);
991+
void makeReportPathField(std::string_view name,
992+
std::string_view name_abrev,
993+
std::string_view title,
994+
size_t width,
995+
bool left_justify,
996+
Unit *unit,
997+
const ReportFieldGetValue &get_value);
995998
void setReportPathDigits(int digits);
996999
void setReportPathNoSplit(bool no_split);
9971000
void reportPathEnd(PathEnd *end);
@@ -1327,6 +1330,10 @@ public:
13271330
// Ensure a network has been read, linked and liberty libraries exist.
13281331
Network *ensureLibLinked();
13291332
void ensureLevelized();
1333+
// Replace the Levelize observer. Takes ownership; deletes any prior
1334+
// observer. Subclass StaLevelizeObserver to extend the default behavior
1335+
// (Search + GraphDelayCalc forwarding) without re-implementing it.
1336+
void setLevelizeObserver(LevelizeObserver *observer);
13301337
// Ensure that the timing graph has been built.
13311338
Graph *ensureGraph();
13321339
void ensureClkArrivals();

include/sta/StringUtil.hh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ stringEqual(std::string_view s1,
9191

9292
std::pair<float, bool>
9393
stringFloat(const std::string &str);
94+
std::pair<long long, bool>
95+
stringLong(const std::string &str,
96+
int base = 10);
9497

9598
bool
9699
isDigits(const char *str);

liberty/LibertyParse.yy

Lines changed: 10 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ sta::LibertyParse::error(const location_type &loc,
6262
%define api.parser.class {LibertyParse}
6363
%define api.value.type variant
6464

65-
%expect 2
65+
%expect 0
6666

6767
%token <std::string> STRING KEYWORD
6868
%token <float> FLOAT
@@ -75,8 +75,8 @@ sta::LibertyParse::error(const location_type &loc,
7575
%type <void *> statement complex_attr simple_attr variable group file
7676
%type <sta::LibertyAttrValueSeq *> attr_values
7777
%type <sta::LibertyAttrValue *> attr_value
78-
%type <std::string> string expr expr_term expr_term1 volt_expr
79-
%type <char> expr_op volt_op
78+
%type <std::string> string expr expr_term expr_term1
79+
%type <char> expr_op
8080

8181
%start file
8282

@@ -157,36 +157,8 @@ string:
157157
;
158158

159159
attr_value:
160-
FLOAT
161-
{ $$ = reader->makeAttrValueFloat($1); }
162-
| expr
160+
expr
163161
{ $$ = reader->makeAttrValueString(std::move($1)); }
164-
| volt_expr
165-
{ $$ = reader->makeAttrValueString(std::move($1)); }
166-
;
167-
168-
/* Voltage expressions are ignored. */
169-
/* Crafted to avoid conflicts with expr */
170-
volt_expr:
171-
FLOAT volt_op FLOAT
172-
{ $$ = sta::format("{}{}{}", $1, $2, $3); }
173-
| string volt_op FLOAT
174-
{ $$ = sta::format("{}{}{}", $1, $2, $3); }
175-
| FLOAT volt_op string
176-
{ $$ = sta::format("{}{}{}", $1, $2, $3); }
177-
| volt_expr volt_op FLOAT
178-
{ $$ = sta::format("{}{}{}", $1, $2, $3); }
179-
;
180-
181-
volt_op:
182-
'+'
183-
{ $$ = '+'; }
184-
| '-'
185-
{ $$ = '-'; }
186-
| '*'
187-
{ $$ = '*'; }
188-
| '/'
189-
{ $$ = '/'; }
190162
;
191163

192164
expr:
@@ -197,6 +169,8 @@ expr:
197169

198170
expr_term:
199171
string
172+
| FLOAT
173+
{ $$ = sta::format("{}", $1); }
200174
| '0'
201175
{ $$ = std::string("0"); }
202176
| '1'
@@ -224,6 +198,10 @@ expr_op:
224198
{ $$ = '&'; }
225199
| '^'
226200
{ $$ = '^'; }
201+
| '-'
202+
{ $$ = '-'; }
203+
| '/'
204+
{ $$ = '/'; }
227205
;
228206
229207
semi_opt:

liberty/LibertyParser.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,13 @@ LibertyGroup::findAttrInt(std::string_view attr_name,
513513
exists = exists1;
514514
return;
515515
}
516+
else {
517+
const std::string &int_str = attr_value.stringValue();
518+
auto [value1, valid1] = stringLong(int_str);
519+
value = value1;
520+
exists = valid1;
521+
return;
522+
}
516523
}
517524
exists = false;
518525
}

liberty/LibertyReader.cc

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2344,16 +2344,13 @@ LibertyReader::readReceiverCapacitance(const LibertyGroup *timing_group,
23442344
std::string cap_group_name1 = sta::format("{}_{}", cap_group_name, rf->to_string());
23452345
const LibertyGroup *cap_group = timing_group->findSubgroup(cap_group_name1);
23462346
if (cap_group) {
2347-
const LibertySimpleAttr *segment_attr = cap_group->findSimpleAttr("segment");
2348-
if (segment_attr) {
2349-
// For receiver_capacitance groups with mulitiple segments this
2350-
// overrides the index passed in beginReceiverCapacitance1Rise/Fall.
2351-
int segment;
2352-
bool exists;
2353-
getAttrInt(segment_attr, segment, exists);
2354-
if (exists)
2355-
index = segment;
2356-
}
2347+
// For receiver_capacitance groups with mulitiple segments this
2348+
// overrides the index passed in beginReceiverCapacitance1Rise/Fall.
2349+
int segment;
2350+
bool exists;
2351+
cap_group->findAttrInt("segment", segment, exists);
2352+
if (exists)
2353+
index = segment;
23572354
TableModel *model = readTableModel(cap_group, rf, TableTemplateType::delay,
23582355
cap_scale_, ScaleFactorType::pin_cap);
23592356
if (ReceiverModel::checkAxes(model)) {
@@ -3224,24 +3221,6 @@ LibertyReader::makeFloatTable(const LibertyComplexAttr *values_attr,
32243221

32253222
////////////////////////////////////////////////////////////////
32263223

3227-
void
3228-
LibertyReader::getAttrInt(const LibertySimpleAttr *attr,
3229-
// Return values.
3230-
int &value,
3231-
bool &exists)
3232-
{
3233-
value = 0;
3234-
exists = false;
3235-
const LibertyAttrValue &attr_value = attr->value();
3236-
if (attr_value.isFloat()) {
3237-
auto [float_val, valid] = attr_value.floatValue();
3238-
value = static_cast<int>(float_val);
3239-
exists = true;
3240-
}
3241-
else
3242-
warn(1268, attr, "{} attribute is not an integer.", attr->name());
3243-
}
3244-
32453224
// Get two floats in a complex attribute.
32463225
// attr(float1, float2);
32473226
void

liberty/LibertyReaderPvt.hh

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -418,10 +418,6 @@ protected:
418418
StateInternalValues parseStateInternalValues(StringSeq &states,
419419
const LibertySimpleAttr *attr);
420420

421-
void getAttrInt(const LibertySimpleAttr *attr,
422-
// Return values.
423-
int &value,
424-
bool &exists);
425421
void getAttrFloat2(const LibertyComplexAttr *attr,
426422
// Return values.
427423
float &value1,

network/Network.i

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,15 @@ get_attribute(const char *key)
655655
return Sta::sta()->ensureLinked()->getAttribute(self, key);
656656
}
657657

658+
void
659+
set_attribute(const char *key,
660+
const char *value)
661+
{
662+
sta::Sta *sta = Sta::sta();
663+
sta->ensureLinked();
664+
sta->networkReader()->setAttribute(self, key, value);
665+
}
666+
658667
} // Instance methods
659668

660669
%extend InstanceChildIterator {
@@ -813,4 +822,3 @@ bool has_next() { return self->hasNext(); }
813822
const Pin *next() { return self->next(); }
814823
void finish() { delete self; }
815824
} // NetConnectedPinIterator methods
816-

search/Levelize.hh

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@
3030

3131
#include "Graph.hh"
3232
#include "StaState.hh"
33+
#include "sta/LevelizeObserver.hh"
3334

3435
namespace sta {
3536

3637
class SearchPred;
37-
class LevelizeObserver;
3838
class GraphLoop;
3939

4040
using VertexEdgeIterPair = std::pair<Vertex*,VertexOutEdgeIterator*>;
@@ -133,12 +133,4 @@ private:
133133
EdgeSeq *edges_;
134134
};
135135

136-
class LevelizeObserver
137-
{
138-
public:
139-
virtual ~LevelizeObserver() = default;
140-
virtual void levelsChangedBefore() = 0;
141-
virtual void levelChangedBefore(Vertex *vertex) = 0;
142-
};
143-
144136
} // namespace sta

0 commit comments

Comments
 (0)