Migrate static helper functions in `StaTclTypes.i` to non-static functions in `TclTypeHelpers.cc`/`.hh` (#182)
* Migrate static helper functions in StaTclTypes.i to non-static functions in StaTclTypeHelpers.cc/.hh * Rename and reorder as requested
This commit is contained in:
parent
aaa9d2d377
commit
cc3b911b6d
|
|
@ -126,6 +126,11 @@ set(STA_SOURCE
|
||||||
parasitics/SpefReader.cc
|
parasitics/SpefReader.cc
|
||||||
parasitics/SpefReaderPvt.hh
|
parasitics/SpefReaderPvt.hh
|
||||||
|
|
||||||
|
power/Power.cc
|
||||||
|
power/VcdReader.cc
|
||||||
|
power/SaifReader.cc
|
||||||
|
power/VcdParse.cc
|
||||||
|
|
||||||
sdc/Clock.cc
|
sdc/Clock.cc
|
||||||
sdc/ClockGatingCheck.cc
|
sdc/ClockGatingCheck.cc
|
||||||
sdc/ClockGroups.cc
|
sdc/ClockGroups.cc
|
||||||
|
|
@ -198,10 +203,7 @@ set(STA_SOURCE
|
||||||
spice/WriteSpice.cc
|
spice/WriteSpice.cc
|
||||||
spice/Xyce.cc
|
spice/Xyce.cc
|
||||||
|
|
||||||
power/Power.cc
|
tcl/TclTypeHelpers.cc
|
||||||
power/VcdReader.cc
|
|
||||||
power/SaifReader.cc
|
|
||||||
power/VcdParse.cc
|
|
||||||
|
|
||||||
util/Debug.cc
|
util/Debug.cc
|
||||||
util/DispatchQueue.cc
|
util/DispatchQueue.cc
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
// OpenSTA, Static Timing Analyzer
|
||||||
|
// Copyright (c) 2024, Parallax Software, Inc.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "ArcDelayCalc.hh"
|
||||||
|
#include "StringSet.hh"
|
||||||
|
#include "StringSeq.hh"
|
||||||
|
|
||||||
|
#include <tcl.h>
|
||||||
|
|
||||||
|
namespace sta {
|
||||||
|
|
||||||
|
#if TCL_MAJOR_VERSION < 9
|
||||||
|
typedef int Tcl_Size;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
StringSet *
|
||||||
|
tclListSetConstChar(Tcl_Obj *const source,
|
||||||
|
Tcl_Interp *interp);
|
||||||
|
|
||||||
|
StringSeq *
|
||||||
|
tclListSeqConstChar(Tcl_Obj *const source,
|
||||||
|
Tcl_Interp *interp);
|
||||||
|
|
||||||
|
StdStringSet *
|
||||||
|
tclListSetStdString(Tcl_Obj *const source,
|
||||||
|
Tcl_Interp *interp);
|
||||||
|
|
||||||
|
void
|
||||||
|
tclArgError(Tcl_Interp *interp,
|
||||||
|
const char *msg,
|
||||||
|
const char *arg);
|
||||||
|
|
||||||
|
void
|
||||||
|
objectListNext(const char *list,
|
||||||
|
const char *type,
|
||||||
|
// Return values.
|
||||||
|
bool &type_match,
|
||||||
|
const char *&next);
|
||||||
|
|
||||||
|
Tcl_Obj *
|
||||||
|
tclArcDcalcArg(ArcDcalcArg &gate,
|
||||||
|
Tcl_Interp *interp);
|
||||||
|
|
||||||
|
ArcDcalcArg
|
||||||
|
arcDcalcArgTcl(Tcl_Obj *obj,
|
||||||
|
Tcl_Interp *interp);
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
@ -39,9 +39,9 @@
|
||||||
#include "PathEnd.hh"
|
#include "PathEnd.hh"
|
||||||
#include "SearchClass.hh"
|
#include "SearchClass.hh"
|
||||||
#include "CircuitSim.hh"
|
#include "CircuitSim.hh"
|
||||||
#include "ArcDelayCalc.hh"
|
|
||||||
#include "Property.hh"
|
#include "Property.hh"
|
||||||
#include "Sta.hh"
|
#include "Sta.hh"
|
||||||
|
#include "TclTypeHelpers.hh"
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
|
|
@ -190,66 +190,6 @@ tclListNetworkSet1(Tcl_Obj *const source,
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
static StringSet *
|
|
||||||
tclListSetConstChar(Tcl_Obj *const source,
|
|
||||||
Tcl_Interp *interp)
|
|
||||||
{
|
|
||||||
Tcl_Size argc;
|
|
||||||
Tcl_Obj **argv;
|
|
||||||
|
|
||||||
if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) {
|
|
||||||
StringSet *set = new StringSet;
|
|
||||||
for (int i = 0; i < argc; i++) {
|
|
||||||
int length;
|
|
||||||
const char *str = Tcl_GetStringFromObj(argv[i], &length);
|
|
||||||
set->insert(str);
|
|
||||||
}
|
|
||||||
return set;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static StringSeq *
|
|
||||||
tclListSeqConstChar(Tcl_Obj *const source,
|
|
||||||
Tcl_Interp *interp)
|
|
||||||
{
|
|
||||||
Tcl_Size argc;
|
|
||||||
Tcl_Obj **argv;
|
|
||||||
|
|
||||||
if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) {
|
|
||||||
StringSeq *seq = new StringSeq;
|
|
||||||
for (int i = 0; i < argc; i++) {
|
|
||||||
int length;
|
|
||||||
const char *str = Tcl_GetStringFromObj(argv[i], &length);
|
|
||||||
seq->push_back(str);
|
|
||||||
}
|
|
||||||
return seq;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static StdStringSet *
|
|
||||||
tclListSetStdString(Tcl_Obj *const source,
|
|
||||||
Tcl_Interp *interp)
|
|
||||||
{
|
|
||||||
Tcl_Size argc;
|
|
||||||
Tcl_Obj **argv;
|
|
||||||
|
|
||||||
if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) {
|
|
||||||
StdStringSet *set = new StdStringSet;
|
|
||||||
for (int i = 0; i < argc; i++) {
|
|
||||||
int length;
|
|
||||||
const char *str = Tcl_GetStringFromObj(argv[i], &length);
|
|
||||||
set->insert(str);
|
|
||||||
}
|
|
||||||
return set;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Sequence out to tcl list.
|
// Sequence out to tcl list.
|
||||||
|
|
@ -315,121 +255,6 @@ setPtrTclList(SET_TYPE *set,
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static void
|
|
||||||
tclArgError(Tcl_Interp *interp,
|
|
||||||
const char *msg,
|
|
||||||
const char *arg)
|
|
||||||
{
|
|
||||||
// Swig does not add try/catch around arg parsing so this cannot use Report::error.
|
|
||||||
string error_msg = "Error: ";
|
|
||||||
error_msg += msg;
|
|
||||||
char *error = stringPrint(error_msg.c_str(), arg);
|
|
||||||
Tcl_SetResult(interp, error, TCL_VOLATILE);
|
|
||||||
stringDelete(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
objectListNext(const char *list,
|
|
||||||
const char *type,
|
|
||||||
// Return values.
|
|
||||||
bool &type_match,
|
|
||||||
const char *&next)
|
|
||||||
{
|
|
||||||
// Default return values (failure).
|
|
||||||
type_match = false;
|
|
||||||
next = nullptr;
|
|
||||||
// _hexaddress_p_type
|
|
||||||
const char *s = list;
|
|
||||||
char ch = *s++;
|
|
||||||
if (ch == '_') {
|
|
||||||
while (*s && isxdigit(*s))
|
|
||||||
s++;
|
|
||||||
if ((s - list - 1) == sizeof(void*) * 2
|
|
||||||
&& *s && *s++ == '_'
|
|
||||||
&& *s && *s++ == 'p'
|
|
||||||
&& *s && *s++ == '_') {
|
|
||||||
const char *t = type;
|
|
||||||
while (*s && *s != ' ') {
|
|
||||||
if (*s != *t)
|
|
||||||
return;
|
|
||||||
s++;
|
|
||||||
t++;
|
|
||||||
}
|
|
||||||
type_match = true;
|
|
||||||
if (*s)
|
|
||||||
next = s + 1;
|
|
||||||
else
|
|
||||||
next = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Tcl_Obj *
|
|
||||||
tclArcDcalcArg(ArcDcalcArg &gate,
|
|
||||||
Tcl_Interp *interp)
|
|
||||||
{
|
|
||||||
Sta *sta = Sta::sta();
|
|
||||||
const Network *network = sta->network();
|
|
||||||
const Instance *drvr = network->instance(gate.drvrPin());
|
|
||||||
const TimingArc *arc = gate.arc();
|
|
||||||
|
|
||||||
Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
|
|
||||||
Tcl_Obj *obj;
|
|
||||||
|
|
||||||
const char *inst_name = network->pathName(drvr);
|
|
||||||
obj = Tcl_NewStringObj(inst_name, strlen(inst_name));
|
|
||||||
Tcl_ListObjAppendElement(interp, list, obj);
|
|
||||||
|
|
||||||
const char *from_name = arc->from()->name();
|
|
||||||
obj = Tcl_NewStringObj(from_name, strlen(from_name));
|
|
||||||
Tcl_ListObjAppendElement(interp, list, obj);
|
|
||||||
|
|
||||||
const char *from_edge = arc->fromEdge()->asString();
|
|
||||||
obj = Tcl_NewStringObj(from_edge, strlen(from_edge));
|
|
||||||
Tcl_ListObjAppendElement(interp, list, obj);
|
|
||||||
|
|
||||||
const char *to_name = arc->to()->name();
|
|
||||||
obj = Tcl_NewStringObj(to_name, strlen(to_name));
|
|
||||||
Tcl_ListObjAppendElement(interp, list, obj);
|
|
||||||
|
|
||||||
const char *to_edge = arc->toEdge()->asString();
|
|
||||||
obj = Tcl_NewStringObj(to_edge, strlen(to_edge));
|
|
||||||
Tcl_ListObjAppendElement(interp, list, obj);
|
|
||||||
|
|
||||||
const char *input_delay = delayAsString(gate.inputDelay(), sta, 3);
|
|
||||||
obj = Tcl_NewStringObj(input_delay, strlen(input_delay));
|
|
||||||
Tcl_ListObjAppendElement(interp, list, obj);
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ArcDcalcArg
|
|
||||||
arcDcalcArgTcl(Tcl_Obj *obj,
|
|
||||||
Tcl_Interp *interp)
|
|
||||||
{
|
|
||||||
Sta *sta = Sta::sta();
|
|
||||||
sta->ensureGraph();
|
|
||||||
int list_argc;
|
|
||||||
Tcl_Obj **list_argv;
|
|
||||||
if (Tcl_ListObjGetElements(interp, obj, &list_argc, &list_argv) == TCL_OK) {
|
|
||||||
const char *input_delay = "0.0";
|
|
||||||
int length;
|
|
||||||
if (list_argc == 6)
|
|
||||||
input_delay = Tcl_GetStringFromObj(list_argv[5], &length);
|
|
||||||
if (list_argc == 5 || list_argc == 6) {
|
|
||||||
return makeArcDcalcArg(Tcl_GetStringFromObj(list_argv[0], &length),
|
|
||||||
Tcl_GetStringFromObj(list_argv[1], &length),
|
|
||||||
Tcl_GetStringFromObj(list_argv[2], &length),
|
|
||||||
Tcl_GetStringFromObj(list_argv[3], &length),
|
|
||||||
Tcl_GetStringFromObj(list_argv[4], &length),
|
|
||||||
input_delay, sta);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sta->report()->warn(2140, "Delay calc arg requires 5 or 6 args.");
|
|
||||||
}
|
|
||||||
return ArcDcalcArg();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
using namespace sta;
|
using namespace sta;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,201 @@
|
||||||
|
// OpenSTA, Static Timing Analyzer
|
||||||
|
// Copyright (c) 2024, Parallax Software, Inc.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "TclTypeHelpers.hh"
|
||||||
|
|
||||||
|
#include "Liberty.hh"
|
||||||
|
#include "Network.hh"
|
||||||
|
#include "Sta.hh"
|
||||||
|
|
||||||
|
namespace sta {
|
||||||
|
|
||||||
|
StringSet *
|
||||||
|
tclListSetConstChar(Tcl_Obj *const source,
|
||||||
|
Tcl_Interp *interp)
|
||||||
|
{
|
||||||
|
Tcl_Size argc;
|
||||||
|
Tcl_Obj **argv;
|
||||||
|
|
||||||
|
if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) {
|
||||||
|
StringSet *set = new StringSet;
|
||||||
|
for (int i = 0; i < argc; i++) {
|
||||||
|
int length;
|
||||||
|
const char *str = Tcl_GetStringFromObj(argv[i], &length);
|
||||||
|
set->insert(str);
|
||||||
|
}
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringSeq *
|
||||||
|
tclListSeqConstChar(Tcl_Obj *const source,
|
||||||
|
Tcl_Interp *interp)
|
||||||
|
{
|
||||||
|
Tcl_Size argc;
|
||||||
|
Tcl_Obj **argv;
|
||||||
|
|
||||||
|
if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) {
|
||||||
|
StringSeq *seq = new StringSeq;
|
||||||
|
for (int i = 0; i < argc; i++) {
|
||||||
|
int length;
|
||||||
|
const char *str = Tcl_GetStringFromObj(argv[i], &length);
|
||||||
|
seq->push_back(str);
|
||||||
|
}
|
||||||
|
return seq;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
StdStringSet *
|
||||||
|
tclListSetStdString(Tcl_Obj *const source,
|
||||||
|
Tcl_Interp *interp)
|
||||||
|
{
|
||||||
|
Tcl_Size argc;
|
||||||
|
Tcl_Obj **argv;
|
||||||
|
|
||||||
|
if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) {
|
||||||
|
StdStringSet *set = new StdStringSet;
|
||||||
|
for (int i = 0; i < argc; i++) {
|
||||||
|
int length;
|
||||||
|
const char *str = Tcl_GetStringFromObj(argv[i], &length);
|
||||||
|
set->insert(str);
|
||||||
|
}
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
tclArgError(Tcl_Interp *interp,
|
||||||
|
const char *msg,
|
||||||
|
const char *arg)
|
||||||
|
{
|
||||||
|
// Swig does not add try/catch around arg parsing so this cannot use Report::error.
|
||||||
|
string error_msg = "Error: ";
|
||||||
|
error_msg += msg;
|
||||||
|
char *error = stringPrint(error_msg.c_str(), arg);
|
||||||
|
Tcl_SetResult(interp, error, TCL_VOLATILE);
|
||||||
|
stringDelete(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
objectListNext(const char *list,
|
||||||
|
const char *type,
|
||||||
|
// Return values.
|
||||||
|
bool &type_match,
|
||||||
|
const char *&next)
|
||||||
|
{
|
||||||
|
// Default return values (failure).
|
||||||
|
type_match = false;
|
||||||
|
next = nullptr;
|
||||||
|
// _hexaddress_p_type
|
||||||
|
const char *s = list;
|
||||||
|
char ch = *s++;
|
||||||
|
if (ch == '_') {
|
||||||
|
while (*s && isxdigit(*s))
|
||||||
|
s++;
|
||||||
|
if ((s - list - 1) == sizeof(void*) * 2
|
||||||
|
&& *s && *s++ == '_'
|
||||||
|
&& *s && *s++ == 'p'
|
||||||
|
&& *s && *s++ == '_') {
|
||||||
|
const char *t = type;
|
||||||
|
while (*s && *s != ' ') {
|
||||||
|
if (*s != *t)
|
||||||
|
return;
|
||||||
|
s++;
|
||||||
|
t++;
|
||||||
|
}
|
||||||
|
type_match = true;
|
||||||
|
if (*s)
|
||||||
|
next = s + 1;
|
||||||
|
else
|
||||||
|
next = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Tcl_Obj *
|
||||||
|
tclArcDcalcArg(ArcDcalcArg &gate,
|
||||||
|
Tcl_Interp *interp)
|
||||||
|
{
|
||||||
|
Sta *sta = Sta::sta();
|
||||||
|
const Network *network = sta->network();
|
||||||
|
const Instance *drvr = network->instance(gate.drvrPin());
|
||||||
|
const TimingArc *arc = gate.arc();
|
||||||
|
|
||||||
|
Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
|
||||||
|
Tcl_Obj *obj;
|
||||||
|
|
||||||
|
const char *inst_name = network->pathName(drvr);
|
||||||
|
obj = Tcl_NewStringObj(inst_name, strlen(inst_name));
|
||||||
|
Tcl_ListObjAppendElement(interp, list, obj);
|
||||||
|
|
||||||
|
const char *from_name = arc->from()->name();
|
||||||
|
obj = Tcl_NewStringObj(from_name, strlen(from_name));
|
||||||
|
Tcl_ListObjAppendElement(interp, list, obj);
|
||||||
|
|
||||||
|
const char *from_edge = arc->fromEdge()->asString();
|
||||||
|
obj = Tcl_NewStringObj(from_edge, strlen(from_edge));
|
||||||
|
Tcl_ListObjAppendElement(interp, list, obj);
|
||||||
|
|
||||||
|
const char *to_name = arc->to()->name();
|
||||||
|
obj = Tcl_NewStringObj(to_name, strlen(to_name));
|
||||||
|
Tcl_ListObjAppendElement(interp, list, obj);
|
||||||
|
|
||||||
|
const char *to_edge = arc->toEdge()->asString();
|
||||||
|
obj = Tcl_NewStringObj(to_edge, strlen(to_edge));
|
||||||
|
Tcl_ListObjAppendElement(interp, list, obj);
|
||||||
|
|
||||||
|
const char *input_delay = delayAsString(gate.inputDelay(), sta, 3);
|
||||||
|
obj = Tcl_NewStringObj(input_delay, strlen(input_delay));
|
||||||
|
Tcl_ListObjAppendElement(interp, list, obj);
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArcDcalcArg
|
||||||
|
arcDcalcArgTcl(Tcl_Obj *obj,
|
||||||
|
Tcl_Interp *interp)
|
||||||
|
{
|
||||||
|
Sta *sta = Sta::sta();
|
||||||
|
sta->ensureGraph();
|
||||||
|
int list_argc;
|
||||||
|
Tcl_Obj **list_argv;
|
||||||
|
if (Tcl_ListObjGetElements(interp, obj, &list_argc, &list_argv) == TCL_OK) {
|
||||||
|
const char *input_delay = "0.0";
|
||||||
|
int length;
|
||||||
|
if (list_argc == 6)
|
||||||
|
input_delay = Tcl_GetStringFromObj(list_argv[5], &length);
|
||||||
|
if (list_argc == 5 || list_argc == 6) {
|
||||||
|
return makeArcDcalcArg(Tcl_GetStringFromObj(list_argv[0], &length),
|
||||||
|
Tcl_GetStringFromObj(list_argv[1], &length),
|
||||||
|
Tcl_GetStringFromObj(list_argv[2], &length),
|
||||||
|
Tcl_GetStringFromObj(list_argv[3], &length),
|
||||||
|
Tcl_GetStringFromObj(list_argv[4], &length),
|
||||||
|
input_delay, sta);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sta->report()->warn(2140, "Delay calc arg requires 5 or 6 args.");
|
||||||
|
}
|
||||||
|
return ArcDcalcArg();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
Loading…
Reference in New Issue