1 %module sta
2
3 %{
4
5 // OpenSTA, Static Timing Analyzer
6 // Copyright (c) 2021, Parallax Software, Inc.
7 //
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program. If not, see <https://www.gnu.org/licenses/>.
20
21 ////////////////////////////////////////////////////////////////
22 //
23 // Most of the TCL SWIG interface code is in this file. This and any
24 // optional interface code is %included into a final interface file
25 // used by the application.
26 //
27 // Define TCL methods for each network object. This works despite the
28 // fact that the underlying implementation does not have class methods
29 // corresponding to the TCL methods defined here.
30 //
31 // Note the function name changes from sta naming convention
32 // (lower/capitalize) to TCL naming convention (lower/underscore).
33 //
34 ////////////////////////////////////////////////////////////////
35
36 #include <limits>
37
38 #include "Machine.hh"
39 #include "StaConfig.hh" // STA_VERSION
40 #include "Stats.hh"
41 #include "Report.hh"
42 #include "Error.hh"
43 #include "StringUtil.hh"
44 #include "PatternMatch.hh"
45 #include "MinMax.hh"
46 #include "Fuzzy.hh"
47 #include "FuncExpr.hh"
48 #include "Units.hh"
49 #include "Transition.hh"
50 #include "TimingRole.hh"
51 #include "TimingArc.hh"
52 #include "Liberty.hh"
53 #include "EquivCells.hh"
54 #include "Wireload.hh"
55 #include "PortDirection.hh"
56 #include "Network.hh"
57 #include "Clock.hh"
58 #include "PortDelay.hh"
59 #include "ExceptionPath.hh"
60 #include "Sdc.hh"
61 #include "Graph.hh"
62 #include "Parasitics.hh"
63 #include "DelayCalc.hh"
64 #include "DcalcAnalysisPt.hh"
65 #include "Corner.hh"
66 #include "PathVertex.hh"
67 #include "PathRef.hh"
68 #include "PathExpanded.hh"
69 #include "PathEnd.hh"
70 #include "PathGroup.hh"
71 #include "PathAnalysisPt.hh"
72 #include "Property.hh"
73 #include "WritePathSpice.hh"
74 #include "Search.hh"
75 #include "Sta.hh"
76 #include "search/Tag.hh"
77 #include "search/CheckTiming.hh"
78 #include "search/CheckMinPulseWidths.hh"
79 #include "search/Levelize.hh"
80 #include "search/ReportPath.hh"
81 #include "search/Power.hh"
82
83 namespace sta {
84
85 ////////////////////////////////////////////////////////////////
86 //
87 // C++ helper functions used by the interface functions.
88 // These are not visible in the TCL API.
89 //
90 ////////////////////////////////////////////////////////////////
91
92 typedef Vector<Library*> LibrarySeq;
93 typedef CellSeq TmpCellSeq;
94 typedef LibertyCellSeq TmpLibertyCellSeq;
95 typedef PortSeq TmpPortSeq;
96 typedef LibertyPortSeq TmpLibertyPortSeq;
97 typedef PinSet TmpPinSet;
98 typedef PinSeq TmpPinSeq;
99 typedef InstanceSeq TmpInstanceSeq;
100 typedef InstanceSet TmpInstanceSet;
101 typedef MinPulseWidthCheckSeq::Iterator MinPulseWidthCheckSeqIterator;
102 typedef FloatSeq TmpFloatSeq;
103 typedef string TmpString;
104 typedef Set<const char*, CharPtrLess> StringSet;
105 typedef MinMaxAll MinMaxAllNull;
106 typedef ClockSet TmpClockSet;
107 typedef StringSeq TmpStringSeq;
108
109 using std::vector;
110
111 // Get the network for commands.
112 Network *
cmdNetwork()113 cmdNetwork()
114 {
115 return Sta::sta()->cmdNetwork();
116 }
117
118 // Make sure the network has been read and linked.
119 // Throwing an error means the caller doesn't have to check the result.
120 Network *
cmdLinkedNetwork()121 cmdLinkedNetwork()
122 {
123 Network *network = cmdNetwork();
124 if (network->isLinked())
125 return network;
126 else {
127 Report *report = Sta::sta()->report();
128 report->error(201, "no network has been linked.");
129 return nullptr;
130 }
131 }
132
133 // Make sure an editable network has been read and linked.
134 NetworkEdit *
cmdEditNetwork()135 cmdEditNetwork()
136 {
137 Network *network = cmdLinkedNetwork();
138 if (network->isEditable())
139 return dynamic_cast<NetworkEdit*>(network);
140 else {
141 Report *report = Sta::sta()->report();
142 report->error(202, "network does not support edits.");
143 return nullptr;
144 }
145 }
146
147 // Get the graph for commands.
148 // Throw to cmd level on failure.
149 Graph *
cmdGraph()150 cmdGraph()
151 {
152 cmdLinkedNetwork();
153 return Sta::sta()->ensureGraph();
154 }
155
156 template <class TYPE>
157 Vector<TYPE> *
tclListSeq(Tcl_Obj * const source,swig_type_info * swig_type,Tcl_Interp * interp)158 tclListSeq(Tcl_Obj *const source,
159 swig_type_info *swig_type,
160 Tcl_Interp *interp)
161 {
162 int argc;
163 Tcl_Obj **argv;
164
165 if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK
166 && argc > 0) {
167 Vector<TYPE> *seq = new Vector<TYPE>;
168 for (int i = 0; i < argc; i++) {
169 void *obj;
170 // Ignore returned TCL_ERROR because can't get swig_type_info.
171 SWIG_ConvertPtr(argv[i], &obj, swig_type, false);
172 seq->push_back(reinterpret_cast<TYPE>(obj));
173 }
174 return seq;
175 }
176 else
177 return nullptr;
178 }
179
180 LibertyLibrarySeq *
tclListSeqLibertyLibrary(Tcl_Obj * const source,Tcl_Interp * interp)181 tclListSeqLibertyLibrary(Tcl_Obj *const source,
182 Tcl_Interp *interp)
183 {
184 return tclListSeq<LibertyLibrary*>(source, SWIGTYPE_p_LibertyLibrary, interp);
185 }
186
187 vector<LibertyCell*> *
tclListSeqLibertyCell(Tcl_Obj * const source,Tcl_Interp * interp)188 tclListSeqLibertyCell(Tcl_Obj *const source,
189 Tcl_Interp *interp)
190 {
191 return tclListSeq<LibertyCell*>(source, SWIGTYPE_p_LibertyCell, interp);
192 }
193
194 template <class TYPE>
195 Set<TYPE> *
tclListSet(Tcl_Obj * const source,swig_type_info * swig_type,Tcl_Interp * interp)196 tclListSet(Tcl_Obj *const source,
197 swig_type_info *swig_type,
198 Tcl_Interp *interp)
199 {
200 int argc;
201 Tcl_Obj **argv;
202
203 if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK
204 && argc > 0) {
205 Set<TYPE> *set = new Set<TYPE>;
206 for (int i = 0; i < argc; i++) {
207 void *obj;
208 // Ignore returned TCL_ERROR because can't get swig_type_info.
209 SWIG_ConvertPtr(argv[i], &obj, swig_type, false);
210 set->insert(reinterpret_cast<TYPE>(obj));
211 }
212 return set;
213 }
214 else
215 return nullptr;
216 }
217
218 PinSet *
tclListSetPin(Tcl_Obj * const source,Tcl_Interp * interp)219 tclListSetPin(Tcl_Obj *const source,
220 Tcl_Interp *interp)
221 {
222 return tclListSet<Pin*>(source, SWIGTYPE_p_Pin, interp);
223 }
224
225 StringSet *
tclListSetConstChar(Tcl_Obj * const source,Tcl_Interp * interp)226 tclListSetConstChar(Tcl_Obj *const source,
227 Tcl_Interp *interp)
228 {
229 int argc;
230 Tcl_Obj **argv;
231
232 if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) {
233 StringSet *set = new StringSet;
234 for (int i = 0; i < argc; i++) {
235 int length;
236 const char *str = Tcl_GetStringFromObj(argv[i], &length);
237 set->insert(str);
238 }
239 return set;
240 }
241 else
242 return nullptr;
243 }
244
245 StringSeq *
tclListSeqConstChar(Tcl_Obj * const source,Tcl_Interp * interp)246 tclListSeqConstChar(Tcl_Obj *const source,
247 Tcl_Interp *interp)
248 {
249 int argc;
250 Tcl_Obj **argv;
251
252 if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) {
253 StringSeq *seq = new StringSeq;
254 for (int i = 0; i < argc; i++) {
255 int length;
256 const char *str = Tcl_GetStringFromObj(argv[i], &length);
257 seq->push_back(str);
258 }
259 return seq;
260 }
261 else
262 return nullptr;
263 }
264
265 ////////////////////////////////////////////////////////////////
266
267 TmpPinSet *
findStartpoints()268 findStartpoints()
269 {
270 PinSet *pins = new PinSet;
271 VertexPinCollector visitor(pins);
272 Sta::sta()->visitStartpoints(&visitor);
273 return pins;
274 }
275
276 TmpPinSet *
findEndpoints()277 findEndpoints()
278 {
279 PinSet *pins = new PinSet;
280 VertexPinCollector visitor(pins);
281 Sta::sta()->visitEndpoints(&visitor);
282 return pins;
283 }
284
285 void
pushPowerResultFloats(PowerResult & power,TmpFloatSeq * floats)286 pushPowerResultFloats(PowerResult &power,
287 TmpFloatSeq *floats)
288 {
289 floats->push_back(power.internal());
290 floats->push_back(power.switching());
291 floats->push_back(power.leakage());
292 floats->push_back(power.total());
293 }
294
295 ////////////////////////////////////////////////////////////////
296
297 void
tclArgError(Tcl_Interp * interp,const char * msg,const char * arg)298 tclArgError(Tcl_Interp *interp,
299 const char *msg,
300 const char *arg)
301 {
302 // Swig does not add try/catch around arg parsing so this cannot use Report::error.
303 string error_msg = "Error: ";
304 error_msg += msg;
305 char *error = stringPrint(error_msg.c_str(), arg);
306 Tcl_SetResult(interp, error, TCL_VOLATILE);
307 stringDelete(error);
308 }
309
310 void
objectListNext(const char * list,const char * type,bool & type_match,const char * & next)311 objectListNext(const char *list,
312 const char *type,
313 // Return values.
314 bool &type_match,
315 const char *&next)
316 {
317 // Default return values (failure).
318 type_match = false;
319 next = nullptr;
320 // _hexaddress_p_type
321 const char *s = list;
322 char ch = *s++;
323 if (ch == '_') {
324 while (*s && isxdigit(*s))
325 s++;
326 if ((s - list - 1) == sizeof(void*) * 2
327 && *s && *s++ == '_'
328 && *s && *s++ == 'p'
329 && *s && *s++ == '_') {
330 const char *t = type;
331 while (*s && *s != ' ') {
332 if (*s != *t)
333 return;
334 s++;
335 t++;
336 }
337 type_match = true;
338 if (*s)
339 next = s + 1;
340 else
341 next = nullptr;
342 }
343 }
344 }
345
346 } // namespace
347
348 using namespace sta;
349
350 %}
351
352 ////////////////////////////////////////////////////////////////
353 //
354 // SWIG type definitions.
355 //
356 ////////////////////////////////////////////////////////////////
357
358 // String that is deleted after crossing over to tcland.
359 %typemap(out) TmpString* {
360 string *str = $1;
361 if (str) {
362 // String is volatile because it is deleted.
363 Tcl_SetResult(interp, const_cast<char*>(str->c_str()), TCL_VOLATILE);
364 delete str;
365 }
366 else
367 Tcl_SetResult(interp, nullptr, TCL_STATIC);
368 }
369
370 %typemap(in) StringSeq* {
371 $1 = tclListSeqConstChar($input, interp);
372 }
373
374 %typemap(out) StringSeq* {
375 StringSeq *strs = $1;
376 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
377 StringSeq::Iterator str_iter(strs);
378 while (str_iter.hasNext()) {
379 const char *str = str_iter.next();
380 Tcl_Obj *obj = Tcl_NewStringObj(str, strlen(str));
381 Tcl_ListObjAppendElement(interp, list, obj);
382 }
383 Tcl_SetObjResult(interp, list);
384 }
385
386 %typemap(out) TmpStringSeq* {
387 StringSeq *strs = $1;
388 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
389 StringSeq::Iterator str_iter(strs);
390 while (str_iter.hasNext()) {
391 const char *str = str_iter.next();
392 Tcl_Obj *obj = Tcl_NewStringObj(str, strlen(str));
393 Tcl_ListObjAppendElement(interp, list, obj);
394 }
395 Tcl_SetObjResult(interp, list);
396 delete strs;
397 }
398
399 %typemap(out) Library* {
400 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
401 Tcl_SetObjResult(interp, obj);
402 }
403
404 %typemap(out) LibraryIterator* {
405 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
406 Tcl_SetObjResult(interp, obj);
407 }
408
409 %typemap(out) LibertyLibraryIterator* {
410 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
411 Tcl_SetObjResult(interp, obj);
412 }
413
414 %typemap(out) Cell* {
415 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
416 Tcl_SetObjResult(interp, obj);
417 }
418
419 %typemap(out) CellSeq* {
420 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
421 CellSeq *cells = $1;
422 CellSeq::Iterator cell_iter(cells);
423 while (cell_iter.hasNext()) {
424 Cell *cell = cell_iter.next();
425 Tcl_Obj *obj = SWIG_NewInstanceObj(cell, SWIGTYPE_p_Cell, false);
426 Tcl_ListObjAppendElement(interp, list, obj);
427 }
428 Tcl_SetObjResult(interp, list);
429 }
430
431 %typemap(out) TmpCellSeq* {
432 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
433 CellSeq *cells = $1;
434 CellSeq::Iterator cell_iter(cells);
435 while (cell_iter.hasNext()) {
436 Cell *cell = cell_iter.next();
437 Tcl_Obj *obj = SWIG_NewInstanceObj(cell, SWIGTYPE_p_Cell, false);
438 Tcl_ListObjAppendElement(interp, list, obj);
439 }
440 Tcl_SetObjResult(interp, list);
441 delete cells;
442 }
443
444 %typemap(in) vector<LibertyCell*> * {
445 $1 = tclListSeqLibertyCell($input, interp);
446 }
447
448 %typemap(out) LibertyCellSeq* {
449 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
450 LibertyCellSeq *cells = $1;
451 LibertyCellSeq::Iterator cell_iter(cells);
452 while (cell_iter.hasNext()) {
453 LibertyCell *cell = cell_iter.next();
454 Tcl_Obj *obj = SWIG_NewInstanceObj(cell, SWIGTYPE_p_LibertyCell,
455 false);
456 Tcl_ListObjAppendElement(interp, list, obj);
457 }
458 Tcl_SetObjResult(interp, list);
459 }
460
461 %typemap(out) TmpLibertyCellSeq* {
462 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
463 LibertyCellSeq *cells = $1;
464 LibertyCellSeq::Iterator cell_iter(cells);
465 while (cell_iter.hasNext()) {
466 LibertyCell *cell = cell_iter.next();
467 Tcl_Obj *obj = SWIG_NewInstanceObj(cell, SWIGTYPE_p_LibertyCell,
468 false);
469 Tcl_ListObjAppendElement(interp, list, obj);
470 }
471 Tcl_SetObjResult(interp, list);
472 delete cells;
473 }
474
475 %typemap(out) CellPortIterator* {
476 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
477 Tcl_SetObjResult(interp, obj);
478 }
479
480 %typemap(out) LibertyCellPortIterator* {
481 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
482 Tcl_SetObjResult(interp, obj);
483 }
484
485 %typemap(out) Port* {
486 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
487 Tcl_SetObjResult(interp, obj);
488 }
489
490 %typemap(in) PortSet* {
491 $1 = tclListSet<Port*>($input, SWIGTYPE_p_Port, interp);
492 }
493
494 %typemap(in) PortSeq* {
495 $1 = tclListSeq<Port*>($input, SWIGTYPE_p_Port, interp);
496 }
497
498 %typemap(out) TmpPortSeq* {
499 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
500 TmpPortSeq *ports = $1;
501 TmpPortSeq::Iterator port_iter(ports);
502 while (port_iter.hasNext()) {
503 Port *port = port_iter.next();
504 Tcl_Obj *obj = SWIG_NewInstanceObj(port, SWIGTYPE_p_Port, false);
505 Tcl_ListObjAppendElement(interp, list, obj);
506 }
507 delete ports;
508 Tcl_SetObjResult(interp, list);
509 }
510
511 %typemap(out) TmpLibertyPortSeq* {
512 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
513 TmpLibertyPortSeq *ports = $1;
514 TmpLibertyPortSeq::Iterator port_iter(ports);
515 while (port_iter.hasNext()) {
516 LibertyPort *port = port_iter.next();
517 Tcl_Obj *obj = SWIG_NewInstanceObj(port, SWIGTYPE_p_LibertyPort,
518 false);
519 Tcl_ListObjAppendElement(interp, list, obj);
520 }
521 delete ports;
522 Tcl_SetObjResult(interp, list);
523 }
524
525 %typemap(out) TmpPinSet* {
526 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
527 PinSet *pins = $1;
528 PinSet::Iterator pin_iter(pins);
529 while (pin_iter.hasNext()) {
530 Pin *pin = pin_iter.next();
531 Tcl_Obj *obj = SWIG_NewInstanceObj(pin, SWIGTYPE_p_Pin, false);
532 Tcl_ListObjAppendElement(interp, list, obj);
533 }
534 delete pins;
535 Tcl_SetObjResult(interp, list);
536 }
537
538 %typemap(out) TmpPinSeq* {
539 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
540 PinSeq *pins = $1;
541 PinSeq::Iterator pin_iter(pins);
542 while (pin_iter.hasNext()) {
543 Pin *pin = pin_iter.next();
544 Tcl_Obj *obj = SWIG_NewInstanceObj(pin, SWIGTYPE_p_Pin, false);
545 Tcl_ListObjAppendElement(interp, list, obj);
546 }
547 delete pins;
548 Tcl_SetObjResult(interp, list);
549 }
550
551 %typemap(out) PortMemberIterator* {
552 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
553 Tcl_SetObjResult(interp, obj);
554 }
555
556 %typemap(out) LibertyCell* {
557 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
558 Tcl_SetObjResult(interp, obj);
559 }
560
561 %typemap(out) LibertyPort* {
562 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
563 Tcl_SetObjResult(interp, obj);
564 }
565
566 %typemap(out) LibertyPortMemberIterator* {
567 Tcl_Obj *obj = SWIG_NewInstanceObj($1,
568 SWIGTYPE_p_LibertyPortMemberIterator,
569 false);
570 Tcl_SetObjResult(interp, obj);
571 }
572
573 %typemap(out) TimingArc* {
574 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
575 Tcl_SetObjResult(interp, obj);
576 }
577
578 %typemap(out) Wireload* {
579 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
580 Tcl_SetObjResult(interp, obj);
581 }
582
583 %typemap(out) WireloadSelection* {
584 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
585 Tcl_SetObjResult(interp, obj);
586 }
587
588 %typemap(in) Transition* {
589 int length;
590 const char *arg = Tcl_GetStringFromObj($input, &length);
591 Transition *tr = Transition::find(arg);
592 if (tr == nullptr) {
593 Tcl_SetResult(interp,const_cast<char*>("Error: transition not found."),
594 TCL_STATIC);
595 return TCL_ERROR;
596 }
597 else
598 $1 = tr;
599 }
600
601 %typemap(out) Transition* {
602 Transition *tr = $1;
603 const char *str = "";
604 if (tr)
605 str = tr->asString();
606 Tcl_SetResult(interp, const_cast<char*>(str), TCL_STATIC);
607 }
608
609 %typemap(in) RiseFall* {
610 int length;
611 const char *arg = Tcl_GetStringFromObj($input, &length);
612 RiseFall *tr = RiseFall::find(arg);
613 if (tr == nullptr) {
614 Tcl_SetResult(interp,const_cast<char*>("Error: unknown transition name."),
615 TCL_STATIC);
616 return TCL_ERROR;
617 }
618 $1 = tr;
619 }
620
621 %typemap(out) RiseFall* {
622 const RiseFall *tr = $1;
623 const char *str = "";
624 if (tr)
625 str = tr->asString();
626 Tcl_SetResult(interp, const_cast<char*>(str), TCL_STATIC);
627 }
628
629 %typemap(in) RiseFallBoth* {
630 int length;
631 const char *arg = Tcl_GetStringFromObj($input, &length);
632 RiseFallBoth *tr = RiseFallBoth::find(arg);
633 if (tr == nullptr) {
634 Tcl_SetResult(interp,const_cast<char*>("Error: unknown transition name."),
635 TCL_STATIC);
636 return TCL_ERROR;
637 }
638 $1 = tr;
639 }
640
641 %typemap(out) RiseFallBoth* {
642 RiseFallBoth *tr = $1;
643 const char *str = "";
644 if (tr)
645 str = tr->asString();
646 Tcl_SetResult(interp, const_cast<char*>(str), TCL_STATIC);
647 }
648
649 %typemap(in) TimingRole* {
650 int length;
651 const char *arg = Tcl_GetStringFromObj($input, &length);
652 TimingRole *role = TimingRole::find(arg);
653 if (role)
654 $1 = TimingRole::find(arg);
655 else {
656 Tcl_SetResult(interp,const_cast<char*>("Error: unknown timing role."),
657 TCL_STATIC);
658 return TCL_ERROR;
659 }
660 }
661
662 %typemap(out) TimingRole* {
663 Tcl_SetResult(interp, const_cast<char*>($1->asString()), TCL_STATIC);
664 }
665
666 %typemap(in) LogicValue {
667 int length;
668 const char *arg = Tcl_GetStringFromObj($input, &length);
669 if (stringEq(arg, "0") || stringEq(arg, "zero"))
670 $1 = LogicValue::zero;
671 else if (stringEq(arg, "1") || stringEq(arg, "one"))
672 $1 = LogicValue::one;
673 else if (stringEq(arg, "X"))
674 $1 = LogicValue::unknown;
675 else if (stringEq(arg, "rise") || stringEq(arg, "rising"))
676 $1 = LogicValue::rise;
677 else if (stringEq(arg, "fall") || stringEq(arg, "falling"))
678 $1 = LogicValue::fall;
679 else {
680 Tcl_SetResult(interp,const_cast<char*>("Error: unknown logic value."),
681 TCL_STATIC);
682 return TCL_ERROR;
683 }
684 }
685
686 %typemap(in) AnalysisType {
687 int length;
688 const char *arg = Tcl_GetStringFromObj($input, &length);
689 if (stringEqual(arg, "single"))
690 $1 = AnalysisType::single;
691 else if (stringEqual(arg, "bc_wc"))
692 $1 = AnalysisType::bc_wc;
693 else if (stringEq(arg, "on_chip_variation"))
694 $1 = AnalysisType::ocv;
695 else {
696 Tcl_SetResult(interp,const_cast<char*>("Error: unknown analysis type."),
697 TCL_STATIC);
698
699 return TCL_ERROR;
700 }
701 }
702
703 %typemap(out) Instance* {
704 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
705 Tcl_SetObjResult(interp, obj);
706 }
707
708 %typemap(in) InstanceSeq* {
709 $1 = tclListSeq<Instance*>($input, SWIGTYPE_p_Instance, interp);
710 }
711
712 %typemap(out) TmpInstanceSeq* {
713 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
714 TmpInstanceSeq *insts = $1;
715 TmpInstanceSeq::Iterator inst_iter(insts);
716 while (inst_iter.hasNext()) {
717 Instance *inst = inst_iter.next();
718 Tcl_Obj *obj = SWIG_NewInstanceObj(inst, SWIGTYPE_p_Instance,false);
719 Tcl_ListObjAppendElement(interp, list, obj);
720 }
721 delete insts;
722 Tcl_SetObjResult(interp, list);
723 }
724
725 %typemap(out) InstanceChildIterator* {
726 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
727 Tcl_SetObjResult(interp, obj);
728 }
729
730 %typemap(out) LeafInstanceIterator* {
731 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
732 Tcl_SetObjResult(interp, obj);
733 }
734
735 %typemap(out) InstancePinIterator* {
736 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
737 Tcl_SetObjResult(interp, obj);
738 }
739
740 %typemap(out) InstanceNetIterator* {
741 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
742 Tcl_SetObjResult(interp, obj);
743 }
744
745 %typemap(out) Pin* {
746 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
747 Tcl_SetObjResult(interp, obj);
748 }
749
750 %typemap(out) PinSeq* {
751 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
752 PinSeq *pins = $1;
753 PinSeq::Iterator pin_iter(pins);
754 while (pin_iter.hasNext()) {
755 Pin *pin = pin_iter.next();
756 Tcl_Obj *obj = SWIG_NewInstanceObj(pin, SWIGTYPE_p_Pin, false);
757 Tcl_ListObjAppendElement(interp, list, obj);
758 }
759 delete pins;
760 Tcl_SetObjResult(interp, list);
761 }
762
763 %typemap(out) Net* {
764 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
765 Tcl_SetObjResult(interp, obj);
766 }
767
768 %typemap(out) NetSeq* {
769 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
770 NetSeq *nets = $1;
771 NetSeq::Iterator net_iter(nets);
772 while (net_iter.hasNext()) {
773 Net *net = net_iter.next();
774 Tcl_Obj *obj = SWIG_NewInstanceObj(net, SWIGTYPE_p_Net, false);
775 Tcl_ListObjAppendElement(interp, list, obj);
776 }
777 delete nets;
778 Tcl_SetObjResult(interp, list);
779 }
780
781 %typemap(out) NetPinIterator* {
782 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
783 Tcl_SetObjResult(interp, obj);
784 }
785
786 %typemap(out) NetTermIterator* {
787 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
788 Tcl_SetObjResult(interp, obj);
789 }
790
791 %typemap(out) NetConnectedPinIterator* {
792 Tcl_Obj *obj=SWIG_NewInstanceObj($1, $1_descriptor, false);
793 Tcl_SetObjResult(interp, obj);
794 }
795
796 %typemap(out) PinConnectedPinIterator* {
797 Tcl_Obj *obj=SWIG_NewInstanceObj($1, $1_descriptor, false);
798 Tcl_SetObjResult(interp, obj);
799 }
800
801 %typemap(out) Clock* {
802 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
803 Tcl_SetObjResult(interp, obj);
804 }
805
806 %typemap(out) ClockSeq* {
807 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
808 ClockSeq *clks = $1;
809 ClockSeq::Iterator clk_iter(clks);
810 while (clk_iter.hasNext()) {
811 Clock *clk = clk_iter.next();
812 Tcl_Obj *obj = SWIG_NewInstanceObj(clk, SWIGTYPE_p_Clock, false);
813 Tcl_ListObjAppendElement(interp, list, obj);
814 }
815 delete clks;
816 Tcl_SetObjResult(interp, list);
817 }
818
819 %typemap(out) ClockIterator* {
820 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
821 Tcl_SetObjResult(interp, obj);
822 }
823
824 %typemap(out) ClockEdge* {
825 Tcl_Obj *obj = SWIG_NewInstanceObj($1,$1_descriptor, false);
826 Tcl_SetObjResult(interp, obj);
827 }
828
829 %typemap(in) FloatSeq* {
830 int argc;
831 Tcl_Obj **argv;
832 FloatSeq *floats = nullptr;
833
834 if (Tcl_ListObjGetElements(interp, $input, &argc, &argv) == TCL_OK) {
835 if (argc)
836 floats = new FloatSeq;
837 for (int i = 0; i < argc; i++) {
838 char *arg = Tcl_GetString(argv[i]);
839 double value;
840 if (Tcl_GetDouble(interp, arg, &value) == TCL_OK)
841 floats->push_back(static_cast<float>(value));
842 else {
843 delete floats;
844 tclArgError(interp, "%s is not a floating point number.", arg);
845 return TCL_ERROR;
846 }
847 }
848 }
849 $1 = floats;
850 }
851
852 %typemap(out) FloatSeq* {
853 FloatSeq *floats = $1;
854 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
855 if (floats) {
856 for (unsigned i = 0; i < floats->size(); i++) {
857 Tcl_Obj *obj = Tcl_NewDoubleObj((*floats)[i]);
858 Tcl_ListObjAppendElement(interp, list, obj);
859 }
860 }
861 Tcl_SetObjResult(interp, list);
862 }
863
864 %typemap(out) TmpFloatSeq* {
865 FloatSeq *floats = $1;
866 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
867 if (floats) {
868 for (unsigned i = 0; i < floats->size(); i++) {
869 Tcl_Obj *obj = Tcl_NewDoubleObj((*floats)[i]);
870 Tcl_ListObjAppendElement(interp, list, obj);
871 }
872 delete floats;
873 }
874 Tcl_SetObjResult(interp, list);
875 }
876
877 %typemap(in) IntSeq* {
878 int argc;
879 Tcl_Obj **argv;
880 IntSeq *ints = nullptr;
881
882 if (Tcl_ListObjGetElements(interp, $input, &argc, &argv) == TCL_OK) {
883 if (argc)
884 ints = new IntSeq;
885 for (int i = 0; i < argc; i++) {
886 char *arg = Tcl_GetString(argv[i]);
887 int value;
888 if (Tcl_GetInt(interp, arg, &value) == TCL_OK)
889 ints->push_back(value);
890 else {
891 delete ints;
892 tclArgError(interp, "%s is not an integer.", arg);
893 return TCL_ERROR;
894 }
895 }
896 }
897 $1 = ints;
898 }
899
900 %typemap(in) MinMax* {
901 int length;
902 char *arg = Tcl_GetStringFromObj($input, &length);
903 MinMax *min_max = MinMax::find(arg);
904 if (min_max)
905 $1 = min_max;
906 else {
907 tclArgError(interp, "%s not min or max.", arg);
908 return TCL_ERROR;
909 }
910 }
911
912 %typemap(out) MinMax* {
913 Tcl_SetResult(interp, const_cast<char*>($1->asString()), TCL_STATIC);
914 }
915
916 %typemap(out) MinMax* {
917 Tcl_SetResult(interp, const_cast<char*>($1->asString()), TCL_STATIC);
918 }
919
920 %typemap(in) MinMaxAll* {
921 int length;
922 char *arg = Tcl_GetStringFromObj($input, &length);
923 MinMaxAll *min_max = MinMaxAll::find(arg);
924 if (min_max)
925 $1 = min_max;
926 else {
927 tclArgError(interp, "%s not min, max or min_max.", arg);
928 return TCL_ERROR;
929 }
930 }
931
932 %typemap(in) MinMaxAllNull* {
933 int length;
934 char *arg = Tcl_GetStringFromObj($input, &length);
935 if (stringEqual(arg, "NULL"))
936 $1 = nullptr;
937 else {
938 MinMaxAll *min_max = MinMaxAll::find(arg);
939 if (min_max)
940 $1 = min_max;
941 else {
942 tclArgError(interp, "%s not min, max or min_max.", arg);
943 return TCL_ERROR;
944 }
945 }
946 }
947
948 %typemap(out) MinMaxAll* {
949 Tcl_SetResult(interp, const_cast<char*>($1->asString()), TCL_STATIC);
950 }
951
952 // SetupHold is typedef'd to MinMax.
953 %typemap(in) SetupHold* {
954 int length;
955 char *arg = Tcl_GetStringFromObj($input, &length);
956 if (stringEqual(arg, "hold")
957 || stringEqual(arg, "min"))
958 $1 = MinMax::min();
959 else if (stringEqual(arg, "setup")
960 || stringEqual(arg, "max"))
961 $1 = MinMax::max();
962 else {
963 tclArgError(interp, "%s not setup, hold, min or max.", arg);
964 return TCL_ERROR;
965 }
966 }
967
968 // SetupHoldAll is typedef'd to MinMaxAll.
969 %typemap(in) SetupHoldAll* {
970 int length;
971 char *arg = Tcl_GetStringFromObj($input, &length);
972 if (stringEqual(arg, "hold")
973 || stringEqual(arg, "min"))
974 $1 = SetupHoldAll::min();
975 else if (stringEqual(arg, "setup")
976 || stringEqual(arg, "max"))
977 $1 = SetupHoldAll::max();
978 else if (stringEqual(arg, "setup_hold")
979 || stringEqual(arg, "min_max"))
980 $1 = SetupHoldAll::all();
981 else {
982 tclArgError(interp, "%s not setup, hold, setup_hold, min, max or min_max.", arg);
983 return TCL_ERROR;
984 }
985 }
986
987 // EarlyLate is typedef'd to MinMax.
988 %typemap(in) EarlyLate* {
989 int length;
990 char *arg = Tcl_GetStringFromObj($input, &length);
991 EarlyLate *early_late = EarlyLate::find(arg);
992 if (early_late)
993 $1 = early_late;
994 else {
995 tclArgError(interp, "%s not early/min, late/max or early_late/min_max.", arg);
996 return TCL_ERROR;
997 }
998 }
999
1000 // EarlyLateAll is typedef'd to MinMaxAll.
1001 %typemap(in) EarlyLateAll* {
1002 int length;
1003 char *arg = Tcl_GetStringFromObj($input, &length);
1004 EarlyLateAll *early_late = EarlyLateAll::find(arg);
1005 if (early_late)
1006 $1 = early_late;
1007 else {
1008 tclArgError(interp, "%s not early/min, late/max or early_late/min_max.", arg);
1009 return TCL_ERROR;
1010 }
1011 }
1012
1013 %typemap(in) TimingDerateType {
1014 int length;
1015 char *arg = Tcl_GetStringFromObj($input, &length);
1016 if (stringEq(arg, "net_delay"))
1017 $1 = TimingDerateType::net_delay;
1018 else if (stringEq(arg, "cell_delay"))
1019 $1 = TimingDerateType::cell_delay;
1020 else if (stringEq(arg, "cell_check"))
1021 $1 = TimingDerateType::cell_check;
1022 else {
1023 tclArgError(interp, "%s not clk or data.", arg);
1024 return TCL_ERROR;
1025 }
1026 }
1027
1028 %typemap(in) PathClkOrData {
1029 int length;
1030 char *arg = Tcl_GetStringFromObj($input, &length);
1031 if (stringEq(arg, "clk"))
1032 $1 = PathClkOrData::clk;
1033 else if (stringEq(arg, "data"))
1034 $1 = PathClkOrData::data;
1035 else {
1036 tclArgError(interp, "%s not clk or data.", arg);
1037 return TCL_ERROR;
1038 }
1039 }
1040
1041 %typemap(in) ReportSortBy {
1042 int length;
1043 char *arg = Tcl_GetStringFromObj($input, &length);
1044 if (stringEq(arg, "group"))
1045 $1 = sort_by_group;
1046 else if (stringEq(arg, "slack"))
1047 $1 = sort_by_slack;
1048 else {
1049 tclArgError(interp, "%s not group or slack.", arg);
1050 return TCL_ERROR;
1051 }
1052 }
1053
1054 %typemap(in) ReportPathFormat {
1055 int length;
1056 char *arg = Tcl_GetStringFromObj($input, &length);
1057 if (stringEq(arg, "full"))
1058 $1 = ReportPathFormat::full;
1059 else if (stringEq(arg, "full_clock"))
1060 $1 = ReportPathFormat::full_clock;
1061 else if (stringEq(arg, "full_clock_expanded"))
1062 $1 = ReportPathFormat::full_clock_expanded;
1063 else if (stringEq(arg, "short"))
1064 $1 = ReportPathFormat::shorter;
1065 else if (stringEq(arg, "end"))
1066 $1 = ReportPathFormat::endpoint;
1067 else if (stringEq(arg, "summary"))
1068 $1 = ReportPathFormat::summary;
1069 else if (stringEq(arg, "slack_only"))
1070 $1 = ReportPathFormat::slack_only;
1071 else if (stringEq(arg, "json"))
1072 $1 = ReportPathFormat::json;
1073 else {
1074 tclArgError(interp, "unknown path type %s.", arg);
1075 return TCL_ERROR;
1076 }
1077 }
1078
1079 %typemap(in) PinSeq* {
1080 $1 = tclListSeq<Pin*>($input, SWIGTYPE_p_Pin, interp);
1081 }
1082
1083 %typemap(in) PinSet* {
1084 $1 = tclListSetPin($input, interp);
1085 }
1086
1087 %typemap(out) PinSet* {
1088 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
1089 const PinSet *pins = $1;
1090 if (pins) {
1091 PinSet::ConstIterator pin_iter(pins);
1092 while (pin_iter.hasNext()) {
1093 Pin *pin = pin_iter.next();
1094 Tcl_Obj *obj = SWIG_NewInstanceObj(pin, SWIGTYPE_p_Pin, false);
1095 Tcl_ListObjAppendElement(interp, list, obj);
1096 }
1097 }
1098 Tcl_SetObjResult(interp, list);
1099 }
1100
1101 %typemap(out) PinSet& {
1102 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
1103 const PinSet *pins = $1;
1104 if (pins) {
1105 PinSet::ConstIterator pin_iter(pins);
1106 while (pin_iter.hasNext()) {
1107 Pin *pin = pin_iter.next();
1108 Tcl_Obj *obj = SWIG_NewInstanceObj(pin, SWIGTYPE_p_Pin, false);
1109 Tcl_ListObjAppendElement(interp, list, obj);
1110 }
1111 }
1112 Tcl_SetObjResult(interp, list);
1113 }
1114
1115 %typemap(in) ClockSet* {
1116 $1 = tclListSet<Clock*>($input, SWIGTYPE_p_Clock, interp);
1117 }
1118
1119 %typemap(out) ClockSet* {
1120 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
1121 const ClockSet *clks = $1;
1122 if (clks) {
1123 ClockSet::ConstIterator clk_iter(clks);
1124 while (clk_iter.hasNext()) {
1125 Clock *clk = clk_iter.next();
1126 Tcl_Obj *obj = SWIG_NewInstanceObj(clk, SWIGTYPE_p_Clock, false);
1127 Tcl_ListObjAppendElement(interp, list, obj);
1128 }
1129 }
1130 Tcl_SetObjResult(interp, list);
1131 }
1132
1133 %typemap(out) TmpClockSet* {
1134 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
1135 const ClockSet *clks = $1;
1136 if (clks) {
1137 ClockSet::ConstIterator clk_iter(clks);
1138 while (clk_iter.hasNext()) {
1139 Clock *clk = clk_iter.next();
1140 Tcl_Obj *obj = SWIG_NewInstanceObj(clk, SWIGTYPE_p_Clock, false);
1141 Tcl_ListObjAppendElement(interp, list, obj);
1142 }
1143 delete clks;
1144 }
1145 Tcl_SetObjResult(interp, list);
1146 }
1147
1148 %typemap(in) InstanceSet* {
1149 $1 = tclListSet<Instance*>($input, SWIGTYPE_p_Instance, interp);
1150 }
1151
1152 %typemap(out) TmpInstanceSet* {
1153 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
1154 InstanceSet *insts = $1;
1155 InstanceSet::Iterator inst_iter(insts);
1156 while (inst_iter.hasNext()) {
1157 Instance *inst = inst_iter.next();
1158 Tcl_Obj *obj = SWIG_NewInstanceObj(inst, SWIGTYPE_p_Instance,false);
1159 Tcl_ListObjAppendElement(interp, list, obj);
1160 }
1161 delete insts;
1162 Tcl_SetObjResult(interp, list);
1163 }
1164
1165 %typemap(in) NetSet* {
1166 $1 = tclListSet<Net*>($input, SWIGTYPE_p_Net, interp);
1167 }
1168
1169 %typemap(in) ExceptionThruSeq* {
1170 $1 = tclListSeq<ExceptionThru*>($input, SWIGTYPE_p_ExceptionThru, interp);
1171 }
1172
1173 %typemap(out) Vertex* {
1174 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
1175 Tcl_SetObjResult(interp, obj);
1176 }
1177
1178 %typemap(out) Vertex** {
1179 int i = 0;
1180 Tcl_ResetResult(interp);
1181 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
1182 while ($1[i]) {
1183 Tcl_Obj *obj = SWIG_NewInstanceObj($1[i], SWIGTYPE_p_Vertex,false);
1184 Tcl_ListObjAppendElement(interp, list, obj);
1185 i++;
1186 }
1187 Tcl_SetObjResult(interp, list);
1188 }
1189
1190 %typemap(in) EdgeSeq* {
1191 $1 = tclListSeq<Edge*>($input, SWIGTYPE_p_Edge, interp);
1192 }
1193
1194 %typemap(out) Edge* {
1195 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
1196 Tcl_SetObjResult(interp, obj);
1197 }
1198
1199 %typemap(out) EdgeSeq* {
1200 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
1201 EdgeSeq *edges = $1;
1202 EdgeSeq::Iterator edge_iter(edges);
1203 while (edge_iter.hasNext()) {
1204 Edge *edge = edge_iter.next();
1205 Tcl_Obj *obj = SWIG_NewInstanceObj(edge, SWIGTYPE_p_Edge, false);
1206 Tcl_ListObjAppendElement(interp, list, obj);
1207 }
1208 delete edges;
1209 Tcl_SetObjResult(interp, list);
1210 }
1211
1212 %typemap(out) VertexIterator* {
1213 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
1214 Tcl_SetObjResult(interp, obj);
1215 }
1216
1217 %typemap(out) VertexInEdgeIterator* {
1218 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
1219 Tcl_SetObjResult(interp, obj);
1220 }
1221
1222 %typemap(out) VertexOutEdgeIterator* {
1223 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
1224 Tcl_SetObjResult(interp, obj);
1225 }
1226
1227 %typemap(out) TimingArcSetArcIterator* {
1228 Tcl_Obj *obj=SWIG_NewInstanceObj($1, $1_descriptor, false);
1229 Tcl_SetObjResult(interp, obj);
1230 }
1231
1232 %typemap(out) LibertyCellTimingArcSetIterator* {
1233 Tcl_Obj *obj=SWIG_NewInstanceObj($1, $1_descriptor, false);
1234 Tcl_SetObjResult(interp, obj);
1235 }
1236
1237 %typemap(out) CheckErrorSeq & {
1238 Tcl_Obj *error_list = Tcl_NewListObj(0, nullptr);
1239 CheckErrorSeq *check_errors = $1;
1240 CheckErrorSeq::Iterator check_iter(check_errors);
1241 while (check_iter.hasNext()) {
1242 CheckError *error = check_iter.next();
1243 Tcl_Obj *string_list = Tcl_NewListObj(0, nullptr);
1244 CheckError::Iterator string_iter(error);
1245 while (string_iter.hasNext()) {
1246 const char *str = string_iter.next();
1247 size_t str_len = strlen(str);
1248 Tcl_Obj *obj = Tcl_NewStringObj(const_cast<char*>(str),
1249 static_cast<int>(str_len));
1250 Tcl_ListObjAppendElement(interp, string_list, obj);
1251 }
1252 Tcl_ListObjAppendElement(interp, error_list, string_list);
1253 }
1254 Tcl_SetObjResult(interp, error_list);
1255 }
1256
1257 %typemap(out) PathEnd* {
1258 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
1259 Tcl_SetObjResult(interp, obj);
1260 }
1261
1262 %typemap(out) PathEndSeq* {
1263 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
1264 const PathEndSeq *path_ends = $1;
1265 PathEndSeq::ConstIterator end_iter(path_ends);
1266 while (end_iter.hasNext()) {
1267 PathEnd *path_end = end_iter.next();
1268 Tcl_Obj *obj = SWIG_NewInstanceObj(path_end, SWIGTYPE_p_PathEnd, false);
1269 Tcl_ListObjAppendElement(interp, list, obj);
1270 }
1271 // Delete the PathEndSeq, not the ends.
1272 delete path_ends;
1273 Tcl_SetObjResult(interp, list);
1274 }
1275
1276 %typemap(out) MinPulseWidthCheckSeqIterator* {
1277 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
1278 Tcl_SetObjResult(interp, obj);
1279 }
1280
1281 %typemap(out) PathRefSeq* {
1282 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
1283 Tcl_SetObjResult(interp, obj);
1284
1285 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
1286 PathRefSeq *paths = $1;
1287 PathRefSeq::Iterator path_iter(paths);
1288 while (path_iter.hasNext()) {
1289 PathRef *path = &path_iter.next();
1290 PathRef *copy = new PathRef(path);
1291 Tcl_Obj *obj = SWIG_NewInstanceObj(copy, SWIGTYPE_p_PathRef, false);
1292 Tcl_ListObjAppendElement(interp, list, obj);
1293 }
1294 Tcl_SetObjResult(interp, list);
1295 }
1296
1297 %typemap(out) MinPulseWidthCheck* {
1298 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
1299 Tcl_SetObjResult(interp, obj);
1300 }
1301
1302 %typemap(out) MinPulseWidthCheckSeq & {
1303 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
1304 Tcl_SetObjResult(interp, obj);
1305 }
1306
1307 %typemap(out) MinPulseWidthCheckSeqIterator & {
1308 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
1309 Tcl_SetObjResult(interp, obj);
1310 }
1311
1312 %typemap(out) VertexPathIterator* {
1313 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
1314 Tcl_SetObjResult(interp, obj);
1315 }
1316
1317 %typemap(out) SlowDrvrIterator* {
1318 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
1319 Tcl_SetObjResult(interp, obj);
1320 }
1321
1322 %typemap(out) ExceptionFrom* {
1323 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
1324 Tcl_SetObjResult(interp, obj);
1325 }
1326
1327 %typemap(out) ExceptionTo* {
1328 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
1329 Tcl_SetObjResult(interp, obj);
1330 }
1331
1332 %typemap(out) ExceptionThru* {
1333 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
1334 Tcl_SetObjResult(interp, obj);
1335 }
1336
1337 %typemap(out) OperatingConditions* {
1338 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
1339 Tcl_SetObjResult(interp, obj);
1340 }
1341
1342 %typemap(in) ReducedParasiticType {
1343 int length;
1344 char *arg = Tcl_GetStringFromObj($input, &length);
1345 if (stringEq(arg, "pi_elmore"))
1346 $1 = ReducedParasiticType::pi_elmore;
1347 else if (stringEq(arg, "pi_pole_residue2"))
1348 $1 = ReducedParasiticType::pi_pole_residue2;
1349 else if (stringEq(arg, "none"))
1350 $1 = ReducedParasiticType::none;
1351 else {
1352 tclArgError(interp, "%s pi_elmore, pi_pole_residue2, or none.", arg);
1353 return TCL_ERROR;
1354 }
1355 }
1356
1357 %typemap(out) Arrival {
1358 Tcl_SetObjResult(interp,Tcl_NewDoubleObj(delayAsFloat($1)));
1359 }
1360
1361 %typemap(out) Required {
1362 Tcl_SetObjResult(interp,Tcl_NewDoubleObj(delayAsFloat($1)));
1363 }
1364
1365 %typemap(out) Slack {
1366 Tcl_SetObjResult(interp,Tcl_NewDoubleObj(delayAsFloat($1)));
1367 }
1368
1369 %typemap(out) ArcDelay {
1370 Tcl_SetObjResult(interp,Tcl_NewDoubleObj(delayAsFloat($1)));
1371 }
1372
1373 %typemap(out) Slew {
1374 Tcl_SetObjResult(interp,Tcl_NewDoubleObj(delayAsFloat($1)));
1375 }
1376
1377 %typemap(in) PathGroupNameSet* {
1378 $1 = tclListSetConstChar($input, interp);
1379 }
1380
1381 %typemap(in) StringSet* {
1382 $1 = tclListSetConstChar($input, interp);
1383 }
1384
1385 %typemap(out) Corner* {
1386 Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
1387 Tcl_SetObjResult(interp, obj);
1388 }
1389
1390 %typemap(out) Corners* {
1391 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
1392 Corners *corners = $1;
1393 for (Corner *corner : *corners) {
1394 Tcl_Obj *obj = SWIG_NewInstanceObj(corner, SWIGTYPE_p_Corner, false);
1395 Tcl_ListObjAppendElement(interp, list, obj);
1396 }
1397 Tcl_SetObjResult(interp, list);
1398 }
1399
1400 %typemap(out) PropertyValue {
1401 PropertyValue value = $1;
1402 switch (value.type()) {
1403 case PropertyValue::Type::type_none:
1404 Tcl_SetResult(interp, const_cast<char*>(""), TCL_STATIC);
1405 break;
1406 case PropertyValue::Type::type_string:
1407 Tcl_SetResult(interp, const_cast<char*>(value.stringValue()), TCL_VOLATILE);
1408 break;
1409 case PropertyValue::Type::type_float: {
1410 char *float_string = stringPrint("%.6e", value.floatValue());
1411 Tcl_SetResult(interp, float_string, TCL_VOLATILE);
1412 stringDelete(float_string);
1413 }
1414 break;
1415 case PropertyValue::Type::type_bool: {
1416 const char *bool_string = value.boolValue() ? "1" : "0";
1417 Tcl_SetResult(interp, const_cast<char*>(bool_string), TCL_STATIC);
1418 }
1419 break;
1420 case PropertyValue::Type::type_library: {
1421 Tcl_Obj *obj = SWIG_NewInstanceObj(value.library(),
1422 SWIGTYPE_p_Library, false);
1423 Tcl_SetObjResult(interp, obj);
1424 }
1425 break;
1426 case PropertyValue::Type::type_cell: {
1427 Tcl_Obj *obj = SWIG_NewInstanceObj(value.cell(),
1428 SWIGTYPE_p_Cell, false);
1429 Tcl_SetObjResult(interp, obj);
1430 }
1431 break;
1432 case PropertyValue::Type::type_port: {
1433 Tcl_Obj *obj = SWIG_NewInstanceObj(value.port(),
1434 SWIGTYPE_p_Port, false);
1435 Tcl_SetObjResult(interp, obj);
1436 }
1437 break;
1438 case PropertyValue::Type::type_liberty_library: {
1439 Tcl_Obj *obj = SWIG_NewInstanceObj(value.libertyLibrary(),
1440 SWIGTYPE_p_LibertyLibrary, false);
1441 Tcl_SetObjResult(interp, obj);
1442 }
1443 break;
1444 case PropertyValue::Type::type_liberty_cell: {
1445 Tcl_Obj *obj = SWIG_NewInstanceObj(value.libertyCell(),
1446 SWIGTYPE_p_LibertyCell, false);
1447 Tcl_SetObjResult(interp, obj);
1448 }
1449 break;
1450 case PropertyValue::Type::type_liberty_port: {
1451 Tcl_Obj *obj = SWIG_NewInstanceObj(value.libertyPort(),
1452 SWIGTYPE_p_LibertyPort, false);
1453 Tcl_SetObjResult(interp, obj);
1454 }
1455 break;
1456 case PropertyValue::Type::type_instance: {
1457 Tcl_Obj *obj = SWIG_NewInstanceObj(value.instance(),
1458 SWIGTYPE_p_Instance, false);
1459 Tcl_SetObjResult(interp, obj);
1460 }
1461 break;
1462 case PropertyValue::Type::type_pin: {
1463 Tcl_Obj *obj = SWIG_NewInstanceObj(value.pin(), SWIGTYPE_p_Pin, false);
1464 Tcl_SetObjResult(interp, obj);
1465 }
1466 break;
1467 case PropertyValue::Type::type_pins: {
1468 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
1469 PinSeq *pins = value.pins();
1470 PinSeq::Iterator pin_iter(pins);
1471 while (pin_iter.hasNext()) {
1472 Pin *pin = pin_iter.next();
1473 Tcl_Obj *obj = SWIG_NewInstanceObj(pin, SWIGTYPE_p_Pin, false);
1474 Tcl_ListObjAppendElement(interp, list, obj);
1475 }
1476 Tcl_SetObjResult(interp, list);
1477 }
1478 break;
1479 case PropertyValue::Type::type_net: {
1480 Tcl_Obj *obj = SWIG_NewInstanceObj(value.net(),
1481 SWIGTYPE_p_Net, false);
1482 Tcl_SetObjResult(interp, obj);
1483 }
1484 break;
1485 case PropertyValue::Type::type_clk: {
1486 Tcl_Obj *obj = SWIG_NewInstanceObj(value.clock(),
1487 SWIGTYPE_p_Clock, false);
1488 Tcl_SetObjResult(interp, obj);
1489 }
1490 break;
1491 case PropertyValue::Type::type_clks: {
1492 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
1493 ClockSeq *clks = value.clocks();
1494 ClockSeq::Iterator clk_iter(clks);
1495 while (clk_iter.hasNext()) {
1496 Clock *clk = clk_iter.next();
1497 Tcl_Obj *obj = SWIG_NewInstanceObj(clk, SWIGTYPE_p_Clock, false);
1498 Tcl_ListObjAppendElement(interp, list, obj);
1499 }
1500 Tcl_SetObjResult(interp, list);
1501 }
1502 break;
1503 case PropertyValue::Type::type_path_refs: {
1504 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
1505 PathRefSeq *paths = value.pathRefs();
1506 PathRefSeq::Iterator path_iter(paths);
1507 while (path_iter.hasNext()) {
1508 PathRef &path = path_iter.next();
1509 PathRef *copy = new PathRef(path);
1510 Tcl_Obj *obj = SWIG_NewInstanceObj(copy, SWIGTYPE_p_PathRef, false);
1511 Tcl_ListObjAppendElement(interp, list, obj);
1512 }
1513 Tcl_SetObjResult(interp, list);
1514 }
1515 break;
1516 case PropertyValue::Type::type_pwr_activity: {
1517 PwrActivity activity = value.pwrActivity();
1518 Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
1519 Tcl_Obj *obj;
1520 const char *str;
1521
1522 str = stringPrintTmp("%.5e", activity.activity());
1523 obj = Tcl_NewStringObj(str, strlen(str));
1524 Tcl_ListObjAppendElement(interp, list, obj);
1525
1526 str = stringPrintTmp("%.3f", activity.duty());
1527 obj = Tcl_NewStringObj(str, strlen(str));
1528 Tcl_ListObjAppendElement(interp, list, obj);
1529
1530 str = activity.originName();
1531 obj = Tcl_NewStringObj(str, strlen(str));
1532 Tcl_ListObjAppendElement(interp, list, obj);
1533
1534 Tcl_SetObjResult(interp, list);
1535 }
1536 break;
1537 }
1538 }
1539
1540 ////////////////////////////////////////////////////////////////
1541 //
1542 // Empty class definitions to make swig happy.
1543 // Private constructor/destructor so swig doesn't emit them.
1544 //
1545 ////////////////////////////////////////////////////////////////
1546
1547 class Library
1548 {
1549 private:
1550 Library();
1551 ~Library();
1552 };
1553
1554 class LibraryIterator
1555 {
1556 private:
1557 LibraryIterator();
1558 ~LibraryIterator();
1559 };
1560
1561 class Cell
1562 {
1563 private:
1564 Cell();
1565 ~Cell();
1566 };
1567
1568 class CellPortIterator
1569 {
1570 private:
1571 CellPortIterator();
1572 ~CellPortIterator();
1573 };
1574
1575 class LibertyCellPortIterator
1576 {
1577 private:
1578 LibertyCellPortIterator();
1579 ~LibertyCellPortIterator();
1580 };
1581
1582 class Port
1583 {
1584 private:
1585 Port();
1586 ~Port();
1587 };
1588
1589 class PortMemberIterator
1590 {
1591 private:
1592 PortMemberIterator();
1593 ~PortMemberIterator();
1594 };
1595
1596 class LibertyLibrary
1597 {
1598 private:
1599 LibertyLibrary();
1600 ~LibertyLibrary();
1601 };
1602
1603 class LibertyLibraryIterator
1604 {
1605 private:
1606 LibertyLibraryIterator();
1607 ~LibertyLibraryIterator();
1608 };
1609
1610 class LibertyCell
1611 {
1612 private:
1613 LibertyCell();
1614 ~LibertyCell();
1615 };
1616
1617 class LibertyPort
1618 {
1619 private:
1620 LibertyPort();
1621 ~LibertyPort();
1622 };
1623
1624 class LibertyPortMemberIterator
1625 {
1626 private:
1627 LibertyPortMemberIterator();
1628 ~LibertyPortMemberIterator();
1629 };
1630
1631 class TimingArcSet
1632 {
1633 private:
1634 TimingArcSet();
1635 ~TimingArcSet();
1636 };
1637
1638 class LibertyCellTimingArcSetIterator
1639 {
1640 private:
1641 LibertyCellTimingArcSetIterator();
1642 ~LibertyCellTimingArcSetIterator();
1643 };
1644
1645 class TimingArcSetArcIterator
1646 {
1647 private:
1648 TimingArcSetArcIterator();
1649 ~TimingArcSetArcIterator();
1650 };
1651
1652 class TimingArc
1653 {
1654 private:
1655 TimingArc();
1656 ~TimingArc();
1657 };
1658
1659 class Wireload
1660 {
1661 private:
1662 Wireload();
1663 ~Wireload();
1664 };
1665
1666 class WireloadSelection
1667 {
1668 private:
1669 WireloadSelection();
1670 ~WireloadSelection();
1671 };
1672
1673 class Transition
1674 {
1675 private:
1676 Transition();
1677 ~Transition();
1678 };
1679
1680 class Instance
1681 {
1682 private:
1683 Instance();
1684 ~Instance();
1685 };
1686
1687 class Pin
1688 {
1689 private:
1690 Pin();
1691 ~Pin();
1692 };
1693
1694 class Term
1695 {
1696 private:
1697 Term();
1698 ~Term();
1699 };
1700
1701 class InstanceChildIterator
1702 {
1703 private:
1704 InstanceChildIterator();
1705 ~InstanceChildIterator();
1706 };
1707
1708 class InstancePinIterator
1709 {
1710 private:
1711 InstancePinIterator();
1712 ~InstancePinIterator();
1713 };
1714
1715 class InstanceNetIterator
1716 {
1717 private:
1718 InstanceNetIterator();
1719 ~InstanceNetIterator();
1720 };
1721
1722 class LeafInstanceIterator
1723 {
1724 private:
1725 LeafInstanceIterator();
1726 ~LeafInstanceIterator();
1727 };
1728
1729 class Net
1730 {
1731 private:
1732 Net();
1733 ~Net();
1734 };
1735
1736 class NetPinIterator
1737 {
1738 private:
1739 NetPinIterator();
1740 ~NetPinIterator();
1741 };
1742
1743 class NetTermIterator
1744 {
1745 private:
1746 NetTermIterator();
1747 ~NetTermIterator();
1748 };
1749
1750 class NetConnectedPinIterator
1751 {
1752 private:
1753 NetConnectedPinIterator();
1754 ~NetConnectedPinIterator();
1755 };
1756
1757 class PinConnectedPinIterator
1758 {
1759 private:
1760 PinConnectedPinIterator();
1761 ~PinConnectedPinIterator();
1762 };
1763
1764 class Clock
1765 {
1766 private:
1767 Clock();
1768 ~Clock();
1769 };
1770
1771 class ClockIterator
1772 {
1773 private:
1774 ClockIterator();
1775 ~ClockIterator();
1776 };
1777
1778 class ClockEdge
1779 {
1780 private:
1781 ClockEdge();
1782 ~ClockEdge();
1783 };
1784
1785 class Vertex
1786 {
1787 private:
1788 Vertex();
1789 ~Vertex();
1790 };
1791
1792 class Edge
1793 {
1794 private:
1795 Edge();
1796 ~Edge();
1797 };
1798
1799 class VertexIterator
1800 {
1801 private:
1802 VertexIterator();
1803 ~VertexIterator();
1804 };
1805
1806 class VertexInEdgeIterator
1807 {
1808 private:
1809 VertexInEdgeIterator();
1810 ~VertexInEdgeIterator();
1811 };
1812
1813 class VertexOutEdgeIterator
1814 {
1815 private:
1816 VertexOutEdgeIterator();
1817 ~VertexOutEdgeIterator();
1818 };
1819
1820 class PathRef
1821 {
1822 private:
1823 PathRef();
1824 ~PathRef();
1825 };
1826
1827 class PathEnd
1828 {
1829 private:
1830 PathEnd();
1831 ~PathEnd();
1832 };
1833
1834 class MinPulseWidthCheck
1835 {
1836 private:
1837 MinPulseWidthCheck();
1838 ~MinPulseWidthCheck();
1839 };
1840
1841 class MinPulseWidthCheckSeq
1842 {
1843 private:
1844 MinPulseWidthCheckSeq();
1845 ~MinPulseWidthCheckSeq();
1846 };
1847
1848 class MinPulseWidthCheckSeqIterator
1849 {
1850 private:
1851 MinPulseWidthCheckSeqIterator();
1852 ~MinPulseWidthCheckSeqIterator();
1853 };
1854
1855 class VertexPathIterator
1856 {
1857 private:
1858 VertexPathIterator();
1859 ~VertexPathIterator();
1860 };
1861
1862 class SlowDrvrIterator
1863 {
1864 private:
1865 SlowDrvrIterator();
1866 ~SlowDrvrIterator();
1867 };
1868
1869 class ExceptionFrom
1870 {
1871 private:
1872 ExceptionFrom();
1873 ~ExceptionFrom();
1874 };
1875
1876 class ExceptionThru
1877 {
1878 private:
1879 ExceptionThru();
1880 ~ExceptionThru();
1881 };
1882
1883 class ExceptionTo
1884 {
1885 private:
1886 ExceptionTo();
1887 ~ExceptionTo();
1888 };
1889
1890 class OperatingConditions
1891 {
1892 private:
1893 OperatingConditions();
1894 ~OperatingConditions();
1895 };
1896
1897 class Corner
1898 {
1899 private:
1900 Corner();
1901 ~Corner();
1902 };
1903
1904 ////////////////////////////////////////////////////////////////
1905 //
1906 // C++ functions visible as TCL functions.
1907 //
1908 ////////////////////////////////////////////////////////////////
1909
1910 %inline %{
1911
1912 float float_inf = INF;
1913 int group_count_max = PathGroup::group_count_max;
1914
1915 const char *
version()1916 version()
1917 {
1918 return STA_VERSION;
1919 }
1920
1921 const char *
git_sha1()1922 git_sha1()
1923 {
1924 return STA_GIT_SHA1;
1925 }
1926
1927 void
report_error(int id,const char * msg)1928 report_error(int id,
1929 const char *msg)
1930 {
1931 Report *report = Sta::sta()->report();
1932 report->error(id, "%s", msg);
1933 }
1934
1935 void
report_file_error(int id,const char * filename,int line,const char * msg)1936 report_file_error(int id,
1937 const char *filename,
1938 int line,
1939 const char *msg)
1940 {
1941 Report *report = Sta::sta()->report();
1942 report->error(id, filename, line, "%s", msg);
1943 }
1944
1945 void
report_warn(int id,const char * msg)1946 report_warn(int id,
1947 const char *msg)
1948 {
1949 Report *report = Sta::sta()->report();
1950 report->warn(id, "%s", msg);
1951 }
1952
1953 void
report_file_warn(int id,const char * filename,int line,const char * msg)1954 report_file_warn(int id,
1955 const char *filename,
1956 int line,
1957 const char *msg)
1958 {
1959 Report *report = Sta::sta()->report();
1960 report->fileWarn(id, filename, line, "%s", msg);
1961 }
1962
1963 void
report_line(const char * msg)1964 report_line(const char *msg)
1965 {
1966 Report *report = Sta::sta()->report();
1967 report->reportLineString(msg);
1968 }
1969
1970 void
fflush()1971 fflush()
1972 {
1973 fflush(stdout);
1974 fflush(stderr);
1975 }
1976
1977 void
redirect_file_begin(const char * filename)1978 redirect_file_begin(const char *filename)
1979 {
1980 Sta::sta()->report()->redirectFileBegin(filename);
1981 }
1982
1983 void
redirect_file_append_begin(const char * filename)1984 redirect_file_append_begin(const char *filename)
1985 {
1986 Sta::sta()->report()->redirectFileAppendBegin(filename);
1987 }
1988
1989 void
redirect_file_end()1990 redirect_file_end()
1991 {
1992 Sta::sta()->report()->redirectFileEnd();
1993 }
1994
1995 void
redirect_string_begin()1996 redirect_string_begin()
1997 {
1998 Sta::sta()->report()->redirectStringBegin();
1999 }
2000
2001 const char *
redirect_string_end()2002 redirect_string_end()
2003 {
2004 return Sta::sta()->report()->redirectStringEnd();
2005 }
2006
2007 void
log_begin_cmd(const char * filename)2008 log_begin_cmd(const char *filename)
2009 {
2010 Sta::sta()->report()->logBegin(filename);
2011 }
2012
2013 void
log_end()2014 log_end()
2015 {
2016 Sta::sta()->report()->logEnd();
2017 }
2018
2019 void
set_debug(const char * what,int level)2020 set_debug(const char *what,
2021 int level)
2022 {
2023 Sta::sta()->setDebugLevel(what, level);
2024 }
2025
2026 bool
is_object(const char * obj)2027 is_object(const char *obj)
2028 {
2029 // _hexaddress_p_type
2030 const char *s = obj;
2031 char ch = *s++;
2032 if (ch != '_')
2033 return false;
2034 while (*s && isxdigit(*s))
2035 s++;
2036 if ((s - obj - 1) == sizeof(void*) * 2
2037 && *s && *s++ == '_'
2038 && *s && *s++ == 'p'
2039 && *s && *s++ == '_') {
2040 while (*s && *s != ' ')
2041 s++;
2042 return *s == '\0';
2043 }
2044 else
2045 return false;
2046 }
2047
2048 // Assumes is_object is true.
2049 const char *
object_type(const char * obj)2050 object_type(const char *obj)
2051 {
2052 return &obj[1 + sizeof(void*) * 2 + 3];
2053 }
2054
2055 bool
is_object_list(const char * list,const char * type)2056 is_object_list(const char *list,
2057 const char *type)
2058 {
2059 const char *s = list;
2060 while (s) {
2061 bool type_match;
2062 const char *next;
2063 objectListNext(s, type, type_match, next);
2064 if (type_match)
2065 s = next;
2066 else
2067 return false;
2068 }
2069 return true;
2070 }
2071
2072 void
set_rise_fall_short_names(const char * rise_short_name,const char * fall_short_name)2073 set_rise_fall_short_names(const char *rise_short_name,
2074 const char *fall_short_name)
2075 {
2076 RiseFall::rise()->setShortName(rise_short_name);
2077 RiseFall::fall()->setShortName(fall_short_name);
2078
2079 RiseFallBoth::rise()->setShortName(rise_short_name);
2080 RiseFallBoth::fall()->setShortName(fall_short_name);
2081
2082 Transition::rise()->setName(rise_short_name);
2083 Transition::fall()->setName(fall_short_name);
2084 }
2085
2086 const char *
rise_short_name()2087 rise_short_name()
2088 {
2089 return RiseFall::rise()->shortName();
2090 }
2091
2092 const char *
fall_short_name()2093 fall_short_name()
2094 {
2095 return RiseFall::fall()->shortName();
2096 }
2097
2098 bool
pin_is_constrained(Pin * pin)2099 pin_is_constrained(Pin *pin)
2100 {
2101 return Sta::sta()->sdc()->isConstrained(pin);
2102 }
2103
2104 bool
instance_is_constrained(Instance * inst)2105 instance_is_constrained(Instance *inst)
2106 {
2107 return Sta::sta()->sdc()->isConstrained(inst);
2108 }
2109
2110 bool
net_is_constrained(Net * net)2111 net_is_constrained(Net *net)
2112 {
2113 return Sta::sta()->sdc()->isConstrained(net);
2114 }
2115
2116 bool
clk_thru_tristate_enabled()2117 clk_thru_tristate_enabled()
2118 {
2119 return Sta::sta()->clkThruTristateEnabled();
2120 }
2121
2122 void
set_clk_thru_tristate_enabled(bool enabled)2123 set_clk_thru_tristate_enabled(bool enabled)
2124 {
2125 Sta::sta()->setClkThruTristateEnabled(enabled);
2126 }
2127
2128 bool
network_is_linked()2129 network_is_linked()
2130 {
2131 return Sta::sta()->cmdNetwork()->isLinked();
2132 }
2133
2134 void
set_path_divider(char divider)2135 set_path_divider(char divider)
2136 {
2137 cmdNetwork()->setPathDivider(divider);
2138 }
2139
2140 void
set_current_instance(Instance * inst)2141 set_current_instance(Instance *inst)
2142 {
2143 Sta::sta()->setCurrentInstance(inst);
2144 }
2145
2146 bool
read_liberty_cmd(char * filename,Corner * corner,const MinMaxAll * min_max,bool infer_latches)2147 read_liberty_cmd(char *filename,
2148 Corner *corner,
2149 const MinMaxAll *min_max,
2150 bool infer_latches)
2151 {
2152 LibertyLibrary *lib = Sta::sta()->readLiberty(filename, corner, min_max,
2153 infer_latches);
2154 return (lib != nullptr);
2155 }
2156
2157 bool
set_min_library_cmd(char * min_filename,char * max_filename)2158 set_min_library_cmd(char *min_filename,
2159 char *max_filename)
2160 {
2161 return Sta::sta()->setMinLibrary(min_filename, max_filename);
2162 }
2163
2164 Library *
find_library(const char * name)2165 find_library(const char *name)
2166 {
2167 return cmdNetwork()->findLibrary(name);
2168 }
2169
2170 LibraryIterator *
library_iterator()2171 library_iterator()
2172 {
2173 return cmdNetwork()->libraryIterator();
2174 }
2175
2176 LibertyLibrary *
find_liberty(const char * name)2177 find_liberty(const char *name)
2178 {
2179 return cmdNetwork()->findLiberty(name);
2180 }
2181
2182 LibertyLibraryIterator *
liberty_library_iterator()2183 liberty_library_iterator()
2184 {
2185 return cmdNetwork()->libertyLibraryIterator();
2186 }
2187
2188 LibertyCell *
find_liberty_cell(const char * name)2189 find_liberty_cell(const char *name)
2190 {
2191 return cmdNetwork()->findLibertyCell(name);
2192 }
2193
2194 TmpCellSeq *
find_cells_matching(const char * pattern,bool regexp,bool nocase)2195 find_cells_matching(const char *pattern,
2196 bool regexp,
2197 bool nocase)
2198 {
2199 Network *network = cmdNetwork();
2200 PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
2201 TmpCellSeq *cells = new TmpCellSeq;
2202 LibraryIterator *lib_iter = network->libraryIterator();
2203 while (lib_iter->hasNext()) {
2204 Library *lib = lib_iter->next();
2205 network->findCellsMatching(lib, &matcher, cells);
2206 }
2207 delete lib_iter;
2208 return cells;
2209 }
2210
2211 LibertyCellSeq *
find_library_buffers(LibertyLibrary * library)2212 find_library_buffers(LibertyLibrary *library)
2213 {
2214 return library->buffers();
2215 }
2216
2217 void
make_equiv_cells(LibertyLibrary * lib)2218 make_equiv_cells(LibertyLibrary *lib)
2219 {
2220 LibertyLibrarySeq libs;
2221 libs.push_back(lib);
2222 Sta::sta()->makeEquivCells(&libs, nullptr);
2223 }
2224
2225 LibertyCellSeq *
find_equiv_cells(LibertyCell * cell)2226 find_equiv_cells(LibertyCell *cell)
2227 {
2228 return Sta::sta()->equivCells(cell);
2229 }
2230
2231 bool
equiv_cells(LibertyCell * cell1,LibertyCell * cell2)2232 equiv_cells(LibertyCell *cell1,
2233 LibertyCell *cell2)
2234 {
2235 return sta::equivCells(cell1, cell2);
2236 }
2237
2238 bool
equiv_cell_ports(LibertyCell * cell1,LibertyCell * cell2)2239 equiv_cell_ports(LibertyCell *cell1,
2240 LibertyCell *cell2)
2241 {
2242 return equivCellPorts(cell1, cell2);
2243 }
2244
2245 bool
equiv_cell_timing_arcs(LibertyCell * cell1,LibertyCell * cell2)2246 equiv_cell_timing_arcs(LibertyCell *cell1,
2247 LibertyCell *cell2)
2248 {
2249 return equivCellTimingArcSets(cell1, cell2);
2250 }
2251
2252 void
set_cmd_namespace_cmd(const char * namespc)2253 set_cmd_namespace_cmd(const char *namespc)
2254 {
2255 if (stringEq(namespc, "sdc"))
2256 Sta::sta()->setCmdNamespace(CmdNamespace::sdc);
2257 else if (stringEq(namespc, "sta"))
2258 Sta::sta()->setCmdNamespace(CmdNamespace::sta);
2259 else
2260 criticalError(269, "unknown namespace");
2261 }
2262
2263 bool
link_design_cmd(const char * top_cell_name)2264 link_design_cmd(const char *top_cell_name)
2265 {
2266 return Sta::sta()->linkDesign(top_cell_name);
2267 }
2268
2269 bool
link_make_black_boxes()2270 link_make_black_boxes()
2271 {
2272 return Sta::sta()->linkMakeBlackBoxes();
2273 }
2274
2275 void
set_link_make_black_boxes(bool make)2276 set_link_make_black_boxes(bool make)
2277 {
2278 Sta::sta()->setLinkMakeBlackBoxes(make);
2279 }
2280
2281 Instance *
top_instance()2282 top_instance()
2283 {
2284 return cmdLinkedNetwork()->topInstance();
2285 }
2286
2287 const char *
liberty_port_direction(const LibertyPort * port)2288 liberty_port_direction(const LibertyPort *port)
2289 {
2290 return port->direction()->name();
2291 }
2292
2293 const char *
port_direction(const Port * port)2294 port_direction(const Port *port)
2295 {
2296 return cmdLinkedNetwork()->direction(port)->name();
2297 }
2298
2299 const char *
pin_direction(const Pin * pin)2300 pin_direction(const Pin *pin)
2301 {
2302 return cmdLinkedNetwork()->direction(pin)->name();
2303 }
2304
2305 TmpPortSeq *
find_ports_matching(const char * pattern,bool regexp,bool nocase)2306 find_ports_matching(const char *pattern,
2307 bool regexp,
2308 bool nocase)
2309 {
2310 Network *network = cmdLinkedNetwork();
2311 PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
2312 Cell *top_cell = network->cell(network->topInstance());
2313 PortSeq ports1;
2314 network->findPortsMatching(top_cell, &matcher, &ports1);
2315 // Expand bus/bundle ports.
2316 TmpPortSeq *ports = new TmpPortSeq;
2317 PortSeq::Iterator port_iter(ports1);
2318 while (port_iter.hasNext()) {
2319 Port *port = port_iter.next();
2320 if (network->isBus(port)
2321 || network->isBundle(port)) {
2322 PortMemberIterator *member_iter = network->memberIterator(port);
2323 while (member_iter->hasNext()) {
2324 Port *member = member_iter->next();
2325 ports->push_back(member);
2326 }
2327 delete member_iter;
2328 }
2329 else
2330 ports->push_back(port);
2331 }
2332 return ports;
2333 }
2334
2335 TmpPinSeq *
find_port_pins_matching(const char * pattern,bool regexp,bool nocase)2336 find_port_pins_matching(const char *pattern,
2337 bool regexp,
2338 bool nocase)
2339 {
2340 Network *network = cmdLinkedNetwork();
2341 PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
2342 PortSeq ports;
2343 Instance *top_inst = network->topInstance();
2344 Cell *top_cell = network->cell(top_inst);
2345 network->findPortsMatching(top_cell, &matcher, &ports);
2346 TmpPinSeq *pins = new TmpPinSeq;
2347 PortSeq::Iterator port_iter(ports);
2348 while (port_iter.hasNext()) {
2349 Port *port = port_iter.next();
2350 if (network->isBus(port)
2351 || network->isBundle(port)) {
2352 PortMemberIterator *member_iter = network->memberIterator(port);
2353 while (member_iter->hasNext()) {
2354 Port *member = member_iter->next();
2355 Pin *pin = network->findPin(top_inst, member);
2356 if (pin)
2357 pins->push_back(pin);
2358 }
2359 delete member_iter;
2360 }
2361 else {
2362 Pin *pin = network->findPin(top_inst, port);
2363 if (pin)
2364 pins->push_back(pin);
2365 }
2366 }
2367 return pins;
2368 }
2369
2370 Pin *
find_pin(const char * path_name)2371 find_pin(const char *path_name)
2372 {
2373 return cmdLinkedNetwork()->findPin(path_name);
2374 }
2375
2376 TmpPinSeq *
find_pins_matching(const char * pattern,bool regexp,bool nocase)2377 find_pins_matching(const char *pattern,
2378 bool regexp,
2379 bool nocase)
2380 {
2381 Sta *sta = Sta::sta();
2382 Network *network = cmdLinkedNetwork();
2383 PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
2384 Instance *current_instance = sta->currentInstance();
2385 TmpPinSeq *pins = new TmpPinSeq;
2386 network->findPinsMatching(current_instance, &matcher, pins);
2387 return pins;
2388 }
2389
2390 TmpPinSeq *
find_pins_hier_matching(const char * pattern,bool regexp,bool nocase)2391 find_pins_hier_matching(const char *pattern,
2392 bool regexp,
2393 bool nocase)
2394 {
2395 Sta *sta = Sta::sta();
2396 Network *network = cmdLinkedNetwork();
2397 Instance *current_instance = sta->currentInstance();
2398 PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
2399 TmpPinSeq *pins = new TmpPinSeq;
2400 network->findPinsHierMatching(current_instance, &matcher, pins);
2401 return pins;
2402 }
2403
2404 Instance *
find_instance(char * path_name)2405 find_instance(char *path_name)
2406 {
2407 return cmdLinkedNetwork()->findInstance(path_name);
2408 }
2409
2410 TmpInstanceSeq *
network_leaf_instances()2411 network_leaf_instances()
2412 {
2413 InstanceSeq *insts = new InstanceSeq;
2414 LeafInstanceIterator *iter = cmdLinkedNetwork()->leafInstanceIterator();
2415 while (iter->hasNext()) {
2416 Instance *inst = iter->next();
2417 insts->push_back(inst);
2418 }
2419 delete iter;
2420 return insts;
2421 }
2422
2423 TmpInstanceSeq *
find_instances_matching(const char * pattern,bool regexp,bool nocase)2424 find_instances_matching(const char *pattern,
2425 bool regexp,
2426 bool nocase)
2427 {
2428 Sta *sta = Sta::sta();
2429 Instance *current_instance = sta->currentInstance();
2430 PatternMatch matcher(pattern, regexp, nocase, sta->tclInterp());
2431 TmpInstanceSeq *insts = new InstanceSeq;
2432 cmdLinkedNetwork()->findInstancesMatching(current_instance, &matcher, insts);
2433 return insts;
2434 }
2435
2436 TmpInstanceSeq *
find_instances_hier_matching(const char * pattern,bool regexp,bool nocase)2437 find_instances_hier_matching(const char *pattern,
2438 bool regexp,
2439 bool nocase)
2440 {
2441 Sta *sta = Sta::sta();
2442 Network *network = cmdLinkedNetwork();
2443 Instance *current_instance = sta->currentInstance();
2444 PatternMatch matcher(pattern, regexp, nocase, sta->tclInterp());
2445 TmpInstanceSeq *insts = new InstanceSeq;
2446 network->findInstancesHierMatching(current_instance, &matcher, insts);
2447 return insts;
2448 }
2449
2450 TmpInstanceSet *
find_register_instances(ClockSet * clks,const RiseFallBoth * clk_tr,bool edge_triggered,bool latches)2451 find_register_instances(ClockSet *clks,
2452 const RiseFallBoth *clk_tr,
2453 bool edge_triggered,
2454 bool latches)
2455 {
2456 cmdLinkedNetwork();
2457 InstanceSet *insts = Sta::sta()->findRegisterInstances(clks, clk_tr,
2458 edge_triggered,
2459 latches);
2460 delete clks;
2461 return insts;
2462 }
2463
2464 TmpPinSet *
find_register_data_pins(ClockSet * clks,const RiseFallBoth * clk_tr,bool edge_triggered,bool latches)2465 find_register_data_pins(ClockSet *clks,
2466 const RiseFallBoth *clk_tr,
2467 bool edge_triggered,
2468 bool latches)
2469 {
2470 cmdLinkedNetwork();
2471 PinSet *pins = Sta::sta()->findRegisterDataPins(clks, clk_tr,
2472 edge_triggered, latches);
2473 delete clks;
2474 return pins;
2475 }
2476
2477 TmpPinSet *
find_register_clk_pins(ClockSet * clks,const RiseFallBoth * clk_tr,bool edge_triggered,bool latches)2478 find_register_clk_pins(ClockSet *clks,
2479 const RiseFallBoth *clk_tr,
2480 bool edge_triggered,
2481 bool latches)
2482 {
2483 cmdLinkedNetwork();
2484 PinSet *pins = Sta::sta()->findRegisterClkPins(clks, clk_tr,
2485 edge_triggered, latches);
2486 delete clks;
2487 return pins;
2488 }
2489
2490 TmpPinSet *
find_register_async_pins(ClockSet * clks,const RiseFallBoth * clk_tr,bool edge_triggered,bool latches)2491 find_register_async_pins(ClockSet *clks,
2492 const RiseFallBoth *clk_tr,
2493 bool edge_triggered,
2494 bool latches)
2495 {
2496 cmdLinkedNetwork();
2497 PinSet *pins = Sta::sta()->findRegisterAsyncPins(clks, clk_tr,
2498 edge_triggered, latches);
2499 delete clks;
2500 return pins;
2501 }
2502
2503 TmpPinSet *
find_register_output_pins(ClockSet * clks,const RiseFallBoth * clk_tr,bool edge_triggered,bool latches)2504 find_register_output_pins(ClockSet *clks,
2505 const RiseFallBoth *clk_tr,
2506 bool edge_triggered,
2507 bool latches)
2508 {
2509 cmdLinkedNetwork();
2510 PinSet *pins = Sta::sta()->findRegisterOutputPins(clks, clk_tr,
2511 edge_triggered, latches);
2512 delete clks;
2513 return pins;
2514 }
2515
2516 Net *
find_net(char * path_name)2517 find_net(char *path_name)
2518 {
2519 return cmdLinkedNetwork()->findNet(path_name);
2520 }
2521
2522 NetSeq *
find_nets_matching(const char * pattern,bool regexp,bool nocase)2523 find_nets_matching(const char *pattern,
2524 bool regexp,
2525 bool nocase)
2526 {
2527 Network *network = cmdLinkedNetwork();
2528 Instance *current_instance = Sta::sta()->currentInstance();
2529 PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
2530 NetSeq *nets = new NetSeq;
2531 network->findNetsMatching(current_instance, &matcher, nets);
2532 return nets;
2533 }
2534
2535 NetSeq *
find_nets_hier_matching(const char * pattern,bool regexp,bool nocase)2536 find_nets_hier_matching(const char *pattern,
2537 bool regexp,
2538 bool nocase)
2539 {
2540 Network *network = cmdLinkedNetwork();
2541 Instance *current_instance = Sta::sta()->currentInstance();
2542 PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
2543 NetSeq *nets = new NetSeq;
2544 network->findNetsHierMatching(current_instance, &matcher, nets);
2545 return nets;
2546 }
2547
2548 TmpPortSeq *
filter_ports(const char * property,const char * op,const char * pattern,PortSeq * ports)2549 filter_ports(const char *property,
2550 const char *op,
2551 const char *pattern,
2552 PortSeq *ports)
2553 {
2554 Sta *sta = Sta::sta();
2555 TmpPortSeq *filtered_ports = new TmpPortSeq;
2556 PortSeq::Iterator port_iter(ports);
2557 bool exact_match = stringEq(op, "==");
2558 while (port_iter.hasNext()) {
2559 Port *port = port_iter.next();
2560 PropertyValue value(getProperty(port, property, sta));
2561 const char *prop = value.stringValue();
2562 if (prop &&
2563 ((exact_match && stringEq(prop, pattern))
2564 || (!exact_match && patternMatch(pattern, prop))))
2565 filtered_ports->push_back(port);
2566 }
2567 delete ports;
2568 return filtered_ports;
2569 }
2570
2571 TmpInstanceSeq *
filter_insts(const char * property,const char * op,const char * pattern,InstanceSeq * insts)2572 filter_insts(const char *property,
2573 const char *op,
2574 const char *pattern,
2575 InstanceSeq *insts)
2576 {
2577 Sta *sta = Sta::sta();
2578 cmdLinkedNetwork();
2579 TmpInstanceSeq *filtered_insts = new TmpInstanceSeq;
2580 TmpInstanceSeq::Iterator inst_iter(insts);
2581 bool exact_match = stringEq(op, "==");
2582 while (inst_iter.hasNext()) {
2583 Instance *inst = inst_iter.next();
2584 PropertyValue value(getProperty(inst, property, sta));
2585 const char *prop = value.stringValue();
2586 if (prop &&
2587 ((exact_match && stringEq(prop, pattern))
2588 || (!exact_match && patternMatch(pattern, prop))))
2589 filtered_insts->push_back(inst);
2590 }
2591 delete insts;
2592 return filtered_insts;
2593 }
2594
2595 PinSeq *
filter_pins(const char * property,const char * op,const char * pattern,PinSeq * pins)2596 filter_pins(const char *property,
2597 const char *op,
2598 const char *pattern,
2599 PinSeq *pins)
2600 {
2601 Sta *sta = Sta::sta();
2602 PinSeq *filtered_pins = new PinSeq;
2603 PinSeq::Iterator pin_iter(pins);
2604 bool exact_match = stringEq(op, "==");
2605 while (pin_iter.hasNext()) {
2606 Pin *pin = pin_iter.next();
2607 PropertyValue value(getProperty(pin, property, sta));
2608 const char *prop = value.stringValue();
2609 if (prop &&
2610 ((exact_match && stringEq(prop, pattern))
2611 || (!exact_match && patternMatch(pattern, prop))))
2612 filtered_pins->push_back(pin);
2613 }
2614 delete pins;
2615 return filtered_pins;
2616 }
2617
2618 PropertyValue
pin_property(const Pin * pin,const char * property)2619 pin_property(const Pin *pin,
2620 const char *property)
2621 {
2622 cmdLinkedNetwork();
2623 return getProperty(pin, property, Sta::sta());
2624 }
2625
2626 PropertyValue
instance_property(const Instance * inst,const char * property)2627 instance_property(const Instance *inst,
2628 const char *property)
2629 {
2630 cmdLinkedNetwork();
2631 return getProperty(inst, property, Sta::sta());
2632 }
2633
2634 PropertyValue
net_property(const Net * net,const char * property)2635 net_property(const Net *net,
2636 const char *property)
2637 {
2638 cmdLinkedNetwork();
2639 return getProperty(net, property, Sta::sta());
2640 }
2641
2642 PropertyValue
port_property(const Port * port,const char * property)2643 port_property(const Port *port,
2644 const char *property)
2645 {
2646 return getProperty(port, property, Sta::sta());
2647 }
2648
2649
2650 PropertyValue
liberty_cell_property(const LibertyCell * cell,const char * property)2651 liberty_cell_property(const LibertyCell *cell,
2652 const char *property)
2653 {
2654 return getProperty(cell, property, Sta::sta());
2655 }
2656
2657 PropertyValue
cell_property(const Cell * cell,const char * property)2658 cell_property(const Cell *cell,
2659 const char *property)
2660 {
2661 return getProperty(cell, property, Sta::sta());
2662 }
2663
2664 PropertyValue
liberty_port_property(const LibertyPort * port,const char * property)2665 liberty_port_property(const LibertyPort *port,
2666 const char *property)
2667 {
2668 return getProperty(port, property, Sta::sta());
2669 }
2670
2671 PropertyValue
library_property(const Library * lib,const char * property)2672 library_property(const Library *lib,
2673 const char *property)
2674 {
2675 return getProperty(lib, property, Sta::sta());
2676 }
2677
2678 PropertyValue
liberty_library_property(const LibertyLibrary * lib,const char * property)2679 liberty_library_property(const LibertyLibrary *lib,
2680 const char *property)
2681 {
2682 return getProperty(lib, property, Sta::sta());
2683 }
2684
2685 PropertyValue
edge_property(Edge * edge,const char * property)2686 edge_property(Edge *edge,
2687 const char *property)
2688 {
2689 cmdGraph();
2690 return getProperty(edge, property, Sta::sta());
2691 }
2692
2693 PropertyValue
clock_property(Clock * clk,const char * property)2694 clock_property(Clock *clk,
2695 const char *property)
2696 {
2697 cmdLinkedNetwork();
2698 return getProperty(clk, property, Sta::sta());
2699 }
2700
2701 PropertyValue
path_end_property(PathEnd * end,const char * property)2702 path_end_property(PathEnd *end,
2703 const char *property)
2704 {
2705 cmdLinkedNetwork();
2706 return getProperty(end, property, Sta::sta());
2707 }
2708
2709 PropertyValue
path_ref_property(PathRef * path,const char * property)2710 path_ref_property(PathRef *path,
2711 const char *property)
2712 {
2713 cmdLinkedNetwork();
2714 return getProperty(path, property, Sta::sta());
2715 }
2716
2717 PropertyValue
timing_arc_set_property(TimingArcSet * arc_set,const char * property)2718 timing_arc_set_property(TimingArcSet *arc_set,
2719 const char *property)
2720 {
2721 cmdLinkedNetwork();
2722 return getProperty(arc_set, property, Sta::sta());
2723 }
2724
2725 LeafInstanceIterator *
leaf_instance_iterator()2726 leaf_instance_iterator()
2727 {
2728 return cmdLinkedNetwork()->leafInstanceIterator();
2729 }
2730
2731 ////////////////////////////////////////////////////////////////
2732
2733 void
define_corners_cmd(StringSet * corner_names)2734 define_corners_cmd(StringSet *corner_names)
2735 {
2736 Sta *sta = Sta::sta();
2737 sta->makeCorners(corner_names);
2738 delete corner_names;
2739 }
2740
2741 Corner *
cmd_corner()2742 cmd_corner()
2743 {
2744 return Sta::sta()->cmdCorner();
2745 }
2746
2747 void
set_cmd_corner(Corner * corner)2748 set_cmd_corner(Corner *corner)
2749 {
2750 Sta::sta()->setCmdCorner(corner);
2751 }
2752
2753 Corner *
find_corner(const char * corner_name)2754 find_corner(const char *corner_name)
2755 {
2756 return Sta::sta()->findCorner(corner_name);
2757 }
2758
2759 Corners *
corners()2760 corners()
2761 {
2762 return Sta::sta()->corners();
2763 }
2764
2765 bool
multi_corner()2766 multi_corner()
2767 {
2768 return Sta::sta()->multiCorner();
2769 }
2770
2771 ////////////////////////////////////////////////////////////////
2772
2773 void
set_analysis_type_cmd(const char * analysis_type)2774 set_analysis_type_cmd(const char *analysis_type)
2775 {
2776 AnalysisType type;
2777 if (stringEq(analysis_type, "single"))
2778 type = AnalysisType::single;
2779 else if (stringEq(analysis_type, "bc_wc"))
2780 type = AnalysisType::bc_wc;
2781 else if (stringEq(analysis_type, "on_chip_variation"))
2782 type = AnalysisType::ocv;
2783 else {
2784 criticalError(270, "unknown analysis type");
2785 type = AnalysisType::single;
2786 }
2787 Sta::sta()->setAnalysisType(type);
2788 }
2789
2790 OperatingConditions *
operating_conditions(const MinMax * min_max)2791 operating_conditions(const MinMax *min_max)
2792 {
2793 return Sta::sta()->operatingConditions(min_max);
2794 }
2795
2796 void
set_operating_conditions_cmd(OperatingConditions * op_cond,const MinMaxAll * min_max)2797 set_operating_conditions_cmd(OperatingConditions *op_cond,
2798 const MinMaxAll *min_max)
2799 {
2800 Sta::sta()->setOperatingConditions(op_cond, min_max);
2801 }
2802
2803 EdgeSeq *
filter_timing_arcs(const char * property,const char * op,const char * pattern,EdgeSeq * edges)2804 filter_timing_arcs(const char *property,
2805 const char *op,
2806 const char *pattern,
2807 EdgeSeq *edges)
2808 {
2809 Sta *sta = Sta::sta();
2810 EdgeSeq *filtered_edges = new EdgeSeq;
2811 EdgeSeq::Iterator edge_iter(edges);
2812 bool exact_match = stringEq(op, "==");
2813 while (edge_iter.hasNext()) {
2814 Edge *edge = edge_iter.next();
2815 PropertyValue value(getProperty(edge, property, sta));
2816 const char *prop = value.stringValue();
2817 if (prop &&
2818 ((exact_match && stringEq(prop, pattern))
2819 || (!exact_match && patternMatch(pattern, prop))))
2820 filtered_edges->push_back(edge);
2821 }
2822 delete edges;
2823 return filtered_edges;
2824 }
2825
2826 const char *
operating_condition_analysis_type()2827 operating_condition_analysis_type()
2828 {
2829 switch (Sta::sta()->sdc()->analysisType()){
2830 case AnalysisType::single:
2831 return "single";
2832 case AnalysisType::bc_wc:
2833 return "bc_wc";
2834 case AnalysisType::ocv:
2835 return "on_chip_variation";
2836 }
2837 // Prevent warnings from lame compilers.
2838 return "?";
2839 }
2840
2841 void
set_instance_pvt(Instance * inst,const MinMaxAll * min_max,float process,float voltage,float temperature)2842 set_instance_pvt(Instance *inst,
2843 const MinMaxAll *min_max,
2844 float process,
2845 float voltage,
2846 float temperature)
2847 {
2848 cmdLinkedNetwork();
2849 Pvt *pvt = new Pvt(process, voltage, temperature);
2850 Sta::sta()->setPvt(inst, min_max, pvt);
2851 }
2852
2853 float
port_ext_pin_cap(Port * port,const MinMax * min_max)2854 port_ext_pin_cap(Port *port,
2855 const MinMax *min_max)
2856 {
2857 cmdLinkedNetwork();
2858 float pin_cap, wire_cap;
2859 int fanout;
2860 Sta::sta()->portExtCaps(port, min_max, pin_cap, wire_cap, fanout);
2861 return pin_cap;
2862 }
2863
2864 void
set_port_pin_cap(Port * port,const RiseFallBoth * rf,const MinMaxAll * min_max,float cap)2865 set_port_pin_cap(Port *port,
2866 const RiseFallBoth *rf,
2867 const MinMaxAll *min_max,
2868 float cap)
2869 {
2870 Sta::sta()->setPortExtPinCap(port, rf, min_max, cap);
2871 }
2872
2873 float
port_ext_wire_cap(Port * port,const MinMax * min_max)2874 port_ext_wire_cap(Port *port,
2875 const MinMax *min_max)
2876 {
2877 cmdLinkedNetwork();
2878 float pin_cap, wire_cap;
2879 int fanout;
2880 Sta::sta()->portExtCaps(port, min_max, pin_cap, wire_cap, fanout);
2881 return wire_cap;
2882 }
2883
2884 void
set_port_wire_cap(Port * port,bool subtract_pin_cap,const RiseFallBoth * rf,const MinMaxAll * min_max,float cap)2885 set_port_wire_cap(Port *port,
2886 bool subtract_pin_cap,
2887 const RiseFallBoth *rf,
2888 const MinMaxAll *min_max,
2889 float cap)
2890 {
2891 Sta::sta()->setPortExtWireCap(port, subtract_pin_cap, rf, min_max, cap);
2892 }
2893
2894 void
set_port_ext_fanout_cmd(Port * port,int fanout,const MinMaxAll * min_max)2895 set_port_ext_fanout_cmd(Port *port,
2896 int fanout,
2897 const MinMaxAll *min_max)
2898 {
2899 Sta::sta()->setPortExtFanout(port, fanout, min_max);
2900 }
2901
2902 float
port_ext_fanout(Port * port,const MinMax * min_max)2903 port_ext_fanout(Port *port,
2904 const MinMax *min_max)
2905 {
2906 cmdLinkedNetwork();
2907 float pin_cap, wire_cap;
2908 int fanout;
2909 Sta::sta()->portExtCaps(port, min_max, pin_cap, wire_cap, fanout);
2910 return fanout;
2911 }
2912
2913 void
set_net_wire_cap(Net * net,bool subtract_pin_cap,Corner * corner,const MinMaxAll * min_max,float cap)2914 set_net_wire_cap(Net *net,
2915 bool subtract_pin_cap,
2916 Corner *corner,
2917 const MinMaxAll *min_max,
2918 float cap)
2919 {
2920 Sta::sta()->setNetWireCap(net, subtract_pin_cap, corner, min_max, cap);
2921 }
2922
2923 void
set_wire_load_mode_cmd(const char * mode_name)2924 set_wire_load_mode_cmd(const char *mode_name)
2925 {
2926 WireloadMode mode = stringWireloadMode(mode_name);
2927 if (mode == WireloadMode::unknown)
2928 criticalError(271, "unknown wire load mode");
2929 else
2930 Sta::sta()->setWireloadMode(mode);
2931 }
2932
2933 void
set_net_resistance(Net * net,const MinMaxAll * min_max,float res)2934 set_net_resistance(Net *net,
2935 const MinMaxAll *min_max,
2936 float res)
2937 {
2938 Sta::sta()->setResistance(net, min_max, res);
2939 }
2940
2941 void
set_wire_load_cmd(Wireload * wireload,const MinMaxAll * min_max)2942 set_wire_load_cmd(Wireload *wireload,
2943 const MinMaxAll *min_max)
2944 {
2945 Sta::sta()->setWireload(wireload, min_max);
2946 }
2947
2948 void
set_wire_load_selection_group_cmd(WireloadSelection * selection,const MinMaxAll * min_max)2949 set_wire_load_selection_group_cmd(WireloadSelection *selection,
2950 const MinMaxAll *min_max)
2951 {
2952 Sta::sta()->setWireloadSelection(selection, min_max);
2953 }
2954
2955 void
make_clock(const char * name,PinSet * pins,bool add_to_pins,float period,FloatSeq * waveform,char * comment)2956 make_clock(const char *name,
2957 PinSet *pins,
2958 bool add_to_pins,
2959 float period,
2960 FloatSeq *waveform,
2961 char *comment)
2962 {
2963 cmdLinkedNetwork();
2964 Sta::sta()->makeClock(name, pins, add_to_pins, period, waveform, comment);
2965 }
2966
2967 void
make_generated_clock(const char * name,PinSet * pins,bool add_to_pins,Pin * src_pin,Clock * master_clk,Pin * pll_out,Pin * pll_fdbk,int divide_by,int multiply_by,float duty_cycle,bool invert,bool combinational,IntSeq * edges,FloatSeq * edge_shifts,char * comment)2968 make_generated_clock(const char *name,
2969 PinSet *pins,
2970 bool add_to_pins,
2971 Pin *src_pin,
2972 Clock *master_clk,
2973 Pin *pll_out,
2974 Pin *pll_fdbk,
2975 int divide_by,
2976 int multiply_by,
2977 float duty_cycle,
2978 bool invert,
2979 bool combinational,
2980 IntSeq *edges,
2981 FloatSeq *edge_shifts,
2982 char *comment)
2983 {
2984 cmdLinkedNetwork();
2985 Sta::sta()->makeGeneratedClock(name, pins, add_to_pins,
2986 src_pin, master_clk, pll_out, pll_fdbk,
2987 divide_by, multiply_by, duty_cycle, invert,
2988 combinational, edges, edge_shifts,
2989 comment);
2990 }
2991
2992 void
remove_clock_cmd(Clock * clk)2993 remove_clock_cmd(Clock *clk)
2994 {
2995 cmdLinkedNetwork();
2996 Sta::sta()->removeClock(clk);
2997 }
2998
2999 void
set_propagated_clock_cmd(Clock * clk)3000 set_propagated_clock_cmd(Clock *clk)
3001 {
3002 cmdLinkedNetwork();
3003 Sta::sta()->setPropagatedClock(clk);
3004 }
3005
3006 void
set_propagated_clock_pin_cmd(Pin * pin)3007 set_propagated_clock_pin_cmd(Pin *pin)
3008 {
3009 cmdLinkedNetwork();
3010 Sta::sta()->setPropagatedClock(pin);
3011 }
3012
3013 void
unset_propagated_clock_cmd(Clock * clk)3014 unset_propagated_clock_cmd(Clock *clk)
3015 {
3016 cmdLinkedNetwork();
3017 Sta::sta()->removePropagatedClock(clk);
3018 }
3019
3020 void
unset_propagated_clock_pin_cmd(Pin * pin)3021 unset_propagated_clock_pin_cmd(Pin *pin)
3022 {
3023 cmdLinkedNetwork();
3024 Sta::sta()->removePropagatedClock(pin);
3025 }
3026
3027 void
set_clock_slew_cmd(Clock * clk,const RiseFallBoth * rf,const MinMaxAll * min_max,float slew)3028 set_clock_slew_cmd(Clock *clk,
3029 const RiseFallBoth *rf,
3030 const MinMaxAll *min_max,
3031 float slew)
3032 {
3033 cmdLinkedNetwork();
3034 Sta::sta()->setClockSlew(clk, rf, min_max, slew);
3035 }
3036
3037 void
unset_clock_slew_cmd(Clock * clk)3038 unset_clock_slew_cmd(Clock *clk)
3039 {
3040 cmdLinkedNetwork();
3041 Sta::sta()->removeClockSlew(clk);
3042 }
3043
3044 void
set_clock_latency_cmd(Clock * clk,Pin * pin,const RiseFallBoth * rf,MinMaxAll * min_max,float delay)3045 set_clock_latency_cmd(Clock *clk,
3046 Pin *pin,
3047 const RiseFallBoth *rf,
3048 MinMaxAll *min_max, float delay)
3049 {
3050 cmdLinkedNetwork();
3051 Sta::sta()->setClockLatency(clk, pin, rf, min_max, delay);
3052 }
3053
3054 void
set_clock_insertion_cmd(Clock * clk,Pin * pin,const RiseFallBoth * rf,const MinMaxAll * min_max,const EarlyLateAll * early_late,float delay)3055 set_clock_insertion_cmd(Clock *clk,
3056 Pin *pin,
3057 const RiseFallBoth *rf,
3058 const MinMaxAll *min_max,
3059 const EarlyLateAll *early_late,
3060 float delay)
3061 {
3062 cmdLinkedNetwork();
3063 Sta::sta()->setClockInsertion(clk, pin, rf, min_max, early_late, delay);
3064 }
3065
3066 void
unset_clock_latency_cmd(Clock * clk,Pin * pin)3067 unset_clock_latency_cmd(Clock *clk,
3068 Pin *pin)
3069 {
3070 cmdLinkedNetwork();
3071 Sta::sta()->removeClockLatency(clk, pin);
3072 }
3073
3074 void
unset_clock_insertion_cmd(Clock * clk,Pin * pin)3075 unset_clock_insertion_cmd(Clock *clk,
3076 Pin *pin)
3077 {
3078 cmdLinkedNetwork();
3079 Sta::sta()->removeClockInsertion(clk, pin);
3080 }
3081
3082 void
set_clock_uncertainty_clk(Clock * clk,const SetupHoldAll * setup_hold,float uncertainty)3083 set_clock_uncertainty_clk(Clock *clk,
3084 const SetupHoldAll *setup_hold,
3085 float uncertainty)
3086 {
3087 cmdLinkedNetwork();
3088 Sta::sta()->setClockUncertainty(clk, setup_hold, uncertainty);
3089 }
3090
3091 void
unset_clock_uncertainty_clk(Clock * clk,const SetupHoldAll * setup_hold)3092 unset_clock_uncertainty_clk(Clock *clk,
3093 const SetupHoldAll *setup_hold)
3094 {
3095 cmdLinkedNetwork();
3096 Sta::sta()->removeClockUncertainty(clk, setup_hold);
3097 }
3098
3099 void
set_clock_uncertainty_pin(Pin * pin,const MinMaxAll * min_max,float uncertainty)3100 set_clock_uncertainty_pin(Pin *pin,
3101 const MinMaxAll *min_max,
3102 float uncertainty)
3103 {
3104 cmdLinkedNetwork();
3105 Sta::sta()->setClockUncertainty(pin, min_max, uncertainty);
3106 }
3107
3108 void
unset_clock_uncertainty_pin(Pin * pin,const MinMaxAll * min_max)3109 unset_clock_uncertainty_pin(Pin *pin,
3110 const MinMaxAll *min_max)
3111 {
3112 cmdLinkedNetwork();
3113 Sta::sta()->removeClockUncertainty(pin, min_max);
3114 }
3115
3116 void
set_inter_clock_uncertainty(Clock * from_clk,const RiseFallBoth * from_tr,Clock * to_clk,const RiseFallBoth * to_tr,const MinMaxAll * min_max,float uncertainty)3117 set_inter_clock_uncertainty(Clock *from_clk,
3118 const RiseFallBoth *from_tr,
3119 Clock *to_clk,
3120 const RiseFallBoth *to_tr,
3121 const MinMaxAll *min_max,
3122 float uncertainty)
3123 {
3124 cmdLinkedNetwork();
3125 Sta::sta()->setClockUncertainty(from_clk, from_tr, to_clk, to_tr, min_max,
3126 uncertainty);
3127 }
3128
3129 void
unset_inter_clock_uncertainty(Clock * from_clk,const RiseFallBoth * from_tr,Clock * to_clk,const RiseFallBoth * to_tr,const MinMaxAll * min_max)3130 unset_inter_clock_uncertainty(Clock *from_clk,
3131 const RiseFallBoth *from_tr,
3132 Clock *to_clk,
3133 const RiseFallBoth *to_tr,
3134 const MinMaxAll *min_max)
3135 {
3136 cmdLinkedNetwork();
3137 Sta::sta()->removeClockUncertainty(from_clk, from_tr, to_clk, to_tr, min_max);
3138 }
3139
3140 void
set_clock_gating_check_cmd(const RiseFallBoth * rf,const SetupHold * setup_hold,float margin)3141 set_clock_gating_check_cmd(const RiseFallBoth *rf,
3142 const SetupHold *setup_hold,
3143 float margin)
3144 {
3145 Sta::sta()->setClockGatingCheck(rf, setup_hold, margin);
3146 }
3147
3148 void
set_clock_gating_check_clk_cmd(Clock * clk,const RiseFallBoth * rf,const SetupHold * setup_hold,float margin)3149 set_clock_gating_check_clk_cmd(Clock *clk,
3150 const RiseFallBoth *rf,
3151 const SetupHold *setup_hold,
3152 float margin)
3153 {
3154 Sta::sta()->setClockGatingCheck(clk, rf, setup_hold, margin);
3155 }
3156
3157 void
set_clock_gating_check_pin_cmd(Pin * pin,const RiseFallBoth * rf,const SetupHold * setup_hold,float margin,LogicValue active_value)3158 set_clock_gating_check_pin_cmd(Pin *pin,
3159 const RiseFallBoth *rf,
3160 const SetupHold *setup_hold,
3161 float margin,
3162 LogicValue active_value)
3163 {
3164 Sta::sta()->setClockGatingCheck(pin, rf, setup_hold, margin, active_value);
3165 }
3166
3167 void
set_clock_gating_check_instance_cmd(Instance * inst,const RiseFallBoth * rf,const SetupHold * setup_hold,float margin,LogicValue active_value)3168 set_clock_gating_check_instance_cmd(Instance *inst,
3169 const RiseFallBoth *rf,
3170 const SetupHold *setup_hold,
3171 float margin,
3172 LogicValue active_value)
3173 {
3174 Sta::sta()->setClockGatingCheck(inst, rf, setup_hold, margin, active_value);
3175 }
3176
3177 void
set_data_check_cmd(Pin * from,const RiseFallBoth * from_rf,Pin * to,const RiseFallBoth * to_rf,Clock * clk,const SetupHoldAll * setup_hold,float margin)3178 set_data_check_cmd(Pin *from,
3179 const RiseFallBoth *from_rf,
3180 Pin *to,
3181 const RiseFallBoth *to_rf,
3182 Clock *clk,
3183 const SetupHoldAll *setup_hold,
3184 float margin)
3185 {
3186 Sta::sta()->setDataCheck(from, from_rf, to, to_rf, clk, setup_hold, margin);
3187 }
3188
3189 void
unset_data_check_cmd(Pin * from,const RiseFallBoth * from_tr,Pin * to,const RiseFallBoth * to_tr,Clock * clk,const SetupHoldAll * setup_hold)3190 unset_data_check_cmd(Pin *from,
3191 const RiseFallBoth *from_tr,
3192 Pin *to,
3193 const RiseFallBoth *to_tr,
3194 Clock *clk,
3195 const SetupHoldAll *setup_hold)
3196 {
3197 Sta::sta()->removeDataCheck(from, from_tr, to, to_tr, clk, setup_hold);
3198 }
3199
3200 void
set_input_delay_cmd(Pin * pin,RiseFallBoth * rf,Clock * clk,RiseFall * clk_rf,Pin * ref_pin,bool source_latency_included,bool network_latency_included,MinMaxAll * min_max,bool add,float delay)3201 set_input_delay_cmd(Pin *pin,
3202 RiseFallBoth *rf,
3203 Clock *clk,
3204 RiseFall *clk_rf,
3205 Pin *ref_pin,
3206 bool source_latency_included,
3207 bool network_latency_included,
3208 MinMaxAll *min_max,
3209 bool add,
3210 float delay)
3211 {
3212 cmdLinkedNetwork();
3213 Sta::sta()->setInputDelay(pin, rf, clk, clk_rf, ref_pin,
3214 source_latency_included, network_latency_included,
3215 min_max, add, delay);
3216 }
3217
3218 void
unset_input_delay_cmd(Pin * pin,RiseFallBoth * rf,Clock * clk,RiseFall * clk_rf,MinMaxAll * min_max)3219 unset_input_delay_cmd(Pin *pin,
3220 RiseFallBoth *rf,
3221 Clock *clk,
3222 RiseFall *clk_rf,
3223 MinMaxAll *min_max)
3224 {
3225 cmdLinkedNetwork();
3226 Sta::sta()->removeInputDelay(pin, rf, clk, clk_rf, min_max);
3227 }
3228
3229 void
set_output_delay_cmd(Pin * pin,const RiseFallBoth * rf,Clock * clk,const RiseFall * clk_rf,Pin * ref_pin,bool source_latency_included,bool network_latency_included,const MinMaxAll * min_max,bool add,float delay)3230 set_output_delay_cmd(Pin *pin,
3231 const RiseFallBoth *rf,
3232 Clock *clk,
3233 const RiseFall *clk_rf,
3234 Pin *ref_pin,
3235 bool source_latency_included,
3236 bool network_latency_included,
3237 const MinMaxAll *min_max,
3238 bool add,
3239 float delay)
3240 {
3241 cmdLinkedNetwork();
3242 Sta::sta()->setOutputDelay(pin, rf, clk, clk_rf, ref_pin,
3243 source_latency_included, network_latency_included,
3244 min_max, add, delay);
3245 }
3246
3247 void
unset_output_delay_cmd(Pin * pin,RiseFallBoth * rf,Clock * clk,RiseFall * clk_rf,MinMaxAll * min_max)3248 unset_output_delay_cmd(Pin *pin,
3249 RiseFallBoth *rf,
3250 Clock *clk,
3251 RiseFall *clk_rf,
3252 MinMaxAll *min_max)
3253 {
3254 cmdLinkedNetwork();
3255 Sta::sta()->removeOutputDelay(pin, rf, clk, clk_rf, min_max);
3256 }
3257
3258 void
disable_cell(LibertyCell * cell,LibertyPort * from,LibertyPort * to)3259 disable_cell(LibertyCell *cell,
3260 LibertyPort *from,
3261 LibertyPort *to)
3262 {
3263 cmdLinkedNetwork();
3264 Sta::sta()->disable(cell, from, to);
3265 }
3266
3267 void
unset_disable_cell(LibertyCell * cell,LibertyPort * from,LibertyPort * to)3268 unset_disable_cell(LibertyCell *cell,
3269 LibertyPort *from,
3270 LibertyPort *to)
3271 {
3272 cmdLinkedNetwork();
3273 Sta::sta()->removeDisable(cell, from, to);
3274 }
3275
3276 void
disable_lib_port(LibertyPort * port)3277 disable_lib_port(LibertyPort *port)
3278 {
3279 cmdLinkedNetwork();
3280 Sta::sta()->disable(port);
3281 }
3282
3283 void
unset_disable_lib_port(LibertyPort * port)3284 unset_disable_lib_port(LibertyPort *port)
3285 {
3286 cmdLinkedNetwork();
3287 Sta::sta()->removeDisable(port);
3288 }
3289
3290 void
disable_port(Port * port)3291 disable_port(Port *port)
3292 {
3293 cmdLinkedNetwork();
3294 Sta::sta()->disable(port);
3295 }
3296
3297 void
unset_disable_port(Port * port)3298 unset_disable_port(Port *port)
3299 {
3300 cmdLinkedNetwork();
3301 Sta::sta()->removeDisable(port);
3302 }
3303
3304 void
disable_instance(Instance * instance,LibertyPort * from,LibertyPort * to)3305 disable_instance(Instance *instance,
3306 LibertyPort *from,
3307 LibertyPort *to)
3308 {
3309 cmdLinkedNetwork();
3310 Sta::sta()->disable(instance, from, to);
3311 }
3312
3313 void
unset_disable_instance(Instance * instance,LibertyPort * from,LibertyPort * to)3314 unset_disable_instance(Instance *instance,
3315 LibertyPort *from,
3316 LibertyPort *to)
3317 {
3318 cmdLinkedNetwork();
3319 Sta::sta()->removeDisable(instance, from, to);
3320 }
3321
3322 void
disable_pin(Pin * pin)3323 disable_pin(Pin *pin)
3324 {
3325 cmdLinkedNetwork();
3326 Sta::sta()->disable(pin);
3327 }
3328
3329 void
unset_disable_pin(Pin * pin)3330 unset_disable_pin(Pin *pin)
3331 {
3332 cmdLinkedNetwork();
3333 Sta::sta()->removeDisable(pin);
3334 }
3335
3336 void
disable_edge(Edge * edge)3337 disable_edge(Edge *edge)
3338 {
3339 cmdLinkedNetwork();
3340 Sta::sta()->disable(edge);
3341 }
3342
3343 void
unset_disable_edge(Edge * edge)3344 unset_disable_edge(Edge *edge)
3345 {
3346 cmdLinkedNetwork();
3347 Sta::sta()->removeDisable(edge);
3348 }
3349
3350 void
disable_timing_arc_set(TimingArcSet * arc_set)3351 disable_timing_arc_set(TimingArcSet *arc_set)
3352 {
3353 cmdLinkedNetwork();
3354 Sta::sta()->disable(arc_set);
3355 }
3356
3357 void
unset_disable_timing_arc_set(TimingArcSet * arc_set)3358 unset_disable_timing_arc_set(TimingArcSet *arc_set)
3359 {
3360 cmdLinkedNetwork();
3361 Sta::sta()->removeDisable(arc_set);
3362 }
3363
3364 void
disable_clock_gating_check_inst(Instance * inst)3365 disable_clock_gating_check_inst(Instance *inst)
3366 {
3367 cmdLinkedNetwork();
3368 Sta::sta()->disableClockGatingCheck(inst);
3369 }
3370
3371 void
disable_clock_gating_check_pin(Pin * pin)3372 disable_clock_gating_check_pin(Pin *pin)
3373 {
3374 cmdLinkedNetwork();
3375 Sta::sta()->disableClockGatingCheck(pin);
3376 }
3377
3378 void
unset_disable_clock_gating_check_inst(Instance * inst)3379 unset_disable_clock_gating_check_inst(Instance *inst)
3380 {
3381 cmdLinkedNetwork();
3382 Sta::sta()->removeDisableClockGatingCheck(inst);
3383 }
3384
3385 void
unset_disable_clock_gating_check_pin(Pin * pin)3386 unset_disable_clock_gating_check_pin(Pin *pin)
3387 {
3388 cmdLinkedNetwork();
3389 Sta::sta()->removeDisableClockGatingCheck(pin);
3390 }
3391
3392 void
make_false_path(ExceptionFrom * from,ExceptionThruSeq * thrus,ExceptionTo * to,const MinMaxAll * min_max,const char * comment)3393 make_false_path(ExceptionFrom *from,
3394 ExceptionThruSeq *thrus,
3395 ExceptionTo *to,
3396 const MinMaxAll *min_max,
3397 const char *comment)
3398 {
3399 cmdLinkedNetwork();
3400 Sta::sta()->makeFalsePath(from, thrus, to, min_max, comment);
3401 }
3402
3403 void
make_multicycle_path(ExceptionFrom * from,ExceptionThruSeq * thrus,ExceptionTo * to,const MinMaxAll * min_max,bool use_end_clk,int path_multiplier,const char * comment)3404 make_multicycle_path(ExceptionFrom *from,
3405 ExceptionThruSeq *thrus,
3406 ExceptionTo *to,
3407 const MinMaxAll *min_max,
3408 bool use_end_clk,
3409 int path_multiplier,
3410 const char *comment)
3411 {
3412 cmdLinkedNetwork();
3413 Sta::sta()->makeMulticyclePath(from, thrus, to, min_max, use_end_clk,
3414 path_multiplier, comment);
3415 }
3416
3417 void
make_path_delay(ExceptionFrom * from,ExceptionThruSeq * thrus,ExceptionTo * to,const MinMax * min_max,bool ignore_clk_latency,float delay,const char * comment)3418 make_path_delay(ExceptionFrom *from,
3419 ExceptionThruSeq *thrus,
3420 ExceptionTo *to,
3421 const MinMax *min_max,
3422 bool ignore_clk_latency,
3423 float delay,
3424 const char *comment)
3425 {
3426 cmdLinkedNetwork();
3427 Sta::sta()->makePathDelay(from, thrus, to, min_max,
3428 ignore_clk_latency, delay, comment);
3429 }
3430
3431 void
reset_path_cmd(ExceptionFrom * from,ExceptionThruSeq * thrus,ExceptionTo * to,const MinMaxAll * min_max)3432 reset_path_cmd(ExceptionFrom *
3433 from, ExceptionThruSeq *thrus,
3434 ExceptionTo *to,
3435 const MinMaxAll *min_max)
3436 {
3437 cmdLinkedNetwork();
3438 Sta::sta()->resetPath(from, thrus, to, min_max);
3439 // from/to and thru are owned and deleted by the caller.
3440 // ExceptionThruSeq thrus arg is made by TclListSeqExceptionThru
3441 // in the swig converter so it is deleted here.
3442 delete thrus;
3443 }
3444
3445 void
make_group_path(const char * name,bool is_default,ExceptionFrom * from,ExceptionThruSeq * thrus,ExceptionTo * to,const char * comment)3446 make_group_path(const char *name,
3447 bool is_default,
3448 ExceptionFrom *from,
3449 ExceptionThruSeq *thrus,
3450 ExceptionTo *to,
3451 const char *comment)
3452 {
3453 cmdLinkedNetwork();
3454 if (name[0] == '\0')
3455 name = nullptr;
3456 Sta::sta()->makeGroupPath(name, is_default, from, thrus, to, comment);
3457 }
3458
3459 bool
is_path_group_name(const char * name)3460 is_path_group_name(const char *name)
3461 {
3462 cmdLinkedNetwork();
3463 return Sta::sta()->isGroupPathName(name);
3464 }
3465
3466 ExceptionFrom *
make_exception_from(PinSet * from_pins,ClockSet * from_clks,InstanceSet * from_insts,const RiseFallBoth * from_tr)3467 make_exception_from(PinSet *from_pins,
3468 ClockSet *from_clks,
3469 InstanceSet *from_insts,
3470 const RiseFallBoth *from_tr)
3471 {
3472 cmdLinkedNetwork();
3473 return Sta::sta()->makeExceptionFrom(from_pins, from_clks, from_insts,
3474 from_tr);
3475 }
3476
3477 void
delete_exception_from(ExceptionFrom * from)3478 delete_exception_from(ExceptionFrom *from)
3479 {
3480 Sta::sta()->deleteExceptionFrom(from);
3481 }
3482
3483 void
check_exception_from_pins(ExceptionFrom * from,const char * file,int line)3484 check_exception_from_pins(ExceptionFrom *from,
3485 const char *file,
3486 int line)
3487 {
3488 Sta::sta()->checkExceptionFromPins(from, file, line);
3489 }
3490
3491 ExceptionThru *
make_exception_thru(PinSet * pins,NetSet * nets,InstanceSet * insts,const RiseFallBoth * rf)3492 make_exception_thru(PinSet *pins,
3493 NetSet *nets,
3494 InstanceSet *insts,
3495 const RiseFallBoth *rf)
3496 {
3497 cmdLinkedNetwork();
3498 return Sta::sta()->makeExceptionThru(pins, nets, insts, rf);
3499 }
3500
3501 void
delete_exception_thru(ExceptionThru * thru)3502 delete_exception_thru(ExceptionThru *thru)
3503 {
3504 Sta::sta()->deleteExceptionThru(thru);
3505 }
3506
3507 ExceptionTo *
make_exception_to(PinSet * to_pins,ClockSet * to_clks,InstanceSet * to_insts,const RiseFallBoth * rf,RiseFallBoth * end_rf)3508 make_exception_to(PinSet *to_pins,
3509 ClockSet *to_clks,
3510 InstanceSet *to_insts,
3511 const RiseFallBoth *rf,
3512 RiseFallBoth *end_rf)
3513 {
3514 cmdLinkedNetwork();
3515 return Sta::sta()->makeExceptionTo(to_pins, to_clks, to_insts, rf, end_rf);
3516 }
3517
3518 void
delete_exception_to(ExceptionTo * to)3519 delete_exception_to(ExceptionTo *to)
3520 {
3521 Sta::sta()->deleteExceptionTo(to);
3522 }
3523
3524 void
check_exception_to_pins(ExceptionTo * to,const char * file,int line)3525 check_exception_to_pins(ExceptionTo *to,
3526 const char *file,
3527 int line)
3528 {
3529 Sta::sta()->checkExceptionToPins(to, file, line);
3530 }
3531
3532 void
set_input_slew_cmd(Port * port,const RiseFallBoth * rf,const MinMaxAll * min_max,float slew)3533 set_input_slew_cmd(Port *port,
3534 const RiseFallBoth *rf,
3535 const MinMaxAll *min_max,
3536 float slew)
3537 {
3538 cmdLinkedNetwork();
3539 Sta::sta()->setInputSlew(port, rf, min_max, slew);
3540 }
3541
3542 void
set_drive_cell_cmd(LibertyLibrary * library,LibertyCell * cell,Port * port,LibertyPort * from_port,float from_slew_rise,float from_slew_fall,LibertyPort * to_port,const RiseFallBoth * rf,const MinMaxAll * min_max)3543 set_drive_cell_cmd(LibertyLibrary *library,
3544 LibertyCell *cell,
3545 Port *port,
3546 LibertyPort *from_port,
3547 float from_slew_rise,
3548 float from_slew_fall,
3549 LibertyPort *to_port,
3550 const RiseFallBoth *rf,
3551 const MinMaxAll *min_max)
3552 {
3553 float from_slews[RiseFall::index_count];
3554 from_slews[RiseFall::riseIndex()] = from_slew_rise;
3555 from_slews[RiseFall::fallIndex()] = from_slew_fall;
3556 Sta::sta()->setDriveCell(library, cell, port, from_port, from_slews,
3557 to_port, rf, min_max);
3558 }
3559
3560 void
set_drive_resistance_cmd(Port * port,const RiseFallBoth * rf,const MinMaxAll * min_max,float res)3561 set_drive_resistance_cmd(Port *port,
3562 const RiseFallBoth *rf,
3563 const MinMaxAll *min_max,
3564 float res)
3565 {
3566 cmdLinkedNetwork();
3567 Sta::sta()->setDriveResistance(port, rf, min_max, res);
3568 }
3569
3570 void
set_slew_limit_clk(Clock * clk,const RiseFallBoth * rf,PathClkOrData clk_data,const MinMax * min_max,float slew)3571 set_slew_limit_clk(Clock *clk,
3572 const RiseFallBoth *rf,
3573 PathClkOrData clk_data,
3574 const MinMax *min_max,
3575 float slew)
3576 {
3577 cmdLinkedNetwork();
3578 Sta::sta()->setSlewLimit(clk, rf, clk_data, min_max, slew);
3579 }
3580
3581 void
set_slew_limit_port(Port * port,const MinMax * min_max,float slew)3582 set_slew_limit_port(Port *port,
3583 const MinMax *min_max,
3584 float slew)
3585 {
3586 cmdLinkedNetwork();
3587 Sta::sta()->setSlewLimit(port, min_max, slew);
3588 }
3589
3590 void
set_slew_limit_cell(Cell * cell,const MinMax * min_max,float slew)3591 set_slew_limit_cell(Cell *cell,
3592 const MinMax *min_max,
3593 float slew)
3594 {
3595 cmdLinkedNetwork();
3596 Sta::sta()->setSlewLimit(cell, min_max, slew);
3597 }
3598
3599 void
set_port_capacitance_limit(Port * port,const MinMax * min_max,float cap)3600 set_port_capacitance_limit(Port *port,
3601 const MinMax *min_max,
3602 float cap)
3603 {
3604 Sta::sta()->setCapacitanceLimit(port, min_max, cap);
3605 }
3606
3607 void
set_pin_capacitance_limit(Pin * pin,const MinMax * min_max,float cap)3608 set_pin_capacitance_limit(Pin *pin,
3609 const MinMax *min_max,
3610 float cap)
3611 {
3612 Sta::sta()->setCapacitanceLimit(pin, min_max, cap);
3613 }
3614
3615 void
set_cell_capacitance_limit(Cell * cell,const MinMax * min_max,float cap)3616 set_cell_capacitance_limit(Cell *cell,
3617 const MinMax *min_max,
3618 float cap)
3619 {
3620 Sta::sta()->setCapacitanceLimit(cell, min_max, cap);
3621 }
3622
3623 void
set_latch_borrow_limit_pin(Pin * pin,float limit)3624 set_latch_borrow_limit_pin(Pin *pin,
3625 float limit)
3626 {
3627 Sta::sta()->setLatchBorrowLimit(pin, limit);
3628 }
3629
3630 void
set_latch_borrow_limit_inst(Instance * inst,float limit)3631 set_latch_borrow_limit_inst(Instance *inst,
3632 float limit)
3633 {
3634 Sta::sta()->setLatchBorrowLimit(inst, limit);
3635 }
3636
3637 void
set_latch_borrow_limit_clk(Clock * clk,float limit)3638 set_latch_borrow_limit_clk(Clock *clk, float limit)
3639 {
3640 Sta::sta()->setLatchBorrowLimit(clk, limit);
3641 }
3642
3643 void
set_min_pulse_width_global(const RiseFallBoth * rf,float min_width)3644 set_min_pulse_width_global(const RiseFallBoth *rf,
3645 float min_width)
3646 {
3647 Sta::sta()->setMinPulseWidth(rf, min_width);
3648 }
3649
3650 void
set_min_pulse_width_pin(Pin * pin,const RiseFallBoth * rf,float min_width)3651 set_min_pulse_width_pin(Pin *pin,
3652 const RiseFallBoth *rf,
3653 float min_width)
3654 {
3655 Sta::sta()->setMinPulseWidth(pin, rf, min_width);
3656 }
3657
3658 void
set_min_pulse_width_clk(Clock * clk,const RiseFallBoth * rf,float min_width)3659 set_min_pulse_width_clk(Clock *clk,
3660 const RiseFallBoth *rf,
3661 float min_width)
3662 {
3663 Sta::sta()->setMinPulseWidth(clk, rf, min_width);
3664 }
3665
3666 void
set_min_pulse_width_inst(Instance * inst,const RiseFallBoth * rf,float min_width)3667 set_min_pulse_width_inst(Instance *inst,
3668 const RiseFallBoth *rf,
3669 float min_width)
3670 {
3671 Sta::sta()->setMinPulseWidth(inst, rf, min_width);
3672 }
3673
3674 void
set_max_area_cmd(float area)3675 set_max_area_cmd(float area)
3676 {
3677 Sta::sta()->setMaxArea(area);
3678 }
3679
3680 void
set_port_fanout_limit(Port * port,const MinMax * min_max,float fanout)3681 set_port_fanout_limit(Port *port,
3682 const MinMax *min_max,
3683 float fanout)
3684 {
3685 Sta::sta()->setFanoutLimit(port, min_max, fanout);
3686 }
3687
3688 void
set_cell_fanout_limit(Cell * cell,const MinMax * min_max,float fanout)3689 set_cell_fanout_limit(Cell *cell,
3690 const MinMax *min_max,
3691 float fanout)
3692 {
3693 Sta::sta()->setFanoutLimit(cell, min_max, fanout);
3694 }
3695
3696 void
set_logic_value_cmd(Pin * pin,LogicValue value)3697 set_logic_value_cmd(Pin *pin,
3698 LogicValue value)
3699 {
3700 Sta::sta()->setLogicValue(pin, value);
3701 }
3702
3703 void
set_case_analysis_cmd(Pin * pin,LogicValue value)3704 set_case_analysis_cmd(Pin *pin,
3705 LogicValue value)
3706 {
3707 Sta::sta()->setCaseAnalysis(pin, value);
3708 }
3709
3710 void
unset_case_analysis_cmd(Pin * pin)3711 unset_case_analysis_cmd(Pin *pin)
3712 {
3713 Sta::sta()->removeCaseAnalysis(pin);
3714 }
3715
3716 void
set_timing_derate_cmd(TimingDerateType type,PathClkOrData clk_data,const RiseFallBoth * rf,const EarlyLate * early_late,float derate)3717 set_timing_derate_cmd(TimingDerateType type,
3718 PathClkOrData clk_data,
3719 const RiseFallBoth *rf,
3720 const EarlyLate *early_late,
3721 float derate)
3722 {
3723 Sta::sta()->setTimingDerate(type, clk_data, rf, early_late, derate);
3724 }
3725
3726 void
set_timing_derate_net_cmd(const Net * net,PathClkOrData clk_data,const RiseFallBoth * rf,const EarlyLate * early_late,float derate)3727 set_timing_derate_net_cmd(const Net *net,
3728 PathClkOrData clk_data,
3729 const RiseFallBoth *rf,
3730 const EarlyLate *early_late,
3731 float derate)
3732 {
3733 Sta::sta()->setTimingDerate(net, clk_data, rf, early_late, derate);
3734 }
3735
3736 void
set_timing_derate_inst_cmd(const Instance * inst,TimingDerateType type,PathClkOrData clk_data,const RiseFallBoth * rf,const EarlyLate * early_late,float derate)3737 set_timing_derate_inst_cmd(const Instance *inst,
3738 TimingDerateType type,
3739 PathClkOrData clk_data,
3740 const RiseFallBoth *rf,
3741 const EarlyLate *early_late,
3742 float derate)
3743 {
3744 Sta::sta()->setTimingDerate(inst, type, clk_data, rf, early_late, derate);
3745 }
3746
3747 void
set_timing_derate_cell_cmd(const LibertyCell * cell,TimingDerateType type,PathClkOrData clk_data,const RiseFallBoth * rf,const EarlyLate * early_late,float derate)3748 set_timing_derate_cell_cmd(const LibertyCell *cell,
3749 TimingDerateType type,
3750 PathClkOrData clk_data,
3751 const RiseFallBoth *rf,
3752 const EarlyLate *early_late,
3753 float derate)
3754 {
3755 Sta::sta()->setTimingDerate(cell, type, clk_data, rf, early_late, derate);
3756 }
3757
3758 void
unset_timing_derate_cmd()3759 unset_timing_derate_cmd()
3760 {
3761 Sta::sta()->unsetTimingDerate();
3762 }
3763
3764 ClockIterator *
clock_iterator()3765 clock_iterator()
3766 {
3767 return new ClockIterator(Sta::sta()->sdc());
3768 }
3769
3770 Clock *
find_clock(const char * name)3771 find_clock(const char *name)
3772 {
3773 cmdLinkedNetwork();
3774 return Sta::sta()->sdc()->findClock(name);
3775 }
3776
3777 bool
is_clock_src(const Pin * pin)3778 is_clock_src(const Pin *pin)
3779 {
3780 return Sta::sta()->isClockSrc(pin);
3781 }
3782
3783 Clock *
default_arrival_clock()3784 default_arrival_clock()
3785 {
3786 return Sta::sta()->sdc()->defaultArrivalClock();
3787 }
3788
3789 ClockSeq *
find_clocks_matching(const char * pattern,bool regexp,bool nocase)3790 find_clocks_matching(const char *pattern,
3791 bool regexp,
3792 bool nocase)
3793 {
3794 cmdLinkedNetwork();
3795 ClockSeq *clks = new ClockSeq;
3796 Sta *sta = Sta::sta();
3797 Sdc *sdc = sta->sdc();
3798 PatternMatch matcher(pattern, regexp, nocase, sta->tclInterp());
3799 sdc->findClocksMatching(&matcher, clks);
3800 return clks;
3801 }
3802
3803 void
update_generated_clks()3804 update_generated_clks()
3805 {
3806 cmdLinkedNetwork();
3807 Sta::sta()->updateGeneratedClks();
3808 }
3809
3810 bool
is_clock(Pin * pin)3811 is_clock(Pin *pin)
3812 {
3813 Sta *sta = Sta::sta();
3814 return sta->isClock(pin);
3815 }
3816
3817 bool
is_ideal_clock(Pin * pin)3818 is_ideal_clock(Pin *pin)
3819 {
3820 Sta *sta = Sta::sta();
3821 return sta->isIdealClock(pin);
3822 }
3823
3824 bool
is_clock_search(const Pin * pin)3825 is_clock_search(const Pin *pin)
3826 {
3827 Sta *sta = Sta::sta();
3828 Graph *graph = sta->graph();
3829 Search *search = sta->search();
3830 Vertex *vertex, *bidirect_drvr_vertex;
3831 graph->pinVertices(pin, vertex, bidirect_drvr_vertex);
3832 return search->isClock(vertex);
3833 }
3834
3835 bool
is_genclk_src(const Pin * pin)3836 is_genclk_src(const Pin *pin)
3837 {
3838 Sta *sta = Sta::sta();
3839 Graph *graph = sta->graph();
3840 Search *search = sta->search();
3841 Vertex *vertex, *bidirect_drvr_vertex;
3842 graph->pinVertices(pin, vertex, bidirect_drvr_vertex);
3843 return search->isGenClkSrc(vertex);
3844 }
3845
3846 // format_unit functions print with fixed digits and suffix.
3847 // Pass value arg as string to support NaNs.
3848 const char *
format_time(const char * value,int digits)3849 format_time(const char *value,
3850 int digits)
3851 {
3852 float value1 = strtof(value, nullptr);
3853 return Sta::sta()->units()->timeUnit()->asString(value1, digits);
3854 }
3855
3856 const char *
format_capacitance(const char * value,int digits)3857 format_capacitance(const char *value,
3858 int digits)
3859 {
3860 float value1 = strtof(value, nullptr);
3861 return Sta::sta()->units()->capacitanceUnit()->asString(value1, digits);
3862 }
3863
3864 const char *
format_resistance(const char * value,int digits)3865 format_resistance(const char *value,
3866 int digits)
3867 {
3868 float value1 = strtof(value, nullptr);
3869 return Sta::sta()->units()->resistanceUnit()->asString(value1, digits);
3870 }
3871
3872 const char *
format_voltage(const char * value,int digits)3873 format_voltage(const char *value,
3874 int digits)
3875 {
3876 float value1 = strtof(value, nullptr);
3877 return Sta::sta()->units()->voltageUnit()->asString(value1, digits);
3878 }
3879
3880 const char *
format_power(const char * value,int digits)3881 format_power(const char *value,
3882 int digits)
3883 {
3884 float value1 = strtof(value, nullptr);
3885 return Sta::sta()->units()->powerUnit()->asString(value1, digits);
3886 }
3887
3888 const char *
format_distance(const char * value,int digits)3889 format_distance(const char *value,
3890 int digits)
3891 {
3892 float value1 = strtof(value, nullptr);
3893 Unit *dist_unit = Sta::sta()->units()->distanceUnit();
3894 return dist_unit->asString(value1, digits);
3895 }
3896
3897 const char *
format_area(const char * value,int digits)3898 format_area(const char *value,
3899 int digits)
3900 {
3901 float value1 = strtof(value, nullptr);
3902 Unit *dist_unit = Sta::sta()->units()->distanceUnit();
3903 return dist_unit->asString(value1 / dist_unit->scale(), digits);
3904 }
3905
3906 ////////////////////////////////////////////////////////////////
3907
3908 // Unit converstion from sta unit to user interface and visa versa.
3909 double
time_ui_sta(double value)3910 time_ui_sta(double value)
3911 {
3912 return value * Sta::sta()->units()->timeUnit()->scale();
3913 }
3914
3915 double
time_sta_ui(double value)3916 time_sta_ui(double value)
3917 {
3918 return value / Sta::sta()->units()->timeUnit()->scale();
3919 }
3920
3921 double
capacitance_ui_sta(double value)3922 capacitance_ui_sta(double value)
3923 {
3924 return value * Sta::sta()->units()->capacitanceUnit()->scale();
3925 }
3926
3927 double
capacitance_sta_ui(double value)3928 capacitance_sta_ui(double value)
3929 {
3930 return value / Sta::sta()->units()->capacitanceUnit()->scale();
3931 }
3932
3933 double
resistance_ui_sta(double value)3934 resistance_ui_sta(double value)
3935 {
3936 return value * Sta::sta()->units()->resistanceUnit()->scale();
3937 }
3938
3939 double
resistance_sta_ui(double value)3940 resistance_sta_ui(double value)
3941 {
3942 return value / Sta::sta()->units()->resistanceUnit()->scale();
3943 }
3944
3945 double
voltage_ui_sta(double value)3946 voltage_ui_sta(double value)
3947 {
3948 return value * Sta::sta()->units()->voltageUnit()->scale();
3949 }
3950
3951 double
voltage_sta_ui(double value)3952 voltage_sta_ui(double value)
3953 {
3954 return value / Sta::sta()->units()->voltageUnit()->scale();
3955 }
3956
3957 double
current_ui_sta(double value)3958 current_ui_sta(double value)
3959 {
3960 return value * Sta::sta()->units()->currentUnit()->scale();
3961 }
3962
3963 double
current_sta_ui(double value)3964 current_sta_ui(double value)
3965 {
3966 return value / Sta::sta()->units()->currentUnit()->scale();
3967 }
3968
3969 double
power_ui_sta(double value)3970 power_ui_sta(double value)
3971 {
3972 return value * Sta::sta()->units()->powerUnit()->scale();
3973 }
3974
3975 double
power_sta_ui(double value)3976 power_sta_ui(double value)
3977 {
3978 return value / Sta::sta()->units()->powerUnit()->scale();
3979 }
3980
3981 double
distance_ui_sta(double value)3982 distance_ui_sta(double value)
3983 {
3984 return value * Sta::sta()->units()->distanceUnit()->scale();
3985 }
3986
3987 double
distance_sta_ui(double value)3988 distance_sta_ui(double value)
3989 {
3990 return value / Sta::sta()->units()->distanceUnit()->scale();
3991 }
3992
3993 double
area_ui_sta(double value)3994 area_ui_sta(double value)
3995 {
3996 double scale = Sta::sta()->units()->distanceUnit()->scale();
3997 return value * scale * scale;
3998 }
3999
4000 double
area_sta_ui(double value)4001 area_sta_ui(double value)
4002 {
4003 double scale = Sta::sta()->units()->distanceUnit()->scale();
4004 return value / (scale * scale);
4005 }
4006
4007 ////////////////////////////////////////////////////////////////
4008
4009 void
set_cmd_unit_scale(const char * unit_name,float scale)4010 set_cmd_unit_scale(const char *unit_name,
4011 float scale)
4012 {
4013 Unit *unit = Sta::sta()->units()->find(unit_name);
4014 if (unit)
4015 unit->setScale(scale);
4016 }
4017
4018 void
set_cmd_unit_digits(const char * unit_name,int digits)4019 set_cmd_unit_digits(const char *unit_name,
4020 int digits)
4021 {
4022 Unit *unit = Sta::sta()->units()->find(unit_name);
4023 if (unit)
4024 unit->setDigits(digits);
4025 }
4026
4027 void
set_cmd_unit_suffix(const char * unit_name,const char * suffix)4028 set_cmd_unit_suffix(const char *unit_name,
4029 const char *suffix)
4030 {
4031 Unit *unit = Sta::sta()->units()->find(unit_name);
4032 if (unit) {
4033 unit->setSuffix(suffix);
4034 }
4035 }
4036
4037 const char *
unit_scale_abreviation(const char * unit_name)4038 unit_scale_abreviation(const char *unit_name)
4039 {
4040 Unit *unit = Sta::sta()->units()->find(unit_name);
4041 if (unit)
4042 return unit->scaleAbreviation();
4043 else
4044 return "";
4045 }
4046
4047 const char *
unit_suffix(const char * unit_name)4048 unit_suffix(const char *unit_name)
4049 {
4050 Unit *unit = Sta::sta()->units()->find(unit_name);
4051 if (unit)
4052 return unit->suffix();
4053 else
4054 return "";
4055 }
4056
4057 ////////////////////////////////////////////////////////////////
4058
4059 VertexIterator *
vertex_iterator()4060 vertex_iterator()
4061 {
4062 return new VertexIterator(cmdGraph());
4063 }
4064
4065 void
set_arc_delay(Edge * edge,TimingArc * arc,const Corner * corner,const MinMaxAll * min_max,float delay)4066 set_arc_delay(Edge *edge,
4067 TimingArc *arc,
4068 const Corner *corner,
4069 const MinMaxAll *min_max,
4070 float delay)
4071 {
4072 cmdGraph();
4073 Sta::sta()->setArcDelay(edge, arc, corner, min_max, delay);
4074 }
4075
4076 void
set_annotated_slew(Vertex * vertex,const Corner * corner,const MinMaxAll * min_max,const RiseFallBoth * rf,float slew)4077 set_annotated_slew(Vertex *vertex,
4078 const Corner *corner,
4079 const MinMaxAll *min_max,
4080 const RiseFallBoth *rf,
4081 float slew)
4082 {
4083 cmdGraph();
4084 Sta::sta()->setAnnotatedSlew(vertex, corner, min_max, rf, slew);
4085 }
4086
4087 // Remove all delay and slew annotations.
4088 void
remove_delay_slew_annotations()4089 remove_delay_slew_annotations()
4090 {
4091 cmdGraph();
4092 Sta::sta()->removeDelaySlewAnnotations();
4093 }
4094
4095 CheckErrorSeq &
check_timing_cmd(bool no_input_delay,bool no_output_delay,bool reg_multiple_clks,bool reg_no_clks,bool unconstrained_endpoints,bool loops,bool generated_clks)4096 check_timing_cmd(bool no_input_delay,
4097 bool no_output_delay,
4098 bool reg_multiple_clks,
4099 bool reg_no_clks,
4100 bool unconstrained_endpoints,
4101 bool loops,
4102 bool generated_clks)
4103 {
4104 cmdLinkedNetwork();
4105 return Sta::sta()->checkTiming(no_input_delay, no_output_delay,
4106 reg_multiple_clks, reg_no_clks,
4107 unconstrained_endpoints,
4108 loops, generated_clks);
4109 }
4110
4111 bool
crpr_enabled()4112 crpr_enabled()
4113 {
4114 return Sta::sta()->crprEnabled();
4115 }
4116
4117 void
set_crpr_enabled(bool enabled)4118 set_crpr_enabled(bool enabled)
4119 {
4120 return Sta::sta()->setCrprEnabled(enabled);
4121 }
4122
4123 const char *
crpr_mode()4124 crpr_mode()
4125 {
4126 switch (Sta::sta()->crprMode()) {
4127 case CrprMode::same_transition:
4128 return "same_transition";
4129 case CrprMode::same_pin:
4130 return "same_pin";
4131 default:
4132 return "";
4133 }
4134 }
4135
4136 void
set_crpr_mode(const char * mode)4137 set_crpr_mode(const char *mode)
4138 {
4139 if (stringEq(mode, "same_pin"))
4140 Sta::sta()->setCrprMode(CrprMode::same_pin);
4141 else if (stringEq(mode, "same_transition"))
4142 Sta::sta()->setCrprMode(CrprMode::same_transition);
4143 else
4144 criticalError(272, "unknown common clk pessimism mode.");
4145 }
4146
4147 bool
pocv_enabled()4148 pocv_enabled()
4149 {
4150 return Sta::sta()->pocvEnabled();
4151 }
4152
4153 void
set_pocv_enabled(bool enabled)4154 set_pocv_enabled(bool enabled)
4155 {
4156 #if !SSTA
4157 if (enabled)
4158 Sta::sta()->report()->error(204, "POCV support requires compilation with SSTA=1.");
4159 #endif
4160 return Sta::sta()->setPocvEnabled(enabled);
4161 }
4162
4163 float
pocv_sigma_factor()4164 pocv_sigma_factor()
4165 {
4166 return Sta::sta()->sigmaFactor();
4167 }
4168
4169 void
set_pocv_sigma_factor(float factor)4170 set_pocv_sigma_factor(float factor)
4171 {
4172 Sta::sta()->setSigmaFactor(factor);
4173 }
4174
4175 bool
propagate_gated_clock_enable()4176 propagate_gated_clock_enable()
4177 {
4178 return Sta::sta()->propagateGatedClockEnable();
4179 }
4180
4181 void
set_propagate_gated_clock_enable(bool enable)4182 set_propagate_gated_clock_enable(bool enable)
4183 {
4184 Sta::sta()->setPropagateGatedClockEnable(enable);
4185 }
4186
4187 bool
preset_clr_arcs_enabled()4188 preset_clr_arcs_enabled()
4189 {
4190 return Sta::sta()->presetClrArcsEnabled();
4191 }
4192
4193 void
set_preset_clr_arcs_enabled(bool enable)4194 set_preset_clr_arcs_enabled(bool enable)
4195 {
4196 Sta::sta()->setPresetClrArcsEnabled(enable);
4197 }
4198
4199 bool
cond_default_arcs_enabled()4200 cond_default_arcs_enabled()
4201 {
4202 return Sta::sta()->condDefaultArcsEnabled();
4203 }
4204
4205 void
set_cond_default_arcs_enabled(bool enabled)4206 set_cond_default_arcs_enabled(bool enabled)
4207 {
4208 Sta::sta()->setCondDefaultArcsEnabled(enabled);
4209 }
4210
4211 bool
bidirect_inst_paths_enabled()4212 bidirect_inst_paths_enabled()
4213 {
4214 return Sta::sta()->bidirectInstPathsEnabled();
4215 }
4216
4217 void
set_bidirect_inst_paths_enabled(bool enabled)4218 set_bidirect_inst_paths_enabled(bool enabled)
4219 {
4220 Sta::sta()->setBidirectInstPathsEnabled(enabled);
4221 }
4222
4223 bool
bidirect_net_paths_enabled()4224 bidirect_net_paths_enabled()
4225 {
4226 return Sta::sta()->bidirectNetPathsEnabled();
4227 }
4228
4229 void
set_bidirect_net_paths_enabled(bool enabled)4230 set_bidirect_net_paths_enabled(bool enabled)
4231 {
4232 Sta::sta()->setBidirectNetPathsEnabled(enabled);
4233 }
4234
4235 bool
recovery_removal_checks_enabled()4236 recovery_removal_checks_enabled()
4237 {
4238 return Sta::sta()->recoveryRemovalChecksEnabled();
4239 }
4240
4241 void
set_recovery_removal_checks_enabled(bool enabled)4242 set_recovery_removal_checks_enabled(bool enabled)
4243 {
4244 Sta::sta()->setRecoveryRemovalChecksEnabled(enabled);
4245 }
4246
4247 bool
gated_clk_checks_enabled()4248 gated_clk_checks_enabled()
4249 {
4250 return Sta::sta()->gatedClkChecksEnabled();
4251 }
4252
4253 void
set_gated_clk_checks_enabled(bool enabled)4254 set_gated_clk_checks_enabled(bool enabled)
4255 {
4256 Sta::sta()->setGatedClkChecksEnabled(enabled);
4257 }
4258
4259 bool
dynamic_loop_breaking()4260 dynamic_loop_breaking()
4261 {
4262 return Sta::sta()->dynamicLoopBreaking();
4263 }
4264
4265 void
set_dynamic_loop_breaking(bool enable)4266 set_dynamic_loop_breaking(bool enable)
4267 {
4268 Sta::sta()->setDynamicLoopBreaking(enable);
4269 }
4270
4271 bool
use_default_arrival_clock()4272 use_default_arrival_clock()
4273 {
4274 return Sta::sta()->useDefaultArrivalClock();
4275 }
4276
4277 void
set_use_default_arrival_clock(bool enable)4278 set_use_default_arrival_clock(bool enable)
4279 {
4280 return Sta::sta()->setUseDefaultArrivalClock(enable);
4281 }
4282
4283 bool
propagate_all_clocks()4284 propagate_all_clocks()
4285 {
4286 return Sta::sta()->propagateAllClocks();
4287 }
4288
4289 void
set_propagate_all_clocks(bool prop)4290 set_propagate_all_clocks(bool prop)
4291 {
4292 Sta::sta()->setPropagateAllClocks(prop);
4293 }
4294
4295 ////////////////////////////////////////////////////////////////
4296
4297 PathEndSeq *
find_path_ends(ExceptionFrom * from,ExceptionThruSeq * thrus,ExceptionTo * to,bool unconstrained,Corner * corner,const MinMaxAll * delay_min_max,int group_count,int endpoint_count,bool unique_pins,float slack_min,float slack_max,bool sort_by_slack,PathGroupNameSet * groups,bool setup,bool hold,bool recovery,bool removal,bool clk_gating_setup,bool clk_gating_hold)4298 find_path_ends(ExceptionFrom *from,
4299 ExceptionThruSeq *thrus,
4300 ExceptionTo *to,
4301 bool unconstrained,
4302 Corner *corner,
4303 const MinMaxAll *delay_min_max,
4304 int group_count,
4305 int endpoint_count,
4306 bool unique_pins,
4307 float slack_min,
4308 float slack_max,
4309 bool sort_by_slack,
4310 PathGroupNameSet *groups,
4311 bool setup,
4312 bool hold,
4313 bool recovery,
4314 bool removal,
4315 bool clk_gating_setup,
4316 bool clk_gating_hold)
4317 {
4318 cmdLinkedNetwork();
4319 Sta *sta = Sta::sta();
4320 PathEndSeq *ends = sta->findPathEnds(from, thrus, to, unconstrained,
4321 corner, delay_min_max,
4322 group_count, endpoint_count, unique_pins,
4323 slack_min, slack_max,
4324 sort_by_slack,
4325 groups->size() ? groups : nullptr,
4326 setup, hold,
4327 recovery, removal,
4328 clk_gating_setup, clk_gating_hold);
4329 delete groups;
4330 return ends;
4331 }
4332
4333 void
report_path_end_header()4334 report_path_end_header()
4335 {
4336 Sta::sta()->reportPathEndHeader();
4337 }
4338
4339 void
report_path_end_footer()4340 report_path_end_footer()
4341 {
4342 Sta::sta()->reportPathEndFooter();
4343 }
4344
4345 void
report_path_end(PathEnd * end)4346 report_path_end(PathEnd *end)
4347 {
4348 Sta::sta()->reportPathEnd(end);
4349 }
4350
4351 void
report_path_end2(PathEnd * end,PathEnd * prev_end)4352 report_path_end2(PathEnd *end,
4353 PathEnd *prev_end)
4354 {
4355 Sta::sta()->reportPathEnd(end, prev_end);
4356 }
4357
4358 void
set_report_path_format(ReportPathFormat format)4359 set_report_path_format(ReportPathFormat format)
4360 {
4361 Sta::sta()->setReportPathFormat(format);
4362 }
4363
4364 void
set_report_path_field_order(StringSeq * field_names)4365 set_report_path_field_order(StringSeq *field_names)
4366 {
4367 Sta::sta()->setReportPathFieldOrder(field_names);
4368 delete field_names;
4369 }
4370
4371 void
set_report_path_fields(bool report_input_pin,bool report_net,bool report_cap,bool report_slew)4372 set_report_path_fields(bool report_input_pin,
4373 bool report_net,
4374 bool report_cap,
4375 bool report_slew)
4376 {
4377 Sta::sta()->setReportPathFields(report_input_pin,
4378 report_net,
4379 report_cap,
4380 report_slew);
4381 }
4382
4383 void
set_report_path_field_properties(const char * field_name,const char * title,int width,bool left_justify)4384 set_report_path_field_properties(const char *field_name,
4385 const char *title,
4386 int width,
4387 bool left_justify)
4388 {
4389 Sta *sta = Sta::sta();
4390 ReportField *field = sta->findReportPathField(field_name);
4391 if (field)
4392 field->setProperties(title, width, left_justify);
4393 else
4394 sta->report()->error(607, "unknown report path field %s", field_name);
4395 }
4396
4397 void
set_report_path_field_width(const char * field_name,int width)4398 set_report_path_field_width(const char *field_name,
4399 int width)
4400 {
4401 Sta *sta = Sta::sta();
4402 ReportField *field = sta->findReportPathField(field_name);
4403 if (field)
4404 field->setWidth(width);
4405 else
4406 sta->report()->error(608, "unknown report path field %s", field_name);
4407 }
4408
4409 void
set_report_path_digits(int digits)4410 set_report_path_digits(int digits)
4411 {
4412 Sta::sta()->setReportPathDigits(digits);
4413 }
4414
4415 void
set_report_path_no_split(bool no_split)4416 set_report_path_no_split(bool no_split)
4417 {
4418 Sta::sta()->setReportPathNoSplit(no_split);
4419 }
4420
4421 void
set_report_path_sigmas(bool report_sigmas)4422 set_report_path_sigmas(bool report_sigmas)
4423 {
4424 Sta::sta()->setReportPathSigmas(report_sigmas);
4425 }
4426
4427 void
delete_path_ref(PathRef * path)4428 delete_path_ref(PathRef *path)
4429 {
4430 delete path;
4431 }
4432
4433 void
remove_constraints()4434 remove_constraints()
4435 {
4436 Sta::sta()->removeConstraints();
4437 }
4438
4439 void
report_path_cmd(PathRef * path)4440 report_path_cmd(PathRef *path)
4441 {
4442 Sta::sta()->reportPath(path);
4443 }
4444
4445 void
report_clk_skew(ClockSet * clks,const Corner * corner,const SetupHold * setup_hold,int digits)4446 report_clk_skew(ClockSet *clks,
4447 const Corner *corner,
4448 const SetupHold *setup_hold,
4449 int digits)
4450 {
4451 cmdLinkedNetwork();
4452 Sta::sta()->reportClkSkew(clks, corner, setup_hold, digits);
4453 delete clks;
4454 }
4455
4456 float
worst_clk_skew_cmd(const SetupHold * setup_hold)4457 worst_clk_skew_cmd(const SetupHold *setup_hold)
4458 {
4459 cmdLinkedNetwork();
4460 return Sta::sta()->findWorstClkSkew(setup_hold);
4461 }
4462
4463 TmpPinSet *
startpoints()4464 startpoints()
4465 {
4466 return findStartpoints();
4467 }
4468
4469 TmpPinSet *
endpoints()4470 endpoints()
4471 {
4472 return findEndpoints();
4473 }
4474
4475 TmpPinSet *
group_path_pins(const char * group_path_name)4476 group_path_pins(const char *group_path_name)
4477 {
4478 Sta *sta = Sta::sta();
4479 Sdc *sdc = sta->sdc();
4480 if (sdc->isGroupPathName(group_path_name))
4481 return sta->findGroupPathPins(group_path_name);
4482 else
4483 return nullptr;
4484 }
4485
4486 ////////////////////////////////////////////////////////////////
4487
4488 MinPulseWidthCheckSeq &
min_pulse_width_violations(const Corner * corner)4489 min_pulse_width_violations(const Corner *corner)
4490 {
4491 cmdLinkedNetwork();
4492 return Sta::sta()->minPulseWidthViolations(corner);
4493 }
4494
4495 MinPulseWidthCheckSeq &
min_pulse_width_check_pins(PinSeq * pins,const Corner * corner)4496 min_pulse_width_check_pins(PinSeq *pins,
4497 const Corner *corner)
4498 {
4499 cmdLinkedNetwork();
4500 Sta *sta = Sta::sta();
4501 MinPulseWidthCheckSeq &checks = sta->minPulseWidthChecks(pins, corner);
4502 delete pins;
4503 return checks;
4504 }
4505
4506 MinPulseWidthCheckSeq &
min_pulse_width_checks(const Corner * corner)4507 min_pulse_width_checks(const Corner *corner)
4508 {
4509 cmdLinkedNetwork();
4510 return Sta::sta()->minPulseWidthChecks(corner);
4511 }
4512
4513 MinPulseWidthCheck *
min_pulse_width_check_slack(const Corner * corner)4514 min_pulse_width_check_slack(const Corner *corner)
4515 {
4516 cmdLinkedNetwork();
4517 return Sta::sta()->minPulseWidthSlack(corner);
4518 }
4519
4520 void
report_mpw_checks(MinPulseWidthCheckSeq * checks,bool verbose)4521 report_mpw_checks(MinPulseWidthCheckSeq *checks,
4522 bool verbose)
4523 {
4524 Sta::sta()->reportMpwChecks(checks, verbose);
4525 }
4526
4527 void
report_mpw_check(MinPulseWidthCheck * check,bool verbose)4528 report_mpw_check(MinPulseWidthCheck *check,
4529 bool verbose)
4530 {
4531 Sta::sta()->reportMpwCheck(check, verbose);
4532 }
4533
4534 ////////////////////////////////////////////////////////////////
4535
4536 MinPeriodCheckSeq &
min_period_violations()4537 min_period_violations()
4538 {
4539 cmdLinkedNetwork();
4540 return Sta::sta()->minPeriodViolations();
4541 }
4542
4543 MinPeriodCheck *
min_period_check_slack()4544 min_period_check_slack()
4545 {
4546 cmdLinkedNetwork();
4547 return Sta::sta()->minPeriodSlack();
4548 }
4549
4550 void
report_min_period_checks(MinPeriodCheckSeq * checks,bool verbose)4551 report_min_period_checks(MinPeriodCheckSeq *checks,
4552 bool verbose)
4553 {
4554 Sta::sta()->reportChecks(checks, verbose);
4555 }
4556
4557 void
report_min_period_check(MinPeriodCheck * check,bool verbose)4558 report_min_period_check(MinPeriodCheck *check,
4559 bool verbose)
4560 {
4561 Sta::sta()->reportCheck(check, verbose);
4562 }
4563
4564 ////////////////////////////////////////////////////////////////
4565
4566 MaxSkewCheckSeq &
max_skew_violations()4567 max_skew_violations()
4568 {
4569 cmdLinkedNetwork();
4570 return Sta::sta()->maxSkewViolations();
4571 }
4572
4573 MaxSkewCheck *
max_skew_check_slack()4574 max_skew_check_slack()
4575 {
4576 cmdLinkedNetwork();
4577 return Sta::sta()->maxSkewSlack();
4578 }
4579
4580 void
report_max_skew_checks(MaxSkewCheckSeq * checks,bool verbose)4581 report_max_skew_checks(MaxSkewCheckSeq *checks,
4582 bool verbose)
4583 {
4584 Sta::sta()->reportChecks(checks, verbose);
4585 }
4586
4587 void
report_max_skew_check(MaxSkewCheck * check,bool verbose)4588 report_max_skew_check(MaxSkewCheck *check,
4589 bool verbose)
4590 {
4591 Sta::sta()->reportCheck(check, verbose);
4592 }
4593
4594 ////////////////////////////////////////////////////////////////
4595
4596 void
find_timing_cmd(bool full)4597 find_timing_cmd(bool full)
4598 {
4599 cmdLinkedNetwork();
4600 Sta::sta()->updateTiming(full);
4601 }
4602
4603 void
find_requireds()4604 find_requireds()
4605 {
4606 cmdLinkedNetwork();
4607 Sta::sta()->findRequireds();
4608 }
4609
4610 void
find_delays()4611 find_delays()
4612 {
4613 cmdLinkedNetwork();
4614 Sta::sta()->findDelays();
4615 }
4616
4617 Slack
total_negative_slack_cmd(const MinMax * min_max)4618 total_negative_slack_cmd(const MinMax *min_max)
4619 {
4620 cmdLinkedNetwork();
4621 Sta *sta = Sta::sta();
4622 return sta->totalNegativeSlack(min_max);
4623 }
4624
4625 Slack
total_negative_slack_corner_cmd(const Corner * corner,const MinMax * min_max)4626 total_negative_slack_corner_cmd(const Corner *corner,
4627 const MinMax *min_max)
4628 {
4629 cmdLinkedNetwork();
4630 Sta *sta = Sta::sta();
4631 return sta->totalNegativeSlack(corner, min_max);
4632 }
4633
4634 Slack
worst_slack_cmd(const MinMax * min_max)4635 worst_slack_cmd(const MinMax *min_max)
4636 {
4637 cmdLinkedNetwork();
4638 Sta *sta = Sta::sta();
4639 Slack worst_slack;
4640 Vertex *worst_vertex;
4641 sta->worstSlack(min_max, worst_slack, worst_vertex);
4642 return worst_slack;
4643 }
4644
4645 Vertex *
worst_slack_vertex(const MinMax * min_max)4646 worst_slack_vertex(const MinMax *min_max)
4647 {
4648 cmdLinkedNetwork();
4649 Sta *sta = Sta::sta();
4650 Slack worst_slack;
4651 Vertex *worst_vertex;
4652 sta->worstSlack(min_max, worst_slack, worst_vertex);
4653 return worst_vertex;;
4654 }
4655
4656 Slack
worst_slack_corner(const Corner * corner,const MinMax * min_max)4657 worst_slack_corner(const Corner *corner,
4658 const MinMax *min_max)
4659 {
4660 cmdLinkedNetwork();
4661 Sta *sta = Sta::sta();
4662 Slack worst_slack;
4663 Vertex *worst_vertex;
4664 sta->worstSlack(corner, min_max, worst_slack, worst_vertex);
4665 return worst_slack;
4666 }
4667
4668 PathRef *
vertex_worst_arrival_path(Vertex * vertex,const MinMax * min_max)4669 vertex_worst_arrival_path(Vertex *vertex,
4670 const MinMax *min_max)
4671 {
4672 Sta *sta = Sta::sta();
4673 PathRef path = sta->vertexWorstArrivalPath(vertex, min_max);
4674 if (!path.isNull())
4675 return new PathRef(path);
4676 else
4677 return nullptr;
4678 }
4679
4680 PathRef *
vertex_worst_arrival_path_rf(Vertex * vertex,const RiseFall * rf,MinMax * min_max)4681 vertex_worst_arrival_path_rf(Vertex *vertex,
4682 const RiseFall *rf,
4683 MinMax *min_max)
4684 {
4685 Sta *sta = Sta::sta();
4686 PathRef path = sta->vertexWorstArrivalPath(vertex, rf, min_max);
4687 if (!path.isNull())
4688 return new PathRef(path);
4689 else
4690 return nullptr;
4691 }
4692
4693 PathRef *
vertex_worst_slack_path(Vertex * vertex,const MinMax * min_max)4694 vertex_worst_slack_path(Vertex *vertex,
4695 const MinMax *min_max)
4696 {
4697 Sta *sta = Sta::sta();
4698 PathRef path = sta->vertexWorstSlackPath(vertex, min_max);
4699 if (!path.isNull())
4700 return new PathRef(path);
4701 else
4702 return nullptr;
4703 }
4704
4705 TmpString *
report_delay_calc_cmd(Edge * edge,TimingArc * arc,const Corner * corner,const MinMax * min_max,int digits)4706 report_delay_calc_cmd(Edge *edge,
4707 TimingArc *arc,
4708 const Corner *corner,
4709 const MinMax *min_max,
4710 int digits)
4711 {
4712 cmdLinkedNetwork();
4713 return Sta::sta()->reportDelayCalc(edge, arc, corner, min_max, digits);
4714 }
4715
4716 ////////////////////////////////////////////////////////////////
4717
4718 PinSeq *
check_slew_limits(Net * net,bool violators,const Corner * corner,const MinMax * min_max)4719 check_slew_limits(Net *net,
4720 bool violators,
4721 const Corner *corner,
4722 const MinMax *min_max)
4723 {
4724 cmdLinkedNetwork();
4725 return Sta::sta()->checkSlewLimits(net, violators, corner, min_max);
4726 }
4727
4728 size_t
max_slew_violation_count()4729 max_slew_violation_count()
4730 {
4731 cmdLinkedNetwork();
4732 return Sta::sta()->checkSlewLimits(nullptr, true, nullptr, MinMax::max())->size();
4733 }
4734
4735 void
report_slew_limit_short_header()4736 report_slew_limit_short_header()
4737 {
4738 Sta::sta()->reportSlewLimitShortHeader();
4739 }
4740
4741 void
report_slew_limit_short(Pin * pin,const Corner * corner,const MinMax * min_max)4742 report_slew_limit_short(Pin *pin,
4743 const Corner *corner,
4744 const MinMax *min_max)
4745 {
4746 Sta::sta()->reportSlewLimitShort(pin, corner, min_max);
4747 }
4748
4749 void
report_slew_limit_verbose(Pin * pin,const Corner * corner,const MinMax * min_max)4750 report_slew_limit_verbose(Pin *pin,
4751 const Corner *corner,
4752 const MinMax *min_max)
4753 {
4754 Sta::sta()->reportSlewLimitVerbose(pin, corner, min_max);
4755 }
4756
4757 ////////////////////////////////////////////////////////////////
4758
4759 PinSeq *
check_fanout_limits(Net * net,bool violators,const MinMax * min_max)4760 check_fanout_limits(Net *net,
4761 bool violators,
4762 const MinMax *min_max)
4763 {
4764 cmdLinkedNetwork();
4765 return Sta::sta()->checkFanoutLimits(net, violators, min_max);
4766 }
4767
4768 size_t
max_fanout_violation_count()4769 max_fanout_violation_count()
4770 {
4771 cmdLinkedNetwork();
4772 return Sta::sta()->checkFanoutLimits(nullptr, true, MinMax::max())->size();
4773 }
4774
4775 void
report_fanout_limit_short_header()4776 report_fanout_limit_short_header()
4777 {
4778 Sta::sta()->reportFanoutLimitShortHeader();
4779 }
4780
4781 void
report_fanout_limit_short(Pin * pin,const MinMax * min_max)4782 report_fanout_limit_short(Pin *pin,
4783 const MinMax *min_max)
4784 {
4785 Sta::sta()->reportFanoutLimitShort(pin, min_max);
4786 }
4787
4788 void
report_fanout_limit_verbose(Pin * pin,const MinMax * min_max)4789 report_fanout_limit_verbose(Pin *pin,
4790 const MinMax *min_max)
4791 {
4792 Sta::sta()->reportFanoutLimitVerbose(pin, min_max);
4793 }
4794
4795 ////////////////////////////////////////////////////////////////
4796
4797 PinSeq *
check_capacitance_limits(Net * net,bool violators,const Corner * corner,const MinMax * min_max)4798 check_capacitance_limits(Net *net,
4799 bool violators,
4800 const Corner *corner,
4801 const MinMax *min_max)
4802 {
4803 cmdLinkedNetwork();
4804 return Sta::sta()->checkCapacitanceLimits(net, violators, corner, min_max);
4805 }
4806
4807 size_t
max_capacitance_violation_count()4808 max_capacitance_violation_count()
4809 {
4810 cmdLinkedNetwork();
4811 return Sta::sta()->checkCapacitanceLimits(nullptr, true,nullptr,MinMax::max())->size();
4812 }
4813
4814 void
report_capacitance_limit_short_header()4815 report_capacitance_limit_short_header()
4816 {
4817 Sta::sta()->reportCapacitanceLimitShortHeader();
4818 }
4819
4820 void
report_capacitance_limit_short(Pin * pin,const Corner * corner,const MinMax * min_max)4821 report_capacitance_limit_short(Pin *pin,
4822 const Corner *corner,
4823 const MinMax *min_max)
4824 {
4825 Sta::sta()->reportCapacitanceLimitShort(pin, corner, min_max);
4826 }
4827
4828 void
report_capacitance_limit_verbose(Pin * pin,const Corner * corner,const MinMax * min_max)4829 report_capacitance_limit_verbose(Pin *pin,
4830 const Corner *corner,
4831 const MinMax *min_max)
4832 {
4833 Sta::sta()->reportCapacitanceLimitVerbose(pin, corner, min_max);
4834 }
4835
4836 ////////////////////////////////////////////////////////////////
4837
4838 TmpFloatSeq *
design_power(const Corner * corner)4839 design_power(const Corner *corner)
4840 {
4841 cmdLinkedNetwork();
4842 PowerResult total, sequential, combinational, macro, pad;
4843 Sta::sta()->power(corner, total, sequential, combinational, macro, pad);
4844 FloatSeq *floats = new FloatSeq;
4845 pushPowerResultFloats(total, floats);
4846 pushPowerResultFloats(sequential, floats);
4847 pushPowerResultFloats(combinational, floats);
4848 pushPowerResultFloats(macro, floats);
4849 pushPowerResultFloats(pad, floats);
4850 return floats;
4851 }
4852
4853 TmpFloatSeq *
instance_power(Instance * inst,const Corner * corner)4854 instance_power(Instance *inst,
4855 const Corner *corner)
4856 {
4857 cmdLinkedNetwork();
4858 PowerResult power;
4859 Sta::sta()->power(inst, corner, power);
4860 FloatSeq *floats = new FloatSeq;
4861 floats->push_back(power.internal());
4862 floats->push_back(power.switching());
4863 floats->push_back(power.leakage());
4864 floats->push_back(power.total());
4865 return floats;
4866 }
4867
4868 void
set_power_global_activity(float activity,float duty)4869 set_power_global_activity(float activity,
4870 float duty)
4871 {
4872 Sta::sta()->power()->setGlobalActivity(activity, duty);
4873 }
4874
4875 void
set_power_input_activity(float activity,float duty)4876 set_power_input_activity(float activity,
4877 float duty)
4878 {
4879 return Sta::sta()->power()->setInputActivity(activity, duty);
4880 }
4881
4882 void
set_power_input_port_activity(const Port * input_port,float activity,float duty)4883 set_power_input_port_activity(const Port *input_port,
4884 float activity,
4885 float duty)
4886 {
4887 return Sta::sta()->power()->setInputPortActivity(input_port, activity, duty);
4888 }
4889
4890 void
set_power_pin_activity(const Pin * pin,float activity,float duty)4891 set_power_pin_activity(const Pin *pin,
4892 float activity,
4893 float duty)
4894 {
4895 return Sta::sta()->power()->setUserActivity(pin, activity, duty,
4896 PwrActivityOrigin::user);
4897 }
4898
4899 ////////////////////////////////////////////////////////////////
4900
4901 EdgeSeq *
disabled_edges_sorted()4902 disabled_edges_sorted()
4903 {
4904 cmdLinkedNetwork();
4905 return Sta::sta()->disabledEdgesSorted();
4906 }
4907
4908 void
write_sdc_cmd(const char * filename,bool leaf,bool compatible,bool no_timestamp,int digits)4909 write_sdc_cmd(const char *filename,
4910 bool leaf,
4911 bool compatible,
4912 bool no_timestamp,
4913 int digits)
4914 {
4915 cmdLinkedNetwork();
4916 Sta::sta()->writeSdc(filename, leaf, compatible, no_timestamp, digits);
4917 }
4918
4919 void
write_path_spice_cmd(PathRef * path,const char * spice_filename,const char * subckt_filename,const char * lib_subckt_filename,const char * model_filename,const char * power_name,const char * gnd_name)4920 write_path_spice_cmd(PathRef *path,
4921 const char *spice_filename,
4922 const char *subckt_filename,
4923 const char *lib_subckt_filename,
4924 const char *model_filename,
4925 const char *power_name,
4926 const char *gnd_name)
4927 {
4928 Sta *sta = Sta::sta();
4929 writePathSpice(path, spice_filename, subckt_filename,
4930 lib_subckt_filename, model_filename,
4931 power_name, gnd_name, sta);
4932 }
4933
4934 bool
liberty_supply_exists(const char * supply_name)4935 liberty_supply_exists(const char *supply_name)
4936 {
4937 auto network = Sta::sta()->network();
4938 auto lib = network->defaultLibertyLibrary();
4939 return lib && lib->supplyExists(supply_name);
4940 }
4941
4942 float
unit_scale(const char * unit_name)4943 unit_scale(const char *unit_name)
4944 {
4945 Unit *unit = Sta::sta()->units()->find(unit_name);
4946 if (unit)
4947 return unit->scale();
4948 else
4949 return 1.0F;
4950 }
4951
4952 bool
fuzzy_equal(float value1,float value2)4953 fuzzy_equal(float value1,
4954 float value2)
4955 {
4956 return fuzzyEqual(value1, value2);
4957 }
4958
4959 char
pin_sim_logic_value(const Pin * pin)4960 pin_sim_logic_value(const Pin *pin)
4961 {
4962 return logicValueString(Sta::sta()->simLogicValue(pin));
4963 }
4964
4965 char
pin_case_logic_value(const Pin * pin)4966 pin_case_logic_value(const Pin *pin)
4967 {
4968 Sta *sta = Sta::sta();
4969 Sdc *sdc = sta->sdc();
4970 LogicValue value = LogicValue::unknown;
4971 bool exists;
4972 sdc->caseLogicValue(pin, value, exists);
4973 return logicValueString(value);
4974 }
4975
4976 char
pin_logic_value(const Pin * pin)4977 pin_logic_value(const Pin *pin)
4978 {
4979 Sta *sta = Sta::sta();
4980 Sdc *sdc = sta->sdc();
4981 LogicValue value = LogicValue::unknown;
4982 bool exists;
4983 sdc->logicValue(pin, value, exists);
4984 return logicValueString(value);
4985 }
4986
4987 SlowDrvrIterator *
slow_driver_iterator()4988 slow_driver_iterator()
4989 {
4990 return Sta::sta()->slowDrvrIterator();
4991 }
4992
4993 bool
timing_arc_disabled(Edge * edge,TimingArc * arc)4994 timing_arc_disabled(Edge *edge,
4995 TimingArc *arc)
4996 {
4997 Graph *graph = Sta::sta()->graph();
4998 return !searchThru(edge, arc, graph);
4999 }
5000
5001 ClockGroups *
make_clock_groups(const char * name,bool logically_exclusive,bool physically_exclusive,bool asynchronous,bool allow_paths,const char * comment)5002 make_clock_groups(const char *name,
5003 bool logically_exclusive,
5004 bool physically_exclusive,
5005 bool asynchronous,
5006 bool allow_paths,
5007 const char *comment)
5008 {
5009 return Sta::sta()->makeClockGroups(name, logically_exclusive,
5010 physically_exclusive, asynchronous,
5011 allow_paths, comment);
5012 }
5013
5014 void
clock_groups_make_group(ClockGroups * clk_groups,ClockSet * clks)5015 clock_groups_make_group(ClockGroups *clk_groups,
5016 ClockSet *clks)
5017 {
5018 Sta::sta()->makeClockGroup(clk_groups, clks);
5019 }
5020
5021 void
unset_clock_groups_logically_exclusive(const char * name)5022 unset_clock_groups_logically_exclusive(const char *name)
5023 {
5024 Sta::sta()->removeClockGroupsLogicallyExclusive(name);
5025 }
5026
5027 void
unset_clock_groups_physically_exclusive(const char * name)5028 unset_clock_groups_physically_exclusive(const char *name)
5029 {
5030 Sta::sta()->removeClockGroupsPhysicallyExclusive(name);
5031 }
5032
5033 void
unset_clock_groups_asynchronous(const char * name)5034 unset_clock_groups_asynchronous(const char *name)
5035 {
5036 Sta::sta()->removeClockGroupsAsynchronous(name);
5037 }
5038
5039 // Debugging function.
5040 bool
same_clk_group(Clock * clk1,Clock * clk2)5041 same_clk_group(Clock *clk1,
5042 Clock *clk2)
5043 {
5044 Sta *sta = Sta::sta();
5045 Sdc *sdc = sta->sdc();
5046 return sdc->sameClockGroupExplicit(clk1, clk2);
5047 }
5048
5049 void
set_clock_sense_cmd(PinSet * pins,ClockSet * clks,bool positive,bool negative,bool stop_propagation)5050 set_clock_sense_cmd(PinSet *pins,
5051 ClockSet *clks,
5052 bool positive,
5053 bool negative,
5054 bool stop_propagation)
5055 {
5056 ClockSense sense;
5057 if (positive)
5058 sense = ClockSense::positive;
5059 else if (negative)
5060 sense = ClockSense::negative;
5061 else if (stop_propagation)
5062 sense = ClockSense::stop;
5063 else
5064 criticalError(273, "unknown clock sense");
5065 Sta::sta()->setClockSense(pins, clks, sense);
5066 }
5067
5068 bool
timing_role_is_check(TimingRole * role)5069 timing_role_is_check(TimingRole *role)
5070 {
5071 return role->isTimingCheck();
5072 }
5073
5074 ////////////////////////////////////////////////////////////////
5075
5076 TmpPinSet *
find_fanin_pins(PinSeq * to,bool flat,bool startpoints_only,int inst_levels,int pin_levels,bool thru_disabled,bool thru_constants)5077 find_fanin_pins(PinSeq *to,
5078 bool flat,
5079 bool startpoints_only,
5080 int inst_levels,
5081 int pin_levels,
5082 bool thru_disabled,
5083 bool thru_constants)
5084 {
5085 cmdLinkedNetwork();
5086 Sta *sta = Sta::sta();
5087 PinSet *fanin = sta->findFaninPins(to, flat, startpoints_only,
5088 inst_levels, pin_levels,
5089 thru_disabled, thru_constants);
5090 delete to;
5091 return fanin;
5092 }
5093
5094 TmpInstanceSet *
find_fanin_insts(PinSeq * to,bool flat,bool startpoints_only,int inst_levels,int pin_levels,bool thru_disabled,bool thru_constants)5095 find_fanin_insts(PinSeq *to,
5096 bool flat,
5097 bool startpoints_only,
5098 int inst_levels,
5099 int pin_levels,
5100 bool thru_disabled,
5101 bool thru_constants)
5102 {
5103 cmdLinkedNetwork();
5104 Sta *sta = Sta::sta();
5105 InstanceSet *fanin = sta->findFaninInstances(to, flat, startpoints_only,
5106 inst_levels, pin_levels,
5107 thru_disabled, thru_constants);
5108 delete to;
5109 return fanin;
5110 }
5111
5112 TmpPinSet *
find_fanout_pins(PinSeq * from,bool flat,bool endpoints_only,int inst_levels,int pin_levels,bool thru_disabled,bool thru_constants)5113 find_fanout_pins(PinSeq *from,
5114 bool flat,
5115 bool endpoints_only,
5116 int inst_levels,
5117 int pin_levels,
5118 bool thru_disabled,
5119 bool thru_constants)
5120 {
5121 cmdLinkedNetwork();
5122 Sta *sta = Sta::sta();
5123 PinSet *fanout = sta->findFanoutPins(from, flat, endpoints_only,
5124 inst_levels, pin_levels,
5125 thru_disabled, thru_constants);
5126 delete from;
5127 return fanout;
5128 }
5129
5130 TmpInstanceSet *
find_fanout_insts(PinSeq * from,bool flat,bool endpoints_only,int inst_levels,int pin_levels,bool thru_disabled,bool thru_constants)5131 find_fanout_insts(PinSeq *from,
5132 bool flat,
5133 bool endpoints_only,
5134 int inst_levels,
5135 int pin_levels,
5136 bool thru_disabled,
5137 bool thru_constants)
5138 {
5139 cmdLinkedNetwork();
5140 Sta *sta = Sta::sta();
5141 InstanceSet *fanout = sta->findFanoutInstances(from, flat, endpoints_only,
5142 inst_levels, pin_levels,
5143 thru_disabled, thru_constants);
5144 delete from;
5145 return fanout;
5146 }
5147
5148 TmpPinSet *
net_load_pins(Net * net)5149 net_load_pins(Net *net)
5150 {
5151 Network *network = cmdLinkedNetwork();
5152 PinSet *pins = new PinSet;
5153 NetConnectedPinIterator *pin_iter = network->connectedPinIterator(net);
5154 while (pin_iter->hasNext()) {
5155 Pin *pin = pin_iter->next();
5156 if (network->isLoad(pin))
5157 pins->insert(pin);
5158 }
5159 delete pin_iter;
5160 return pins;
5161 }
5162
5163 TmpPinSet *
net_driver_pins(Net * net)5164 net_driver_pins(Net *net)
5165 {
5166 Network *network = cmdLinkedNetwork();
5167 PinSet *pins = new PinSet;
5168 NetConnectedPinIterator *pin_iter = network->connectedPinIterator(net);
5169 while (pin_iter->hasNext()) {
5170 Pin *pin = pin_iter->next();
5171 if (network->isDriver(pin))
5172 pins->insert(pin);
5173 }
5174 delete pin_iter;
5175 return pins;
5176 }
5177
5178 ////////////////////////////////////////////////////////////////
5179
5180 void
report_loops()5181 report_loops()
5182 {
5183 Sta *sta = Sta::sta();
5184 Network *network = cmdLinkedNetwork();
5185 Graph *graph = cmdGraph();
5186 Report *report = sta->report();
5187 GraphLoopSeq *loops = sta->graphLoops();
5188 GraphLoopSeq::Iterator loop_iter(loops);
5189 while (loop_iter.hasNext()) {
5190 GraphLoop *loop = loop_iter.next();
5191 loop->report(report, network, graph);
5192 report->reportLineString("");
5193 }
5194 }
5195
5196 // Includes top instance.
5197 int
network_instance_count()5198 network_instance_count()
5199 {
5200 Network *network = cmdNetwork();
5201 return network->instanceCount();
5202 }
5203
5204 int
network_pin_count()5205 network_pin_count()
5206 {
5207 Network *network = cmdNetwork();
5208 return network->pinCount();
5209 }
5210
5211 int
network_net_count()5212 network_net_count()
5213 {
5214 Network *network = cmdNetwork();
5215 return network->netCount();
5216 }
5217
5218 int
network_leaf_instance_count()5219 network_leaf_instance_count()
5220 {
5221 Network *network = cmdNetwork();
5222 return network->leafInstanceCount();
5223 }
5224
5225 int
network_leaf_pin_count()5226 network_leaf_pin_count()
5227 {
5228 Network *network = cmdNetwork();
5229 return network->leafPinCount();
5230 }
5231
5232 int
graph_vertex_count()5233 graph_vertex_count()
5234 {
5235 return cmdGraph()->vertexCount();
5236 }
5237
5238 int
graph_edge_count()5239 graph_edge_count()
5240 {
5241 return cmdGraph()->edgeCount();
5242 }
5243
5244 int
graph_arc_count()5245 graph_arc_count()
5246 {
5247 return cmdGraph()->arcCount();
5248 }
5249
5250 int
tag_group_count()5251 tag_group_count()
5252 {
5253 return Sta::sta()->tagGroupCount();
5254 }
5255
5256 void
report_tag_groups()5257 report_tag_groups()
5258 {
5259 Sta::sta()->search()->reportTagGroups();
5260 }
5261
5262 void
report_tag_arrivals_cmd(Vertex * vertex)5263 report_tag_arrivals_cmd(Vertex *vertex)
5264 {
5265 Sta::sta()->search()->reportArrivals(vertex);
5266 }
5267
5268 void
report_arrival_count_histogram()5269 report_arrival_count_histogram()
5270 {
5271 Sta::sta()->search()->reportArrivalCountHistogram();
5272 }
5273
5274 int
tag_count()5275 tag_count()
5276 {
5277 return Sta::sta()->tagCount();
5278 }
5279
5280 void
report_tags()5281 report_tags()
5282 {
5283 Sta::sta()->search()->reportTags();
5284 }
5285
5286 void
report_clk_infos()5287 report_clk_infos()
5288 {
5289 Sta::sta()->search()->reportClkInfos();
5290 }
5291
5292 int
clk_info_count()5293 clk_info_count()
5294 {
5295 return Sta::sta()->clkInfoCount();
5296 }
5297
5298 int
arrival_count()5299 arrival_count()
5300 {
5301 return Sta::sta()->arrivalCount();
5302 }
5303
5304 void
delete_all_memory()5305 delete_all_memory()
5306 {
5307 deleteAllMemory();
5308 }
5309
5310 Tcl_Interp *
tcl_interp()5311 tcl_interp()
5312 {
5313 return Sta::sta()->tclInterp();
5314 }
5315
5316 // Initialize sta after delete_all_memory.
5317 void
init_sta()5318 init_sta()
5319 {
5320 initSta();
5321 }
5322
5323 void
clear_sta()5324 clear_sta()
5325 {
5326 Sta::sta()->clear();
5327 }
5328
5329 void
make_sta(Tcl_Interp * interp)5330 make_sta(Tcl_Interp *interp)
5331 {
5332 Sta *sta = new Sta;
5333 Sta::setSta(sta);
5334 sta->makeComponents();
5335 sta->setTclInterp(interp);
5336 }
5337
5338 void
clear_network()5339 clear_network()
5340 {
5341 Sta *sta = Sta::sta();
5342 sta->network()->clear();
5343 }
5344
5345 // Elapsed run time (in seconds).
5346 double
elapsed_run_time()5347 elapsed_run_time()
5348 {
5349 return elapsedRunTime();
5350 }
5351
5352 // User run time (in seconds).
5353 double
user_run_time()5354 user_run_time()
5355 {
5356 return userRunTime();
5357 }
5358
5359 // User run time (in seconds).
5360 unsigned long
cputime()5361 cputime()
5362 {
5363 return static_cast<unsigned long>(userRunTime() + .5);
5364 }
5365
5366 // Peak memory usage in bytes.
5367 unsigned long
memory_usage()5368 memory_usage()
5369 {
5370 return memoryUsage();
5371 }
5372
5373 int
processor_count()5374 processor_count()
5375 {
5376 return processorCount();
5377 }
5378
5379 int
thread_count()5380 thread_count()
5381 {
5382 return Sta::sta()->threadCount();
5383 }
5384
5385 void
set_thread_count(int count)5386 set_thread_count(int count)
5387 {
5388 Sta::sta()->setThreadCount(count);
5389 }
5390
5391 void
arrivals_invalid()5392 arrivals_invalid()
5393 {
5394 Sta *sta = Sta::sta();
5395 sta->arrivalsInvalid();
5396 }
5397
5398 void
delays_invalid()5399 delays_invalid()
5400 {
5401 Sta *sta = Sta::sta();
5402 sta->delaysInvalid();
5403 }
5404
5405 const char *
pin_location(const Pin * pin)5406 pin_location(const Pin *pin)
5407 {
5408 Network *network = cmdNetwork();
5409 double x, y;
5410 bool exists;
5411 network->location(pin, x, y, exists);
5412 // return x/y as tcl list
5413 if (exists)
5414 return sta::stringPrintTmp("%f %f", x, y);
5415 else
5416 return "";
5417 }
5418
5419 const char *
port_location(const Port * port)5420 port_location(const Port *port)
5421 {
5422 Network *network = cmdNetwork();
5423 const Pin *pin = network->findPin(network->topInstance(), port);
5424 return pin_location(pin);
5425 }
5426
5427 int
endpoint_count()5428 endpoint_count()
5429 {
5430 return Sta::sta()->endpointCount();
5431 }
5432
5433 %} // inline
5434
5435 ////////////////////////////////////////////////////////////////
5436 //
5437 // Object Methods
5438 //
5439 ////////////////////////////////////////////////////////////////
5440
5441 %extend Library {
name()5442 const char *name()
5443 {
5444 return cmdNetwork()->name(self);
5445 }
5446
5447 Cell *
find_cell(const char * name)5448 find_cell(const char *name)
5449 {
5450 return cmdNetwork()->findCell(self, name);
5451 }
5452
5453 TmpCellSeq *
find_cells_matching(const char * pattern,bool regexp,bool nocase)5454 find_cells_matching(const char *pattern,
5455 bool regexp,
5456 bool nocase)
5457 {
5458 PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
5459 TmpCellSeq *cells = new TmpCellSeq;
5460 cmdNetwork()->findCellsMatching(self, &matcher, cells);
5461 return cells;
5462 }
5463
5464 } // Library methods
5465
5466 %extend LibertyLibrary {
name()5467 const char *name() { return self->name(); }
5468
5469 LibertyCell *
find_liberty_cell(const char * name)5470 find_liberty_cell(const char *name)
5471 {
5472 return self->findLibertyCell(name);
5473 }
5474
5475 TmpLibertyCellSeq *
find_liberty_cells_matching(const char * pattern,bool regexp,bool nocase)5476 find_liberty_cells_matching(const char *pattern,
5477 bool regexp,
5478 bool nocase)
5479 {
5480 PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
5481 // TmpLibertyCellSeq deletes temporary CellSeq after conversion to tcl list.
5482 TmpLibertyCellSeq *cells = new TmpLibertyCellSeq;
5483 self->findLibertyCellsMatching(&matcher, cells);
5484 return cells;
5485 }
5486
5487 Wireload *
find_wireload(const char * model_name)5488 find_wireload(const char *model_name)
5489 {
5490 return self->findWireload(model_name);
5491 }
5492
5493 WireloadSelection *
find_wireload_selection(const char * selection_name)5494 find_wireload_selection(const char *selection_name)
5495 {
5496 return self->findWireloadSelection(selection_name);
5497 }
5498
5499 OperatingConditions *
find_operating_conditions(const char * op_cond_name)5500 find_operating_conditions(const char *op_cond_name)
5501 {
5502 return self->findOperatingConditions(op_cond_name);
5503 }
5504
5505 OperatingConditions *
default_operating_conditions()5506 default_operating_conditions()
5507 {
5508 return self->defaultOperatingConditions();
5509 }
5510
5511 } // LibertyLibrary methods
5512
5513 %extend LibraryIterator {
has_next()5514 bool has_next() { return self->hasNext(); }
next()5515 Library *next() { return self->next(); }
finish()5516 void finish() { delete self; }
5517 } // LibraryIterator methods
5518
5519 %extend LibertyLibraryIterator {
has_next()5520 bool has_next() { return self->hasNext(); }
next()5521 LibertyLibrary *next() { return self->next(); }
finish()5522 void finish() { delete self; }
5523 } // LibertyLibraryIterator methods
5524
5525 %extend Cell {
library()5526 Library *library() { return cmdNetwork()->library(self); }
liberty_cell()5527 LibertyCell *liberty_cell() { return cmdNetwork()->libertyCell(self); }
is_leaf()5528 bool is_leaf() { return cmdNetwork()->isLeaf(self); }
5529 CellPortIterator *
port_iterator()5530 port_iterator() { return cmdNetwork()->portIterator(self); }
5531
5532 Port *
find_port(const char * name)5533 find_port(const char *name)
5534 {
5535 return cmdNetwork()->findPort(self, name);
5536 }
5537
5538 TmpPortSeq *
find_ports_matching(const char * pattern,bool regexp,bool nocase)5539 find_ports_matching(const char *pattern,
5540 bool regexp,
5541 bool nocase)
5542 {
5543 PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
5544 TmpPortSeq *ports = new TmpPortSeq;
5545 cmdNetwork()->findPortsMatching(self, &matcher, ports);
5546 return ports;
5547 }
5548
5549 } // Cell methods
5550
5551 %extend LibertyCell {
name()5552 const char *name() { return self->name(); }
is_leaf()5553 bool is_leaf() { return self->isLeaf(); }
is_buffer()5554 bool is_buffer() { return self->isBuffer(); }
is_inverter()5555 bool is_inverter() { return self->isInverter(); }
liberty_library()5556 LibertyLibrary *liberty_library() { return self->libertyLibrary(); }
cell()5557 Cell *cell() { return reinterpret_cast<Cell*>(self); }
5558 LibertyPort *
find_liberty_port(const char * name)5559 find_liberty_port(const char *name)
5560 {
5561 return self->findLibertyPort(name);
5562 }
5563
5564 TmpLibertyPortSeq *
find_liberty_ports_matching(const char * pattern,bool regexp,bool nocase)5565 find_liberty_ports_matching(const char *pattern,
5566 bool regexp,
5567 bool nocase)
5568 {
5569 PatternMatch matcher(pattern, regexp, nocase, Sta::sta()->tclInterp());
5570 TmpLibertyPortSeq *ports = new TmpLibertyPortSeq;
5571 self->findLibertyPortsMatching(&matcher, ports);
5572 return ports;
5573 }
5574
5575 LibertyCellPortIterator *
liberty_port_iterator()5576 liberty_port_iterator() { return new LibertyCellPortIterator(self); }
5577
5578 LibertyCellTimingArcSetIterator *
timing_arc_set_iterator()5579 timing_arc_set_iterator() { return new LibertyCellTimingArcSetIterator(self); }
5580
5581 } // LibertyCell methods
5582
5583 %extend CellPortIterator {
has_next()5584 bool has_next() { return self->hasNext(); }
next()5585 Port *next() { return self->next(); }
finish()5586 void finish() { delete self; }
5587 } // CellPortIterator methods
5588
5589 %extend LibertyCellPortIterator {
has_next()5590 bool has_next() { return self->hasNext(); }
next()5591 LibertyPort *next() { return self->next(); }
finish()5592 void finish() { delete self; }
5593 } // LibertyCellPortIterator methods
5594
5595 %extend Port {
bus_name()5596 const char *bus_name() { return cmdNetwork()->busName(self); }
cell()5597 Cell *cell() { return cmdNetwork()->cell(self); }
liberty_port()5598 LibertyPort *liberty_port() { return cmdNetwork()->libertyPort(self); }
is_bus()5599 bool is_bus() { return cmdNetwork()->isBus(self); }
5600 PortMemberIterator *
member_iterator()5601 member_iterator() { return cmdNetwork()->memberIterator(self); }
5602
5603 } // Port methods
5604
5605 %extend LibertyPort {
bus_name()5606 const char *bus_name() { return self->busName(); }
cell()5607 Cell *cell() { return self->cell(); }
is_bus()5608 bool is_bus() { return self->isBus(); }
5609 LibertyPortMemberIterator *
member_iterator()5610 member_iterator() { return new LibertyPortMemberIterator(self); }
5611
5612 const char *
function()5613 function()
5614 {
5615 FuncExpr *func = self->function();
5616 if (func)
5617 return func->asString();
5618 else
5619 return nullptr;
5620 }
5621
5622 const char *
tristate_enable()5623 tristate_enable()
5624 {
5625 FuncExpr *enable = self->tristateEnable();
5626 if (enable)
5627 return enable->asString();
5628 else
5629 return nullptr;
5630 }
5631
5632 float
capacitance(Corner * corner,const MinMax * min_max)5633 capacitance(Corner *corner,
5634 const MinMax *min_max)
5635 {
5636 Sta *sta = Sta::sta();
5637 return sta->capacitance(self, corner, min_max);
5638 }
5639
5640 } // LibertyPort methods
5641
5642 %extend OperatingConditions {
process()5643 float process() { return self->process(); }
voltage()5644 float voltage() { return self->voltage(); }
temperature()5645 float temperature() { return self->temperature(); }
5646 }
5647
5648 %extend PortMemberIterator {
has_next()5649 bool has_next() { return self->hasNext(); }
next()5650 Port *next() { return self->next(); }
finish()5651 void finish() { delete self; }
5652 } // PortMemberIterator methods
5653
5654 %extend LibertyPortMemberIterator {
has_next()5655 bool has_next() { return self->hasNext(); }
next()5656 LibertyPort *next() { return self->next(); }
finish()5657 void finish() { delete self; }
5658 } // LibertyPortMemberIterator methods
5659
5660 %extend TimingArcSet {
from()5661 LibertyPort *from() { return self->from(); }
to()5662 LibertyPort *to() { return self->to(); }
role()5663 TimingRole *role() { return self->role(); }
sdf_cond()5664 const char *sdf_cond() { return self->sdfCond(); }
5665
5666 const char *
full_name()5667 full_name()
5668 {
5669 const char *from = self->from()->name();
5670 const char *to = self->to()->name();
5671 const char *cell_name = self->libertyCell()->name();
5672 return stringPrintTmp("%s %s -> %s",
5673 cell_name,
5674 from,
5675 to);
5676 }
5677
5678 } // TimingArcSet methods
5679
5680 %extend LibertyCellTimingArcSetIterator {
has_next()5681 bool has_next() { return self->hasNext(); }
next()5682 TimingArcSet *next() { return self->next(); }
finish()5683 void finish() { delete self; }
5684 }
5685
5686 %extend TimingArc {
from()5687 LibertyPort *from() { return self->from(); }
to()5688 LibertyPort *to() { return self->to(); }
from_trans()5689 Transition *from_trans() { return self->fromTrans(); }
from_trans_name()5690 const char *from_trans_name() { return self->fromTrans()->asRiseFall()->name(); }
to_trans()5691 Transition *to_trans() { return self->toTrans(); }
to_trans_name()5692 const char *to_trans_name() { return self->toTrans()->asRiseFall()->name(); }
role()5693 TimingRole *role() { return self->role(); }
5694 } // TimingArc methods
5695
5696 %extend TimingArcSetArcIterator {
has_next()5697 bool has_next() { return self->hasNext(); }
next()5698 TimingArc *next() { return self->next(); }
finish()5699 void finish() { delete self; }
5700 }
5701
5702 %extend Instance {
parent()5703 Instance *parent() { return cmdLinkedNetwork()->parent(self); }
cell()5704 Cell *cell() { return cmdLinkedNetwork()->cell(self); }
liberty_cell()5705 LibertyCell *liberty_cell() { return cmdLinkedNetwork()->libertyCell(self); }
is_leaf()5706 bool is_leaf() { return cmdLinkedNetwork()->isLeaf(self); }
5707 InstanceChildIterator *
child_iterator()5708 child_iterator() { return cmdLinkedNetwork()->childIterator(self); }
5709 InstancePinIterator *
pin_iterator()5710 pin_iterator() { return cmdLinkedNetwork()->pinIterator(self); }
5711 InstanceNetIterator *
net_iterator()5712 net_iterator() { return cmdLinkedNetwork()->netIterator(self); }
5713 Pin *
find_pin(const char * name)5714 find_pin(const char *name)
5715 {
5716 return cmdLinkedNetwork()->findPin(self, name);
5717 }
5718 } // Instance methods
5719
5720 %extend InstanceChildIterator {
has_next()5721 bool has_next() { return self->hasNext(); }
next()5722 Instance *next() { return self->next(); }
finish()5723 void finish() { delete self; }
5724 } // InstanceChildIterator methods
5725
5726 %extend LeafInstanceIterator {
has_next()5727 bool has_next() { return self->hasNext(); }
next()5728 Instance *next() { return self->next(); }
finish()5729 void finish() { delete self; }
5730 } // LeafInstanceIterator methods
5731
5732 %extend InstancePinIterator {
has_next()5733 bool has_next() { return self->hasNext(); }
next()5734 Pin *next() { return self->next(); }
finish()5735 void finish() { delete self; }
5736 } // InstancePinIterator methods
5737
5738 %extend InstanceNetIterator {
has_next()5739 bool has_next() { return self->hasNext(); }
next()5740 Net *next() { return self->next(); }
finish()5741 void finish() { delete self; }
5742 } // InstanceNetIterator methods
5743
5744 %extend Pin {
port_name()5745 const char *port_name() { return cmdLinkedNetwork()->portName(self); }
instance()5746 Instance *instance() { return cmdLinkedNetwork()->instance(self); }
net()5747 Net *net() { return cmdLinkedNetwork()->net(self); }
port()5748 Port *port() { return cmdLinkedNetwork()->port(self); }
term()5749 Term *term() { return cmdLinkedNetwork()->term(self); }
liberty_port()5750 LibertyPort *liberty_port() { return cmdLinkedNetwork()->libertyPort(self); }
is_driver()5751 bool is_driver() { return cmdLinkedNetwork()->isDriver(self); }
is_load()5752 bool is_load() { return cmdLinkedNetwork()->isLoad(self); }
is_leaf()5753 bool is_leaf() { return cmdLinkedNetwork()->isLeaf(self); }
is_hierarchical()5754 bool is_hierarchical() { return cmdLinkedNetwork()->isHierarchical(self); }
is_top_level_port()5755 bool is_top_level_port() { return cmdLinkedNetwork()->isTopLevelPort(self); }
connected_pin_iterator()5756 PinConnectedPinIterator *connected_pin_iterator()
5757 { return cmdLinkedNetwork()->connectedPinIterator(self); }
5758
5759 Vertex **
vertices()5760 vertices()
5761 {
5762 Vertex *vertex, *vertex_bidirect_drvr;
5763 static Vertex *vertices[3];
5764
5765 cmdGraph()->pinVertices(self, vertex, vertex_bidirect_drvr);
5766 vertices[0] = vertex;
5767 vertices[1] = vertex_bidirect_drvr;
5768 vertices[2] = nullptr;
5769 return vertices;
5770 }
5771
5772 float
capacitance(const RiseFall * rf,const Corner * corner,const MinMax * min_max)5773 capacitance(const RiseFall *rf,
5774 const Corner *corner,
5775 const MinMax *min_max)
5776 {
5777 cmdLinkedNetwork();
5778 float pin_cap, wire_cap;
5779 Sta::sta()->connectedCap(self, rf, corner, min_max, pin_cap, wire_cap);
5780 return pin_cap + wire_cap;
5781 }
5782
5783 float
pin_capacitance(const RiseFall * rf,const Corner * corner,const MinMax * min_max)5784 pin_capacitance(const RiseFall *rf,
5785 const Corner *corner,
5786 const MinMax *min_max)
5787 {
5788 cmdLinkedNetwork();
5789 float pin_cap, wire_cap;
5790 Sta::sta()->connectedCap(self, rf, corner, min_max, pin_cap, wire_cap);
5791 return pin_cap;
5792 }
5793
5794 float
wire_capacitance(const RiseFall * rf,const Corner * corner,const MinMax * min_max)5795 wire_capacitance(const RiseFall *rf,
5796 const Corner *corner,
5797 const MinMax *min_max)
5798 {
5799 cmdLinkedNetwork();
5800 float pin_cap, wire_cap;
5801 Sta::sta()->connectedCap(self, rf, corner, min_max, pin_cap, wire_cap);
5802 return wire_cap;
5803 }
5804
5805 } // Pin methods
5806
5807 %extend PinConnectedPinIterator {
has_next()5808 bool has_next() { return self->hasNext(); }
next()5809 Pin *next() { return self->next(); }
finish()5810 void finish() { delete self; }
5811 } // PinConnectedPinIterator methods
5812
5813 %extend Term {
net()5814 Net *net() { return cmdLinkedNetwork()->net(self); }
pin()5815 Pin *pin() { return cmdLinkedNetwork()->pin(self); }
5816 } // Term methods
5817
5818 %extend Net {
instance()5819 Instance *instance() { return cmdLinkedNetwork()->instance(self); }
highest_connected_net()5820 Net *highest_connected_net()
5821 { return cmdLinkedNetwork()->highestConnectedNet(self); }
pin_iterator()5822 NetPinIterator *pin_iterator() { return cmdLinkedNetwork()->pinIterator(self);}
term_iterator()5823 NetTermIterator *term_iterator() {return cmdLinkedNetwork()->termIterator(self);}
connected_pin_iterator()5824 NetConnectedPinIterator *connected_pin_iterator()
5825 { return cmdLinkedNetwork()->connectedPinIterator(self); }
is_power()5826 bool is_power() { return cmdLinkedNetwork()->isPower(self);}
is_ground()5827 bool is_ground() { return cmdLinkedNetwork()->isGround(self);}
5828
5829 float
capacitance(Corner * corner,const MinMax * min_max)5830 capacitance(Corner *corner,
5831 const MinMax *min_max)
5832 {
5833 cmdLinkedNetwork();
5834 float pin_cap, wire_cap;
5835 Sta::sta()->connectedCap(self, corner, min_max, pin_cap, wire_cap);
5836 return pin_cap + wire_cap;
5837 }
5838
5839 float
pin_capacitance(Corner * corner,const MinMax * min_max)5840 pin_capacitance(Corner *corner,
5841 const MinMax *min_max)
5842 {
5843 cmdLinkedNetwork();
5844 float pin_cap, wire_cap;
5845 Sta::sta()->connectedCap(self, corner, min_max, pin_cap, wire_cap);
5846 return pin_cap;
5847 }
5848
5849 float
wire_capacitance(Corner * corner,const MinMax * min_max)5850 wire_capacitance(Corner *corner,
5851 const MinMax *min_max)
5852 {
5853 cmdLinkedNetwork();
5854 float pin_cap, wire_cap;
5855 Sta::sta()->connectedCap(self, corner, min_max, pin_cap, wire_cap);
5856 return wire_cap;
5857 }
5858
5859 // get_ports -of_objects net
5860 TmpPortSeq *
ports()5861 ports()
5862 {
5863 Network *network = cmdLinkedNetwork();
5864 PortSeq *ports = new PortSeq;
5865 if (network->isTopInstance(network->instance(self))) {
5866 NetTermIterator *term_iter = network->termIterator(self);
5867 while (term_iter->hasNext()) {
5868 Term *term = term_iter->next();
5869 Port *port = network->port(network->pin(term));
5870 ports->push_back(port);
5871 }
5872 delete term_iter;
5873 }
5874 return ports;
5875 }
5876
5877 } // Net methods
5878
5879 %extend NetPinIterator {
has_next()5880 bool has_next() { return self->hasNext(); }
next()5881 Pin *next() { return self->next(); }
finish()5882 void finish() { delete self; }
5883 } // NetPinIterator methods
5884
5885 %extend NetTermIterator {
has_next()5886 bool has_next() { return self->hasNext(); }
next()5887 Term *next() { return self->next(); }
finish()5888 void finish() { delete self; }
5889 } // NetTermIterator methods
5890
5891 %extend NetConnectedPinIterator {
has_next()5892 bool has_next() { return self->hasNext(); }
next()5893 Pin *next() { return self->next(); }
finish()5894 void finish() { delete self; }
5895 } // NetConnectedPinIterator methods
5896
5897 %extend Clock {
period()5898 float period() { return self->period(); }
waveform()5899 FloatSeq *waveform() { return self->waveform(); }
time(RiseFall * rf)5900 float time(RiseFall *rf) { return self->edge(rf)->time(); }
is_generated()5901 bool is_generated() { return self->isGenerated(); }
waveform_valid()5902 bool waveform_valid() { return self->waveformValid(); }
is_virtual()5903 bool is_virtual() { return self->isVirtual(); }
is_propagated()5904 bool is_propagated() { return self->isPropagated(); }
sources()5905 PinSet &sources() { return self->pins(); }
5906
5907 float
slew(const RiseFall * rf,const MinMax * min_max)5908 slew(const RiseFall *rf,
5909 const MinMax *min_max)
5910 {
5911 return self->slew(rf, min_max);
5912 }
5913
5914 }
5915
5916 %extend ClockEdge {
clock()5917 Clock *clock() { return self->clock(); }
transition()5918 RiseFall *transition() { return self->transition(); }
time()5919 float time() { return self->time(); }
5920 }
5921
5922 %extend ClockIterator {
has_next()5923 bool has_next() { return self->hasNext(); }
next()5924 Clock *next() { return self->next(); }
finish()5925 void finish() { delete self; }
5926 }
5927
5928 %extend Vertex {
pin()5929 Pin *pin() { return self->pin(); }
is_bidirect_driver()5930 bool is_bidirect_driver() { return self->isBidirectDriver(); }
level()5931 int level() { return Sta::sta()->vertexLevel(self); }
tag_group_index()5932 int tag_group_index() { return self->tagGroupIndex(); }
5933
5934 Slew
slew(const RiseFall * rf,const MinMax * min_max)5935 slew(const RiseFall *rf,
5936 const MinMax *min_max)
5937 {
5938 Sta *sta = Sta::sta();
5939 return sta->vertexSlew(self, rf, min_max);
5940 }
5941
5942 Slew
slew_corner(const RiseFall * rf,const Corner * corner,const MinMax * min_max)5943 slew_corner(const RiseFall *rf,
5944 const Corner *corner,
5945 const MinMax *min_max)
5946 {
5947 Sta *sta = Sta::sta();
5948 return sta->vertexSlew(self, rf, corner, min_max);
5949 }
5950
5951 VertexOutEdgeIterator *
out_edge_iterator()5952 out_edge_iterator()
5953 {
5954 return new VertexOutEdgeIterator(self, Sta::sta()->graph());
5955 }
5956
5957 VertexInEdgeIterator *
in_edge_iterator()5958 in_edge_iterator()
5959 {
5960 return new VertexInEdgeIterator(self, Sta::sta()->graph());
5961 }
5962
5963 TmpFloatSeq *
arrivals_clk(const RiseFall * rf,Clock * clk,const RiseFall * clk_rf)5964 arrivals_clk(const RiseFall *rf,
5965 Clock *clk,
5966 const RiseFall *clk_rf)
5967 {
5968 Sta *sta = Sta::sta();
5969 TmpFloatSeq *floats = new FloatSeq;
5970 const ClockEdge *clk_edge = nullptr;
5971 if (clk)
5972 clk_edge = clk->edge(clk_rf);
5973 for (auto path_ap : sta->corners()->pathAnalysisPts()) {
5974 floats->push_back(delayAsFloat(sta->vertexArrival(self, rf, clk_edge,
5975 path_ap)));
5976 }
5977 return floats;
5978 }
5979
5980 TmpStringSeq *
arrivals_clk_delays(const RiseFall * rf,Clock * clk,const RiseFall * clk_rf,int digits)5981 arrivals_clk_delays(const RiseFall *rf,
5982 Clock *clk,
5983 const RiseFall *clk_rf,
5984 int digits)
5985 {
5986 Sta *sta = Sta::sta();
5987 StringSeq *arrivals = new StringSeq;
5988 const ClockEdge *clk_edge = nullptr;
5989 if (clk)
5990 clk_edge = clk->edge(clk_rf);
5991 for (auto path_ap : sta->corners()->pathAnalysisPts()) {
5992 arrivals->push_back(delayAsString(sta->vertexArrival(self, rf, clk_edge,
5993 path_ap),
5994 sta, digits));
5995 }
5996 return arrivals;
5997 }
5998
5999 TmpFloatSeq *
requireds_clk(const RiseFall * rf,Clock * clk,const RiseFall * clk_rf)6000 requireds_clk(const RiseFall *rf,
6001 Clock *clk,
6002 const RiseFall *clk_rf)
6003 {
6004 Sta *sta = Sta::sta();
6005 TmpFloatSeq *floats = new FloatSeq;
6006 const ClockEdge *clk_edge = nullptr;
6007 if (clk)
6008 clk_edge = clk->edge(clk_rf);
6009 for (auto path_ap : sta->corners()->pathAnalysisPts()) {
6010 floats->push_back(delayAsFloat(sta->vertexRequired(self, rf, clk_edge,
6011 path_ap)));
6012 }
6013 return floats;
6014 }
6015
6016 TmpStringSeq *
requireds_clk_delays(const RiseFall * rf,Clock * clk,const RiseFall * clk_rf,int digits)6017 requireds_clk_delays(const RiseFall *rf,
6018 Clock *clk,
6019 const RiseFall *clk_rf,
6020 int digits)
6021 {
6022 Sta *sta = Sta::sta();
6023 StringSeq *requireds = new StringSeq;
6024 const ClockEdge *clk_edge = nullptr;
6025 if (clk)
6026 clk_edge = clk->edge(clk_rf);
6027 for (auto path_ap : sta->corners()->pathAnalysisPts()) {
6028 requireds->push_back(delayAsString(sta->vertexRequired(self, rf, clk_edge,
6029 path_ap),
6030 sta, digits));
6031 }
6032 return requireds;
6033 }
6034
6035 Slack
slack(MinMax * min_max)6036 slack(MinMax *min_max)
6037 {
6038 Sta *sta = Sta::sta();
6039 return sta->vertexSlack(self, min_max);
6040 }
6041
6042 TmpFloatSeq *
slacks(RiseFall * rf)6043 slacks(RiseFall *rf)
6044 {
6045 Sta *sta = Sta::sta();
6046 TmpFloatSeq *floats = new FloatSeq;
6047 for (auto path_ap : sta->corners()->pathAnalysisPts()) {
6048 floats->push_back(delayAsFloat(sta->vertexSlack(self, rf, path_ap)));
6049 }
6050 return floats;
6051 }
6052
6053 // Slack with respect to a clock rise/fall edge.
6054 TmpFloatSeq *
slacks_clk(const RiseFall * rf,Clock * clk,const RiseFall * clk_rf)6055 slacks_clk(const RiseFall *rf,
6056 Clock *clk,
6057 const RiseFall *clk_rf)
6058 {
6059 Sta *sta = Sta::sta();
6060 TmpFloatSeq *floats = new FloatSeq;
6061 const ClockEdge *clk_edge = nullptr;
6062 if (clk)
6063 clk_edge = clk->edge(clk_rf);
6064 for (auto path_ap : sta->corners()->pathAnalysisPts()) {
6065 floats->push_back(delayAsFloat(sta->vertexSlack(self, rf, clk_edge,
6066 path_ap)));
6067 }
6068 return floats;
6069 }
6070
6071 TmpStringSeq *
slacks_clk_delays(const RiseFall * rf,Clock * clk,const RiseFall * clk_rf,int digits)6072 slacks_clk_delays(const RiseFall *rf,
6073 Clock *clk,
6074 const RiseFall *clk_rf,
6075 int digits)
6076 {
6077 Sta *sta = Sta::sta();
6078 StringSeq *slacks = new StringSeq;
6079 const ClockEdge *clk_edge = nullptr;
6080 if (clk)
6081 clk_edge = clk->edge(clk_rf);
6082 for (auto path_ap : sta->corners()->pathAnalysisPts()) {
6083 slacks->push_back(delayAsString(sta->vertexSlack(self, rf, clk_edge,
6084 path_ap),
6085 sta, digits));
6086 }
6087 return slacks;
6088 }
6089
6090 VertexPathIterator *
path_iterator(const RiseFall * rf,const MinMax * min_max)6091 path_iterator(const RiseFall *rf,
6092 const MinMax *min_max)
6093 {
6094 return Sta::sta()->vertexPathIterator(self, rf, min_max);
6095 }
6096
6097 bool
has_downstream_clk_pin()6098 has_downstream_clk_pin()
6099 {
6100 return self->hasDownstreamClkPin();
6101 }
6102
6103 bool
is_clock()6104 is_clock()
6105 {
6106 Sta *sta = Sta::sta();
6107 Search *search = sta->search();
6108 return search->isClock(self);
6109 }
6110
is_disabled_constraint()6111 bool is_disabled_constraint() { return self->isDisabledConstraint(); }
6112
6113 } // Vertex methods
6114
6115 %extend Edge {
from()6116 Vertex *from() { return self->from(Sta::sta()->graph()); }
to()6117 Vertex *to() { return self->to(Sta::sta()->graph()); }
from_pin()6118 Pin *from_pin() { return self->from(Sta::sta()->graph())->pin(); }
to_pin()6119 Pin *to_pin() { return self->to(Sta::sta()->graph())->pin(); }
role()6120 TimingRole *role() { return self->role(); }
sense()6121 const char *sense() { return timingSenseString(self->sense()); }
6122 TimingArcSetArcIterator *
timing_arc_iterator()6123 timing_arc_iterator() { return new TimingArcSetArcIterator(self->timingArcSet()); }
is_disabled_loop()6124 bool is_disabled_loop() { return Sta::sta()->isDisabledLoop(self); }
is_disabled_constraint()6125 bool is_disabled_constraint() { return Sta::sta()->isDisabledConstraint(self);}
is_disabled_constant()6126 bool is_disabled_constant() { return Sta::sta()->isDisabledConstant(self); }
is_disabled_cond_default()6127 bool is_disabled_cond_default()
6128 { return Sta::sta()->isDisabledCondDefault(self); }
6129 TmpPinSet *
disabled_constant_pins()6130 disabled_constant_pins() { return Sta::sta()->disabledConstantPins(self); }
is_disabled_bidirect_inst_path()6131 bool is_disabled_bidirect_inst_path()
6132 { return Sta::sta()->isDisabledBidirectInstPath(self); }
is_disabled_bidirect_net_path()6133 bool is_disabled_bidirect_net_path()
6134 { return Sta::sta()->isDisabledBidirectNetPath(self); }
is_disabled_preset_clear()6135 bool is_disabled_preset_clear()
6136 { return Sta::sta()->isDisabledPresetClr(self); }
6137 const char *
sim_timing_sense()6138 sim_timing_sense(){return timingSenseString(Sta::sta()->simTimingSense(self));}
6139
6140 TmpFloatSeq *
arc_delays(TimingArc * arc)6141 arc_delays(TimingArc *arc)
6142 {
6143 Sta *sta = Sta::sta();
6144 TmpFloatSeq *floats = new FloatSeq;
6145 for (auto dcalc_ap : sta->corners()->dcalcAnalysisPts())
6146 floats->push_back(delayAsFloat(sta->arcDelay(self, arc, dcalc_ap)));
6147 return floats;
6148 }
6149
6150 TmpStringSeq *
arc_delay_strings(TimingArc * arc,int digits)6151 arc_delay_strings(TimingArc *arc,
6152 int digits)
6153 {
6154 Sta *sta = Sta::sta();
6155 StringSeq *delays = new StringSeq;
6156 for (auto dcalc_ap : sta->corners()->dcalcAnalysisPts())
6157 delays->push_back(delayAsString(sta->arcDelay(self, arc, dcalc_ap),
6158 sta, digits));
6159 return delays;
6160 }
6161
6162 bool
delay_annotated(TimingArc * arc,const Corner * corner,const MinMax * min_max)6163 delay_annotated(TimingArc *arc,
6164 const Corner *corner,
6165 const MinMax *min_max)
6166 {
6167 DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(min_max);
6168 return Sta::sta()->arcDelayAnnotated(self, arc, dcalc_ap);
6169 }
6170
6171 float
arc_delay(TimingArc * arc,const Corner * corner,const MinMax * min_max)6172 arc_delay(TimingArc *arc,
6173 const Corner *corner,
6174 const MinMax *min_max)
6175 {
6176 DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(min_max);
6177 return delayAsFloat(Sta::sta()->arcDelay(self, arc, dcalc_ap));
6178 }
6179
6180 const char *
cond()6181 cond()
6182 {
6183 FuncExpr *cond = self->timingArcSet()->cond();
6184 if (cond)
6185 return cond->asString();
6186 else
6187 return nullptr;
6188 }
6189
6190 const char *
mode_name()6191 mode_name()
6192 {
6193 return self->timingArcSet()->modeName();
6194 }
6195
6196 const char *
mode_value()6197 mode_value()
6198 {
6199 return self->timingArcSet()->modeValue();
6200 }
6201
6202 const char *
latch_d_to_q_en()6203 latch_d_to_q_en()
6204 {
6205 if (self->role() == TimingRole::latchDtoQ()) {
6206 Sta *sta = Sta::sta();
6207 const Network *network = sta->cmdNetwork();
6208 const Graph *graph = sta->graph();
6209 Pin *from_pin = self->from(graph)->pin();
6210 Instance *inst = network->instance(from_pin);
6211 LibertyCell *lib_cell = network->libertyCell(inst);
6212 TimingArcSet *d_q_set = self->timingArcSet();
6213 LibertyPort *enable_port;
6214 FuncExpr *enable_func;
6215 RiseFall *enable_rf;
6216 lib_cell->latchEnable(d_q_set, enable_port, enable_func, enable_rf);
6217 const char *en_name = enable_port->name();
6218 return stringPrintTmp("%s %s", en_name, enable_rf->asString());
6219
6220 }
6221 return "";
6222 }
6223
6224 } // Edge methods
6225
6226 %extend VertexIterator {
has_next()6227 bool has_next() { return self->hasNext(); }
next()6228 Vertex *next() { return self->next(); }
finish()6229 void finish() { delete self; }
6230 }
6231
6232 %extend VertexInEdgeIterator {
has_next()6233 bool has_next() { return self->hasNext(); }
next()6234 Edge *next() { return self->next(); }
finish()6235 void finish() { delete self; }
6236 }
6237
6238 %extend VertexOutEdgeIterator {
has_next()6239 bool has_next() { return self->hasNext(); }
next()6240 Edge *next() { return self->next(); }
finish()6241 void finish() { delete self; }
6242 }
6243
6244 %extend PathEnd {
is_unconstrained()6245 bool is_unconstrained() { return self->isUnconstrained(); }
is_check()6246 bool is_check() { return self->isCheck(); }
is_latch_check()6247 bool is_latch_check() { return self->isLatchCheck(); }
is_data_check()6248 bool is_data_check() { return self->isDataCheck(); }
is_output_delay()6249 bool is_output_delay() { return self->isOutputDelay(); }
is_path_delay()6250 bool is_path_delay() { return self->isPathDelay(); }
is_gated_clock()6251 bool is_gated_clock() { return self->isGatedClock(); }
vertex()6252 Vertex *vertex() { return self->vertex(Sta::sta()); }
path()6253 PathRef *path() { return &self->pathRef(); }
end_transition()6254 RiseFall *end_transition()
6255 { return const_cast<RiseFall*>(self->path()->transition(Sta::sta())); }
slack()6256 Slack slack() { return self->slack(Sta::sta()); }
margin()6257 ArcDelay margin() { return self->margin(Sta::sta()); }
data_required_time()6258 Required data_required_time() { return self->requiredTimeOffset(Sta::sta()); }
data_arrival_time()6259 Arrival data_arrival_time() { return self->dataArrivalTimeOffset(Sta::sta()); }
check_role()6260 TimingRole *check_role() { return self->checkRole(Sta::sta()); }
min_max()6261 MinMax *min_max() { return const_cast<MinMax*>(self->minMax(Sta::sta())); }
source_clk_offset()6262 float source_clk_offset() { return self->sourceClkOffset(Sta::sta()); }
source_clk_latency()6263 Arrival source_clk_latency() { return self->sourceClkLatency(Sta::sta()); }
source_clk_insertion_delay()6264 Arrival source_clk_insertion_delay()
6265 { return self->sourceClkInsertionDelay(Sta::sta()); }
target_clk()6266 Clock *target_clk() { return self->targetClk(Sta::sta()); }
target_clk_edge()6267 ClockEdge *target_clk_edge() { return self->targetClkEdge(Sta::sta()); }
target_clk_path()6268 Path *target_clk_path() { return self->targetClkPath(); }
target_clk_time()6269 float target_clk_time() { return self->targetClkTime(Sta::sta()); }
target_clk_offset()6270 float target_clk_offset() { return self->targetClkOffset(Sta::sta()); }
target_clk_mcp_adjustment()6271 float target_clk_mcp_adjustment()
6272 { return self->targetClkMcpAdjustment(Sta::sta()); }
target_clk_delay()6273 Arrival target_clk_delay() { return self->targetClkDelay(Sta::sta()); }
target_clk_insertion_delay()6274 Arrival target_clk_insertion_delay()
6275 { return self->targetClkInsertionDelay(Sta::sta()); }
target_clk_uncertainty()6276 float target_clk_uncertainty()
6277 { return self->targetNonInterClkUncertainty(Sta::sta()); }
inter_clk_uncertainty()6278 float inter_clk_uncertainty()
6279 { return self->interClkUncertainty(Sta::sta()); }
target_clk_arrival()6280 Arrival target_clk_arrival() { return self->targetClkArrival(Sta::sta()); }
path_delay_margin_is_external()6281 bool path_delay_margin_is_external()
6282 { return self->pathDelayMarginIsExternal();}
common_clk_pessimism()6283 Crpr common_clk_pessimism() { return self->commonClkPessimism(Sta::sta()); }
target_clk_end_trans()6284 RiseFall *target_clk_end_trans()
6285 { return const_cast<RiseFall*>(self->targetClkEndTrans(Sta::sta())); }
6286
6287 }
6288
6289 %extend MinPulseWidthCheckSeqIterator {
has_next()6290 bool has_next() { return self->hasNext(); }
next()6291 MinPulseWidthCheck *next() { return self->next(); }
finish()6292 void finish() { delete self; }
6293 } // MinPulseWidthCheckSeqIterator methods
6294
6295 %extend PathRef {
6296 float
arrival()6297 arrival()
6298 {
6299 Sta *sta = Sta::sta();
6300 return delayAsFloat(self->arrival(sta));
6301 }
6302
6303 float
required()6304 required()
6305 {
6306 Sta *sta = Sta::sta();
6307 return delayAsFloat(self->required(sta));
6308 }
6309
6310 float
slack()6311 slack()
6312 {
6313 Sta *sta = Sta::sta();
6314 return delayAsFloat(self->slack(sta));
6315 }
6316
6317 Pin *
pin()6318 pin()
6319 {
6320 Sta *sta = Sta::sta();
6321 return self->pin(sta);
6322 }
6323
6324 const char *
tag()6325 tag()
6326 {
6327 Sta *sta = Sta::sta();
6328 return self->tag(sta)->asString(sta);
6329 }
6330
6331 // mea_opt3
6332 TmpPinSeq *
pins()6333 pins()
6334 {
6335 Sta *sta = Sta::sta();
6336 PinSeq *pins = new PinSeq;
6337 PathRef path1(self);
6338 while (!path1.isNull()) {
6339 pins->push_back(path1.vertex(sta)->pin());
6340 PathRef prev_path;
6341 path1.prevPath(sta, prev_path);
6342 path1.init(prev_path);
6343 }
6344 return pins;
6345 }
6346
6347 }
6348
6349 %extend VertexPathIterator {
has_next()6350 bool has_next() { return self->hasNext(); }
6351 PathRef *
next()6352 next()
6353 {
6354 Path *path = self->next();
6355 return new PathRef(path);
6356 }
6357
finish()6358 void finish() { delete self; }
6359 }
6360
6361 %extend SlowDrvrIterator {
has_next()6362 bool has_next() { return self->hasNext(); }
next()6363 Instance *next() { return self->next(); }
6364 void
finish()6365 finish()
6366 {
6367 delete self->container();
6368 delete self;
6369 }
6370
6371 }
6372
6373 %extend Corner {
name()6374 const char *name() { return self->name(); }
6375 }
6376
6377 // Local Variables:
6378 // mode:c++
6379 // End:
6380