2018-09-28 17:54:21 +02:00
|
|
|
// OpenSTA, Static Timing Analyzer
|
2024-01-12 01:34:49 +01:00
|
|
|
// Copyright (c) 2024, Parallax Software, Inc.
|
2018-09-28 17:54:21 +02:00
|
|
|
//
|
|
|
|
|
// 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
|
2022-01-04 18:17:08 +01:00
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2018-09-28 17:54:21 +02:00
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
//
|
|
|
|
|
// You should have received a copy of the GNU General Public License
|
2022-01-04 18:17:08 +01:00
|
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
2018-09-28 17:54:21 +02:00
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// Define TCL methods for each network object. This works despite the
|
|
|
|
|
// fact that the underlying implementation does not have class methods
|
|
|
|
|
// corresponding to the TCL methods defined here.
|
|
|
|
|
//
|
|
|
|
|
// Note the function name changes from sta naming convention
|
|
|
|
|
// (lower/capitalize) to TCL naming convention (lower/underscore).
|
|
|
|
|
//
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2024-07-22 03:18:35 +02:00
|
|
|
%module sta
|
|
|
|
|
|
|
|
|
|
%{
|
2021-02-14 17:44:35 +01:00
|
|
|
#include "Machine.hh"
|
2020-04-05 23:53:44 +02:00
|
|
|
#include "StaConfig.hh" // STA_VERSION
|
|
|
|
|
#include "Stats.hh"
|
|
|
|
|
#include "Report.hh"
|
|
|
|
|
#include "Error.hh"
|
|
|
|
|
#include "Fuzzy.hh"
|
|
|
|
|
#include "Units.hh"
|
|
|
|
|
#include "Transition.hh"
|
|
|
|
|
#include "Property.hh"
|
|
|
|
|
#include "Sta.hh"
|
2018-09-28 17:54:21 +02:00
|
|
|
|
|
|
|
|
namespace sta {
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// C++ helper functions used by the interface functions.
|
|
|
|
|
// These are not visible in the TCL API.
|
|
|
|
|
//
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
typedef MinPulseWidthCheckSeq::Iterator MinPulseWidthCheckSeqIterator;
|
2020-07-15 20:56:11 +02:00
|
|
|
|
2018-09-28 17:54:21 +02:00
|
|
|
// Get the network for commands.
|
|
|
|
|
Network *
|
|
|
|
|
cmdNetwork()
|
|
|
|
|
{
|
|
|
|
|
return Sta::sta()->cmdNetwork();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Make sure the network has been read and linked.
|
|
|
|
|
// Throwing an error means the caller doesn't have to check the result.
|
|
|
|
|
Network *
|
|
|
|
|
cmdLinkedNetwork()
|
|
|
|
|
{
|
|
|
|
|
Network *network = cmdNetwork();
|
|
|
|
|
if (network->isLinked())
|
|
|
|
|
return network;
|
|
|
|
|
else {
|
2021-03-05 18:03:42 +01:00
|
|
|
Report *report = Sta::sta()->report();
|
2024-01-08 03:23:53 +01:00
|
|
|
report->error(1570, "no network has been linked.");
|
2019-03-13 01:25:53 +01:00
|
|
|
return nullptr;
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Make sure an editable network has been read and linked.
|
|
|
|
|
NetworkEdit *
|
|
|
|
|
cmdEditNetwork()
|
|
|
|
|
{
|
|
|
|
|
Network *network = cmdLinkedNetwork();
|
|
|
|
|
if (network->isEditable())
|
|
|
|
|
return dynamic_cast<NetworkEdit*>(network);
|
|
|
|
|
else {
|
2021-03-05 18:03:42 +01:00
|
|
|
Report *report = Sta::sta()->report();
|
2024-01-08 03:23:53 +01:00
|
|
|
report->error(1571, "network does not support edits.");
|
2019-03-13 01:25:53 +01:00
|
|
|
return nullptr;
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get the graph for commands.
|
|
|
|
|
// Throw to cmd level on failure.
|
|
|
|
|
Graph *
|
|
|
|
|
cmdGraph()
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
|
|
|
|
return Sta::sta()->ensureGraph();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
using namespace sta;
|
|
|
|
|
|
|
|
|
|
%}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// Empty class definitions to make swig happy.
|
|
|
|
|
// Private constructor/destructor so swig doesn't emit them.
|
|
|
|
|
//
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
class Transition
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
Transition();
|
|
|
|
|
~Transition();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// C++ functions visible as TCL functions.
|
|
|
|
|
//
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
%inline %{
|
|
|
|
|
|
2018-11-09 19:04:16 +01:00
|
|
|
float float_inf = INF;
|
|
|
|
|
|
2018-09-28 17:54:21 +02:00
|
|
|
const char *
|
|
|
|
|
version()
|
|
|
|
|
{
|
2019-02-16 21:07:59 +01:00
|
|
|
return STA_VERSION;
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-07 18:58:47 +02:00
|
|
|
const char *
|
|
|
|
|
git_sha1()
|
|
|
|
|
{
|
|
|
|
|
return STA_GIT_SHA1;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-22 20:42:34 +02:00
|
|
|
// Elapsed run time (in seconds).
|
|
|
|
|
double
|
|
|
|
|
elapsed_run_time()
|
|
|
|
|
{
|
|
|
|
|
return elapsedRunTime();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// User run time (in seconds).
|
|
|
|
|
double
|
|
|
|
|
user_run_time()
|
|
|
|
|
{
|
|
|
|
|
return userRunTime();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// User run time (in seconds).
|
|
|
|
|
unsigned long
|
|
|
|
|
cputime()
|
|
|
|
|
{
|
|
|
|
|
return static_cast<unsigned long>(userRunTime() + .5);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Peak memory usage in bytes.
|
|
|
|
|
unsigned long
|
|
|
|
|
memory_usage()
|
|
|
|
|
{
|
|
|
|
|
return memoryUsage();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
processor_count()
|
|
|
|
|
{
|
|
|
|
|
return processorCount();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
thread_count()
|
|
|
|
|
{
|
|
|
|
|
return Sta::sta()->threadCount();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
set_thread_count(int count)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->setThreadCount(count);
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-22 04:14:31 +02:00
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2020-12-25 23:00:11 +01:00
|
|
|
void
|
|
|
|
|
report_error(int id,
|
|
|
|
|
const char *msg)
|
|
|
|
|
{
|
2020-12-26 01:55:46 +01:00
|
|
|
Report *report = Sta::sta()->report();
|
|
|
|
|
report->error(id, "%s", msg);
|
2020-12-25 23:00:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
report_file_error(int id,
|
|
|
|
|
const char *filename,
|
|
|
|
|
int line,
|
|
|
|
|
const char *msg)
|
|
|
|
|
{
|
2020-12-26 01:55:46 +01:00
|
|
|
Report *report = Sta::sta()->report();
|
|
|
|
|
report->error(id, filename, line, "%s", msg);
|
2020-12-25 23:00:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
report_warn(int id,
|
|
|
|
|
const char *msg)
|
|
|
|
|
{
|
2020-12-26 01:55:46 +01:00
|
|
|
Report *report = Sta::sta()->report();
|
|
|
|
|
report->warn(id, "%s", msg);
|
2020-12-25 23:00:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
report_file_warn(int id,
|
|
|
|
|
const char *filename,
|
|
|
|
|
int line,
|
|
|
|
|
const char *msg)
|
|
|
|
|
{
|
2020-12-26 01:55:46 +01:00
|
|
|
Report *report = Sta::sta()->report();
|
|
|
|
|
report->fileWarn(id, filename, line, "%s", msg);
|
2020-12-25 23:00:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2020-12-26 01:55:46 +01:00
|
|
|
report_line(const char *msg)
|
2020-12-25 23:00:11 +01:00
|
|
|
{
|
2022-06-25 19:08:33 +02:00
|
|
|
Sta *sta = Sta::sta();
|
|
|
|
|
if (sta)
|
|
|
|
|
sta->report()->reportLineString(msg);
|
|
|
|
|
else
|
|
|
|
|
// After sta::delete_all_memory souce -echo prints the cmd file line
|
|
|
|
|
printf("%s\n", msg);
|
2020-12-25 23:00:11 +01:00
|
|
|
}
|
|
|
|
|
|
2020-03-09 00:58:10 +01:00
|
|
|
void
|
|
|
|
|
fflush()
|
|
|
|
|
{
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
fflush(stderr);
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-28 17:54:21 +02:00
|
|
|
void
|
|
|
|
|
redirect_file_begin(const char *filename)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->report()->redirectFileBegin(filename);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
redirect_file_append_begin(const char *filename)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->report()->redirectFileAppendBegin(filename);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
redirect_file_end()
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->report()->redirectFileEnd();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
redirect_string_begin()
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->report()->redirectStringBegin();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
redirect_string_end()
|
|
|
|
|
{
|
|
|
|
|
return Sta::sta()->report()->redirectStringEnd();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2020-12-25 01:31:52 +01:00
|
|
|
log_begin_cmd(const char *filename)
|
2018-09-28 17:54:21 +02:00
|
|
|
{
|
|
|
|
|
Sta::sta()->report()->logBegin(filename);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
log_end()
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->report()->logEnd();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
set_debug(const char *what,
|
|
|
|
|
int level)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->setDebugLevel(what, level);
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-22 20:42:34 +02:00
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2018-09-28 17:54:21 +02:00
|
|
|
bool
|
|
|
|
|
is_object(const char *obj)
|
|
|
|
|
{
|
|
|
|
|
// _hexaddress_p_type
|
|
|
|
|
const char *s = obj;
|
|
|
|
|
char ch = *s++;
|
|
|
|
|
if (ch != '_')
|
|
|
|
|
return false;
|
|
|
|
|
while (*s && isxdigit(*s))
|
|
|
|
|
s++;
|
|
|
|
|
if ((s - obj - 1) == sizeof(void*) * 2
|
|
|
|
|
&& *s && *s++ == '_'
|
|
|
|
|
&& *s && *s++ == 'p'
|
|
|
|
|
&& *s && *s++ == '_') {
|
|
|
|
|
while (*s && *s != ' ')
|
|
|
|
|
s++;
|
|
|
|
|
return *s == '\0';
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Assumes is_object is true.
|
|
|
|
|
const char *
|
|
|
|
|
object_type(const char *obj)
|
|
|
|
|
{
|
|
|
|
|
return &obj[1 + sizeof(void*) * 2 + 3];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
is_object_list(const char *list,
|
|
|
|
|
const char *type)
|
|
|
|
|
{
|
|
|
|
|
const char *s = list;
|
|
|
|
|
while (s) {
|
|
|
|
|
bool type_match;
|
|
|
|
|
const char *next;
|
|
|
|
|
objectListNext(s, type, type_match, next);
|
|
|
|
|
if (type_match)
|
|
|
|
|
s = next;
|
|
|
|
|
else
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-21 07:24:32 +02:00
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2024-07-22 20:42:34 +02:00
|
|
|
// Initialize sta after delete_all_memory.
|
|
|
|
|
void
|
|
|
|
|
init_sta()
|
|
|
|
|
{
|
|
|
|
|
initSta();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
clear_sta()
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
make_sta(Tcl_Interp *interp)
|
|
|
|
|
{
|
|
|
|
|
Sta *sta = new Sta;
|
|
|
|
|
Sta::setSta(sta);
|
|
|
|
|
sta->makeComponents();
|
|
|
|
|
sta->setTclInterp(interp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Tcl_Interp *
|
|
|
|
|
tcl_interp()
|
|
|
|
|
{
|
|
|
|
|
return Sta::sta()->tclInterp();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
clear_network()
|
|
|
|
|
{
|
|
|
|
|
Sta *sta = Sta::sta();
|
|
|
|
|
sta->network()->clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
delete_all_memory()
|
|
|
|
|
{
|
|
|
|
|
deleteAllMemory();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2018-09-28 17:54:21 +02:00
|
|
|
// format_unit functions print with fixed digits and suffix.
|
|
|
|
|
// Pass value arg as string to support NaNs.
|
|
|
|
|
const char *
|
2019-04-19 03:01:10 +02:00
|
|
|
format_time(const char *value,
|
2018-09-28 17:54:21 +02:00
|
|
|
int digits)
|
|
|
|
|
{
|
2019-04-19 03:01:10 +02:00
|
|
|
float value1 = strtof(value, nullptr);
|
|
|
|
|
return Sta::sta()->units()->timeUnit()->asString(value1, digits);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *
|
2019-04-19 03:01:10 +02:00
|
|
|
format_capacitance(const char *value,
|
2018-09-28 17:54:21 +02:00
|
|
|
int digits)
|
|
|
|
|
{
|
2019-04-19 03:01:10 +02:00
|
|
|
float value1 = strtof(value, nullptr);
|
|
|
|
|
return Sta::sta()->units()->capacitanceUnit()->asString(value1, digits);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *
|
2019-04-19 03:01:10 +02:00
|
|
|
format_resistance(const char *value,
|
2018-09-28 17:54:21 +02:00
|
|
|
int digits)
|
|
|
|
|
{
|
2019-04-19 03:01:10 +02:00
|
|
|
float value1 = strtof(value, nullptr);
|
|
|
|
|
return Sta::sta()->units()->resistanceUnit()->asString(value1, digits);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *
|
2019-04-19 03:01:10 +02:00
|
|
|
format_voltage(const char *value,
|
2018-09-28 17:54:21 +02:00
|
|
|
int digits)
|
|
|
|
|
{
|
2019-04-19 03:01:10 +02:00
|
|
|
float value1 = strtof(value, nullptr);
|
|
|
|
|
return Sta::sta()->units()->voltageUnit()->asString(value1, digits);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
2023-03-23 15:01:04 +01:00
|
|
|
const char *
|
|
|
|
|
format_current(const char *value,
|
|
|
|
|
int digits)
|
|
|
|
|
{
|
|
|
|
|
float value1 = strtof(value, nullptr);
|
|
|
|
|
return Sta::sta()->units()->currentUnit()->asString(value1, digits);
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-28 17:54:21 +02:00
|
|
|
const char *
|
2019-04-19 03:01:10 +02:00
|
|
|
format_power(const char *value,
|
2018-09-28 17:54:21 +02:00
|
|
|
int digits)
|
|
|
|
|
{
|
2019-04-19 03:01:10 +02:00
|
|
|
float value1 = strtof(value, nullptr);
|
|
|
|
|
return Sta::sta()->units()->powerUnit()->asString(value1, digits);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-17 02:34:48 +02:00
|
|
|
const char *
|
|
|
|
|
format_distance(const char *value,
|
|
|
|
|
int digits)
|
|
|
|
|
{
|
|
|
|
|
float value1 = strtof(value, nullptr);
|
|
|
|
|
Unit *dist_unit = Sta::sta()->units()->distanceUnit();
|
|
|
|
|
return dist_unit->asString(value1, digits);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
format_area(const char *value,
|
|
|
|
|
int digits)
|
|
|
|
|
{
|
|
|
|
|
float value1 = strtof(value, nullptr);
|
|
|
|
|
Unit *dist_unit = Sta::sta()->units()->distanceUnit();
|
|
|
|
|
return dist_unit->asString(value1 / dist_unit->scale(), digits);
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-08 20:50:41 +02:00
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2022-04-04 05:40:49 +02:00
|
|
|
// <unit>_sta_ui conversion from sta units to user interface units.
|
|
|
|
|
// <unit>_ui_sta conversion from user interface units to sta units.
|
|
|
|
|
|
2018-09-28 17:54:21 +02:00
|
|
|
double
|
|
|
|
|
time_ui_sta(double value)
|
|
|
|
|
{
|
2022-04-04 05:40:49 +02:00
|
|
|
return Sta::sta()->units()->timeUnit()->userToSta(value);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double
|
|
|
|
|
time_sta_ui(double value)
|
|
|
|
|
{
|
2022-04-04 05:40:49 +02:00
|
|
|
return Sta::sta()->units()->timeUnit()->staToUser(value);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double
|
|
|
|
|
capacitance_ui_sta(double value)
|
|
|
|
|
{
|
2022-04-04 05:40:49 +02:00
|
|
|
return Sta::sta()->units()->capacitanceUnit()->userToSta(value);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double
|
|
|
|
|
capacitance_sta_ui(double value)
|
|
|
|
|
{
|
2022-04-04 05:40:49 +02:00
|
|
|
return Sta::sta()->units()->capacitanceUnit()->staToUser(value);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double
|
|
|
|
|
resistance_ui_sta(double value)
|
|
|
|
|
{
|
2022-04-04 05:40:49 +02:00
|
|
|
return Sta::sta()->units()->resistanceUnit()->userToSta(value);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double
|
|
|
|
|
resistance_sta_ui(double value)
|
|
|
|
|
{
|
2022-04-04 05:40:49 +02:00
|
|
|
return Sta::sta()->units()->resistanceUnit()->staToUser(value);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double
|
|
|
|
|
voltage_ui_sta(double value)
|
|
|
|
|
{
|
2022-04-04 05:40:49 +02:00
|
|
|
return Sta::sta()->units()->voltageUnit()->userToSta(value);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double
|
|
|
|
|
voltage_sta_ui(double value)
|
|
|
|
|
{
|
2022-04-04 05:40:49 +02:00
|
|
|
return Sta::sta()->units()->voltageUnit()->staToUser(value);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double
|
|
|
|
|
current_ui_sta(double value)
|
|
|
|
|
{
|
2022-04-04 05:40:49 +02:00
|
|
|
return Sta::sta()->units()->currentUnit()->userToSta(value);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double
|
|
|
|
|
current_sta_ui(double value)
|
|
|
|
|
{
|
2022-04-04 05:40:49 +02:00
|
|
|
return Sta::sta()->units()->currentUnit()->staToUser(value);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double
|
|
|
|
|
power_ui_sta(double value)
|
|
|
|
|
{
|
2022-04-04 05:40:49 +02:00
|
|
|
return Sta::sta()->units()->powerUnit()->userToSta(value);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double
|
|
|
|
|
power_sta_ui(double value)
|
|
|
|
|
{
|
2022-04-04 05:40:49 +02:00
|
|
|
return Sta::sta()->units()->powerUnit()->staToUser(value);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-08 20:50:41 +02:00
|
|
|
double
|
|
|
|
|
distance_ui_sta(double value)
|
|
|
|
|
{
|
2022-04-04 05:40:49 +02:00
|
|
|
return Sta::sta()->units()->distanceUnit()->userToSta(value);
|
2019-07-08 20:50:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double
|
|
|
|
|
distance_sta_ui(double value)
|
|
|
|
|
{
|
2022-04-04 05:40:49 +02:00
|
|
|
return Sta::sta()->units()->distanceUnit()->staToUser(value);
|
2019-07-08 20:50:41 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-17 02:34:48 +02:00
|
|
|
double
|
|
|
|
|
area_ui_sta(double value)
|
|
|
|
|
{
|
|
|
|
|
double scale = Sta::sta()->units()->distanceUnit()->scale();
|
|
|
|
|
return value * scale * scale;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double
|
|
|
|
|
area_sta_ui(double value)
|
|
|
|
|
{
|
|
|
|
|
double scale = Sta::sta()->units()->distanceUnit()->scale();
|
|
|
|
|
return value / (scale * scale);
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-08 20:50:41 +02:00
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
set_cmd_unit_scale(const char *unit_name,
|
|
|
|
|
float scale)
|
|
|
|
|
{
|
|
|
|
|
Unit *unit = Sta::sta()->units()->find(unit_name);
|
|
|
|
|
if (unit)
|
|
|
|
|
unit->setScale(scale);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
set_cmd_unit_digits(const char *unit_name,
|
|
|
|
|
int digits)
|
|
|
|
|
{
|
|
|
|
|
Unit *unit = Sta::sta()->units()->find(unit_name);
|
|
|
|
|
if (unit)
|
|
|
|
|
unit->setDigits(digits);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
set_cmd_unit_suffix(const char *unit_name,
|
|
|
|
|
const char *suffix)
|
|
|
|
|
{
|
|
|
|
|
Unit *unit = Sta::sta()->units()->find(unit_name);
|
|
|
|
|
if (unit) {
|
|
|
|
|
unit->setSuffix(suffix);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-24 02:11:48 +02:00
|
|
|
const char *
|
2023-04-17 17:52:20 +02:00
|
|
|
unit_scale_abbreviation (const char *unit_name)
|
2020-06-24 02:11:48 +02:00
|
|
|
{
|
|
|
|
|
Unit *unit = Sta::sta()->units()->find(unit_name);
|
|
|
|
|
if (unit)
|
2023-04-17 17:52:20 +02:00
|
|
|
return unit->scaleAbbreviation();
|
2020-06-24 02:11:48 +02:00
|
|
|
else
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
unit_suffix(const char *unit_name)
|
|
|
|
|
{
|
|
|
|
|
Unit *unit = Sta::sta()->units()->find(unit_name);
|
|
|
|
|
if (unit)
|
|
|
|
|
return unit->suffix();
|
|
|
|
|
else
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-17 17:52:20 +02:00
|
|
|
const char *
|
|
|
|
|
unit_scaled_suffix(const char *unit_name)
|
|
|
|
|
{
|
|
|
|
|
Unit *unit = Sta::sta()->units()->find(unit_name);
|
|
|
|
|
if (unit)
|
|
|
|
|
return unit->scaledSuffix();
|
|
|
|
|
else
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-22 21:29:17 +02:00
|
|
|
float
|
|
|
|
|
unit_scale(const char *unit_name)
|
|
|
|
|
{
|
|
|
|
|
Unit *unit = Sta::sta()->units()->find(unit_name);
|
|
|
|
|
if (unit)
|
|
|
|
|
return unit->scale();
|
|
|
|
|
else
|
|
|
|
|
return 1.0F;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-08 20:50:41 +02:00
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2024-07-22 19:54:57 +02:00
|
|
|
const char *
|
|
|
|
|
rise_short_name()
|
|
|
|
|
{
|
|
|
|
|
return RiseFall::rise()->shortName();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
fall_short_name()
|
|
|
|
|
{
|
|
|
|
|
return RiseFall::fall()->shortName();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
PropertyValue
|
|
|
|
|
pin_property(const Pin *pin,
|
|
|
|
|
const char *property)
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
|
|
|
|
return getProperty(pin, property, Sta::sta());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PropertyValue
|
|
|
|
|
instance_property(const Instance *inst,
|
|
|
|
|
const char *property)
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
|
|
|
|
return getProperty(inst, property, Sta::sta());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PropertyValue
|
|
|
|
|
net_property(const Net *net,
|
|
|
|
|
const char *property)
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
|
|
|
|
return getProperty(net, property, Sta::sta());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PropertyValue
|
|
|
|
|
port_property(const Port *port,
|
|
|
|
|
const char *property)
|
|
|
|
|
{
|
|
|
|
|
return getProperty(port, property, Sta::sta());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PropertyValue
|
|
|
|
|
liberty_cell_property(const LibertyCell *cell,
|
|
|
|
|
const char *property)
|
|
|
|
|
{
|
|
|
|
|
return getProperty(cell, property, Sta::sta());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PropertyValue
|
|
|
|
|
cell_property(const Cell *cell,
|
|
|
|
|
const char *property)
|
|
|
|
|
{
|
|
|
|
|
return getProperty(cell, property, Sta::sta());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PropertyValue
|
|
|
|
|
liberty_port_property(const LibertyPort *port,
|
|
|
|
|
const char *property)
|
|
|
|
|
{
|
|
|
|
|
return getProperty(port, property, Sta::sta());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PropertyValue
|
|
|
|
|
library_property(const Library *lib,
|
|
|
|
|
const char *property)
|
|
|
|
|
{
|
|
|
|
|
return getProperty(lib, property, Sta::sta());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PropertyValue
|
|
|
|
|
liberty_library_property(const LibertyLibrary *lib,
|
|
|
|
|
const char *property)
|
|
|
|
|
{
|
|
|
|
|
return getProperty(lib, property, Sta::sta());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PropertyValue
|
|
|
|
|
edge_property(Edge *edge,
|
|
|
|
|
const char *property)
|
|
|
|
|
{
|
|
|
|
|
cmdGraph();
|
|
|
|
|
return getProperty(edge, property, Sta::sta());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PropertyValue
|
|
|
|
|
clock_property(Clock *clk,
|
|
|
|
|
const char *property)
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
|
|
|
|
return getProperty(clk, property, Sta::sta());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PropertyValue
|
|
|
|
|
path_end_property(PathEnd *end,
|
|
|
|
|
const char *property)
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
|
|
|
|
return getProperty(end, property, Sta::sta());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PropertyValue
|
|
|
|
|
path_ref_property(PathRef *path,
|
|
|
|
|
const char *property)
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
|
|
|
|
return getProperty(path, property, Sta::sta());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PropertyValue
|
|
|
|
|
timing_arc_set_property(TimingArcSet *arc_set,
|
|
|
|
|
const char *property)
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
|
|
|
|
return getProperty(arc_set, property, Sta::sta());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
2024-07-22 22:16:49 +02:00
|
|
|
//
|
|
|
|
|
// Variables
|
|
|
|
|
//
|
2024-07-22 19:54:57 +02:00
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2018-09-28 17:54:21 +02:00
|
|
|
bool
|
|
|
|
|
crpr_enabled()
|
|
|
|
|
{
|
|
|
|
|
return Sta::sta()->crprEnabled();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
set_crpr_enabled(bool enabled)
|
|
|
|
|
{
|
|
|
|
|
return Sta::sta()->setCrprEnabled(enabled);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
crpr_mode()
|
|
|
|
|
{
|
|
|
|
|
switch (Sta::sta()->crprMode()) {
|
2019-03-13 01:25:53 +01:00
|
|
|
case CrprMode::same_transition:
|
2018-09-28 17:54:21 +02:00
|
|
|
return "same_transition";
|
2019-03-13 01:25:53 +01:00
|
|
|
case CrprMode::same_pin:
|
2018-09-28 17:54:21 +02:00
|
|
|
return "same_pin";
|
|
|
|
|
default:
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
set_crpr_mode(const char *mode)
|
|
|
|
|
{
|
2021-12-13 01:10:24 +01:00
|
|
|
Sta *sta = Sta::sta();
|
2018-09-28 17:54:21 +02:00
|
|
|
if (stringEq(mode, "same_pin"))
|
2019-03-13 01:25:53 +01:00
|
|
|
Sta::sta()->setCrprMode(CrprMode::same_pin);
|
2018-09-28 17:54:21 +02:00
|
|
|
else if (stringEq(mode, "same_transition"))
|
2019-03-13 01:25:53 +01:00
|
|
|
Sta::sta()->setCrprMode(CrprMode::same_transition);
|
2018-09-28 17:54:21 +02:00
|
|
|
else
|
2024-01-08 03:23:53 +01:00
|
|
|
sta->report()->critical(1573, "unknown common clk pessimism mode.");
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
2019-01-27 08:03:01 +01:00
|
|
|
bool
|
|
|
|
|
pocv_enabled()
|
|
|
|
|
{
|
|
|
|
|
return Sta::sta()->pocvEnabled();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
set_pocv_enabled(bool enabled)
|
|
|
|
|
{
|
2019-01-28 18:31:56 +01:00
|
|
|
#if !SSTA
|
|
|
|
|
if (enabled)
|
2024-01-08 03:23:53 +01:00
|
|
|
Sta::sta()->report()->error(1574, "POCV support requires compilation with SSTA=1.");
|
2019-01-28 18:31:56 +01:00
|
|
|
#endif
|
2019-01-27 08:03:01 +01:00
|
|
|
return Sta::sta()->setPocvEnabled(enabled);
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-13 01:25:53 +01:00
|
|
|
float
|
|
|
|
|
pocv_sigma_factor()
|
|
|
|
|
{
|
|
|
|
|
return Sta::sta()->sigmaFactor();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
set_pocv_sigma_factor(float factor)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->setSigmaFactor(factor);
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-28 17:54:21 +02:00
|
|
|
bool
|
|
|
|
|
propagate_gated_clock_enable()
|
|
|
|
|
{
|
|
|
|
|
return Sta::sta()->propagateGatedClockEnable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
set_propagate_gated_clock_enable(bool enable)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->setPropagateGatedClockEnable(enable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
preset_clr_arcs_enabled()
|
|
|
|
|
{
|
|
|
|
|
return Sta::sta()->presetClrArcsEnabled();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
set_preset_clr_arcs_enabled(bool enable)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->setPresetClrArcsEnabled(enable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
cond_default_arcs_enabled()
|
|
|
|
|
{
|
|
|
|
|
return Sta::sta()->condDefaultArcsEnabled();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
set_cond_default_arcs_enabled(bool enabled)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->setCondDefaultArcsEnabled(enabled);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
bidirect_inst_paths_enabled()
|
|
|
|
|
{
|
|
|
|
|
return Sta::sta()->bidirectInstPathsEnabled();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
set_bidirect_inst_paths_enabled(bool enabled)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->setBidirectInstPathsEnabled(enabled);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
bidirect_net_paths_enabled()
|
|
|
|
|
{
|
|
|
|
|
return Sta::sta()->bidirectNetPathsEnabled();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
set_bidirect_net_paths_enabled(bool enabled)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->setBidirectNetPathsEnabled(enabled);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
recovery_removal_checks_enabled()
|
|
|
|
|
{
|
|
|
|
|
return Sta::sta()->recoveryRemovalChecksEnabled();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
set_recovery_removal_checks_enabled(bool enabled)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->setRecoveryRemovalChecksEnabled(enabled);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
gated_clk_checks_enabled()
|
|
|
|
|
{
|
|
|
|
|
return Sta::sta()->gatedClkChecksEnabled();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
set_gated_clk_checks_enabled(bool enabled)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->setGatedClkChecksEnabled(enabled);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
dynamic_loop_breaking()
|
|
|
|
|
{
|
|
|
|
|
return Sta::sta()->dynamicLoopBreaking();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
set_dynamic_loop_breaking(bool enable)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->setDynamicLoopBreaking(enable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
use_default_arrival_clock()
|
|
|
|
|
{
|
|
|
|
|
return Sta::sta()->useDefaultArrivalClock();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
set_use_default_arrival_clock(bool enable)
|
|
|
|
|
{
|
|
|
|
|
return Sta::sta()->setUseDefaultArrivalClock(enable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
propagate_all_clocks()
|
|
|
|
|
{
|
|
|
|
|
return Sta::sta()->propagateAllClocks();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
set_propagate_all_clocks(bool prop)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->setPropagateAllClocks(prop);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
void
|
2024-05-21 17:45:55 +02:00
|
|
|
report_clk_skew(ConstClockSeq clks,
|
2018-11-09 19:04:16 +01:00
|
|
|
const Corner *corner,
|
2018-09-28 17:54:21 +02:00
|
|
|
const SetupHold *setup_hold,
|
2024-05-10 03:06:44 +02:00
|
|
|
bool include_internal_latency,
|
2018-09-28 17:54:21 +02:00
|
|
|
int digits)
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
2024-05-10 03:06:44 +02:00
|
|
|
Sta::sta()->reportClkSkew(clks, corner, setup_hold,
|
|
|
|
|
include_internal_latency, digits);
|
2024-02-27 18:00:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2024-05-21 17:45:55 +02:00
|
|
|
report_clk_latency(ConstClockSeq clks,
|
2024-02-27 18:00:48 +01:00
|
|
|
const Corner *corner,
|
2024-05-12 03:12:55 +02:00
|
|
|
bool include_internal_latency,
|
2024-02-27 18:00:48 +01:00
|
|
|
int digits)
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
2024-05-12 03:12:55 +02:00
|
|
|
Sta::sta()->reportClkLatency(clks, corner, include_internal_latency, digits);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
2021-05-31 02:22:55 +02:00
|
|
|
float
|
2024-05-10 03:06:44 +02:00
|
|
|
worst_clk_skew_cmd(const SetupHold *setup_hold,
|
|
|
|
|
bool include_internal_latency)
|
2021-05-31 02:22:55 +02:00
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
2024-05-10 03:06:44 +02:00
|
|
|
return Sta::sta()->findWorstClkSkew(setup_hold, include_internal_latency);
|
2021-05-31 02:22:55 +02:00
|
|
|
}
|
|
|
|
|
|
2024-05-10 03:06:44 +02:00
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2018-09-28 17:54:21 +02:00
|
|
|
MinPulseWidthCheckSeq &
|
2018-11-09 19:04:16 +01:00
|
|
|
min_pulse_width_violations(const Corner *corner)
|
2018-09-28 17:54:21 +02:00
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
2018-11-09 19:04:16 +01:00
|
|
|
return Sta::sta()->minPulseWidthViolations(corner);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MinPulseWidthCheckSeq &
|
2018-11-09 19:04:16 +01:00
|
|
|
min_pulse_width_check_pins(PinSeq *pins,
|
|
|
|
|
const Corner *corner)
|
2018-09-28 17:54:21 +02:00
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
2018-11-09 19:04:16 +01:00
|
|
|
Sta *sta = Sta::sta();
|
|
|
|
|
MinPulseWidthCheckSeq &checks = sta->minPulseWidthChecks(pins, corner);
|
2018-09-28 17:54:21 +02:00
|
|
|
delete pins;
|
|
|
|
|
return checks;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MinPulseWidthCheckSeq &
|
2018-11-09 19:04:16 +01:00
|
|
|
min_pulse_width_checks(const Corner *corner)
|
2018-09-28 17:54:21 +02:00
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
2018-11-09 19:04:16 +01:00
|
|
|
return Sta::sta()->minPulseWidthChecks(corner);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MinPulseWidthCheck *
|
2018-11-09 19:04:16 +01:00
|
|
|
min_pulse_width_check_slack(const Corner *corner)
|
2018-09-28 17:54:21 +02:00
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
2018-11-09 19:04:16 +01:00
|
|
|
return Sta::sta()->minPulseWidthSlack(corner);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
report_mpw_checks(MinPulseWidthCheckSeq *checks,
|
|
|
|
|
bool verbose)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->reportMpwChecks(checks, verbose);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
report_mpw_check(MinPulseWidthCheck *check,
|
|
|
|
|
bool verbose)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->reportMpwCheck(check, verbose);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
MinPeriodCheckSeq &
|
2019-03-13 01:25:53 +01:00
|
|
|
min_period_violations()
|
2018-09-28 17:54:21 +02:00
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
2019-03-13 01:25:53 +01:00
|
|
|
return Sta::sta()->minPeriodViolations();
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MinPeriodCheck *
|
2019-03-13 01:25:53 +01:00
|
|
|
min_period_check_slack()
|
2018-09-28 17:54:21 +02:00
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
2019-03-13 01:25:53 +01:00
|
|
|
return Sta::sta()->minPeriodSlack();
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
report_min_period_checks(MinPeriodCheckSeq *checks,
|
|
|
|
|
bool verbose)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->reportChecks(checks, verbose);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
report_min_period_check(MinPeriodCheck *check,
|
|
|
|
|
bool verbose)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->reportCheck(check, verbose);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
MaxSkewCheckSeq &
|
|
|
|
|
max_skew_violations()
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
|
|
|
|
return Sta::sta()->maxSkewViolations();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MaxSkewCheck *
|
|
|
|
|
max_skew_check_slack()
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
|
|
|
|
return Sta::sta()->maxSkewSlack();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
report_max_skew_checks(MaxSkewCheckSeq *checks,
|
|
|
|
|
bool verbose)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->reportChecks(checks, verbose);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
report_max_skew_check(MaxSkewCheck *check,
|
|
|
|
|
bool verbose)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->reportCheck(check, verbose);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2021-10-05 02:49:19 +02:00
|
|
|
Slack
|
|
|
|
|
find_clk_min_period(const Clock *clk,
|
|
|
|
|
bool ignore_port_paths)
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
|
|
|
|
Sta *sta = Sta::sta();
|
|
|
|
|
return sta->findClkMinPeriod(clk, ignore_port_paths);
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-02 20:08:48 +02:00
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2023-01-19 19:23:45 +01:00
|
|
|
PinSeq
|
2021-03-06 14:47:44 +01:00
|
|
|
check_slew_limits(Net *net,
|
|
|
|
|
bool violators,
|
|
|
|
|
const Corner *corner,
|
|
|
|
|
const MinMax *min_max)
|
2018-09-28 17:54:21 +02:00
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
2021-03-06 14:47:44 +01:00
|
|
|
return Sta::sta()->checkSlewLimits(net, violators, corner, min_max);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
2021-05-29 01:21:43 +02:00
|
|
|
size_t
|
|
|
|
|
max_slew_violation_count()
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
2023-01-19 19:23:45 +01:00
|
|
|
return Sta::sta()->checkSlewLimits(nullptr, true, nullptr, MinMax::max()).size();
|
2021-05-29 01:21:43 +02:00
|
|
|
}
|
|
|
|
|
|
2022-04-03 22:31:07 +02:00
|
|
|
float
|
|
|
|
|
max_slew_check_slack()
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
2022-04-04 05:40:49 +02:00
|
|
|
Sta *sta = Sta::sta();
|
2023-01-19 19:23:45 +01:00
|
|
|
const Pin *pin;
|
2022-04-08 01:18:00 +02:00
|
|
|
Slew slew;
|
|
|
|
|
float slack;
|
|
|
|
|
float limit;
|
|
|
|
|
sta->maxSlewCheck(pin, slew, slack, limit);
|
|
|
|
|
return sta->units()->timeUnit()->staToUser(slack);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float
|
|
|
|
|
max_slew_check_limit()
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
|
|
|
|
Sta *sta = Sta::sta();
|
2023-01-19 19:23:45 +01:00
|
|
|
const Pin *pin;
|
2022-04-08 01:18:00 +02:00
|
|
|
Slew slew;
|
|
|
|
|
float slack;
|
|
|
|
|
float limit;
|
|
|
|
|
sta->maxSlewCheck(pin, slew, slack, limit);
|
|
|
|
|
return sta->units()->timeUnit()->staToUser(limit);
|
2022-04-03 22:31:07 +02:00
|
|
|
}
|
|
|
|
|
|
2018-09-28 17:54:21 +02:00
|
|
|
void
|
|
|
|
|
report_slew_limit_short_header()
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->reportSlewLimitShortHeader();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
report_slew_limit_short(Pin *pin,
|
2018-11-09 19:04:16 +01:00
|
|
|
const Corner *corner,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMax *min_max)
|
|
|
|
|
{
|
2018-11-09 19:04:16 +01:00
|
|
|
Sta::sta()->reportSlewLimitShort(pin, corner, min_max);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
report_slew_limit_verbose(Pin *pin,
|
2018-11-09 19:04:16 +01:00
|
|
|
const Corner *corner,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMax *min_max)
|
|
|
|
|
{
|
2018-11-09 19:04:16 +01:00
|
|
|
Sta::sta()->reportSlewLimitVerbose(pin, corner, min_max);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
2018-11-26 18:15:52 +01:00
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2023-01-19 19:23:45 +01:00
|
|
|
PinSeq
|
2021-03-08 04:43:51 +01:00
|
|
|
check_fanout_limits(Net *net,
|
|
|
|
|
bool violators,
|
|
|
|
|
const MinMax *min_max)
|
2020-06-02 20:08:48 +02:00
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
2021-03-08 04:43:51 +01:00
|
|
|
return Sta::sta()->checkFanoutLimits(net, violators, min_max);
|
2020-06-02 20:08:48 +02:00
|
|
|
}
|
|
|
|
|
|
2021-05-29 01:21:43 +02:00
|
|
|
size_t
|
|
|
|
|
max_fanout_violation_count()
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
2023-01-19 19:23:45 +01:00
|
|
|
return Sta::sta()->checkFanoutLimits(nullptr, true, MinMax::max()).size();
|
2021-05-29 01:21:43 +02:00
|
|
|
}
|
|
|
|
|
|
2022-04-03 22:31:07 +02:00
|
|
|
float
|
|
|
|
|
max_fanout_check_slack()
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
2022-04-08 01:18:00 +02:00
|
|
|
Sta *sta = Sta::sta();
|
2023-01-19 19:23:45 +01:00
|
|
|
const Pin *pin;
|
2022-04-08 01:18:00 +02:00
|
|
|
float fanout;
|
|
|
|
|
float slack;
|
|
|
|
|
float limit;
|
|
|
|
|
sta->maxFanoutCheck(pin, fanout, slack, limit);
|
|
|
|
|
return slack;;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float
|
|
|
|
|
max_fanout_check_limit()
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
|
|
|
|
Sta *sta = Sta::sta();
|
2023-01-19 19:23:45 +01:00
|
|
|
const Pin *pin;
|
2022-04-08 01:18:00 +02:00
|
|
|
float fanout;
|
|
|
|
|
float slack;
|
|
|
|
|
float limit;
|
|
|
|
|
sta->maxFanoutCheck(pin, fanout, slack, limit);
|
|
|
|
|
return limit;;
|
2022-04-03 22:31:07 +02:00
|
|
|
}
|
|
|
|
|
|
2020-06-02 20:08:48 +02:00
|
|
|
void
|
|
|
|
|
report_fanout_limit_short_header()
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->reportFanoutLimitShortHeader();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
report_fanout_limit_short(Pin *pin,
|
|
|
|
|
const MinMax *min_max)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->reportFanoutLimitShort(pin, min_max);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
report_fanout_limit_verbose(Pin *pin,
|
|
|
|
|
const MinMax *min_max)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->reportFanoutLimitVerbose(pin, min_max);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2023-01-19 19:23:45 +01:00
|
|
|
PinSeq
|
2021-03-07 18:21:53 +01:00
|
|
|
check_capacitance_limits(Net *net,
|
|
|
|
|
bool violators,
|
|
|
|
|
const Corner *corner,
|
|
|
|
|
const MinMax *min_max)
|
2020-06-02 20:08:48 +02:00
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
2021-03-07 18:21:53 +01:00
|
|
|
return Sta::sta()->checkCapacitanceLimits(net, violators, corner, min_max);
|
2020-06-02 20:08:48 +02:00
|
|
|
}
|
|
|
|
|
|
2021-05-29 01:21:43 +02:00
|
|
|
size_t
|
|
|
|
|
max_capacitance_violation_count()
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
2023-01-19 19:23:45 +01:00
|
|
|
return Sta::sta()->checkCapacitanceLimits(nullptr, true,nullptr,MinMax::max()).size();
|
2021-05-29 01:21:43 +02:00
|
|
|
}
|
|
|
|
|
|
2022-04-03 22:31:07 +02:00
|
|
|
float
|
|
|
|
|
max_capacitance_check_slack()
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
2022-04-04 05:40:49 +02:00
|
|
|
Sta *sta = Sta::sta();
|
2023-01-19 19:23:45 +01:00
|
|
|
const Pin *pin;
|
2022-04-08 01:18:00 +02:00
|
|
|
float capacitance;
|
|
|
|
|
float slack;
|
|
|
|
|
float limit;
|
|
|
|
|
sta->maxCapacitanceCheck(pin, capacitance, slack, limit);
|
|
|
|
|
return sta->units()->capacitanceUnit()->staToUser(slack);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float
|
|
|
|
|
max_capacitance_check_limit()
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
|
|
|
|
Sta *sta = Sta::sta();
|
2023-01-19 19:23:45 +01:00
|
|
|
const Pin *pin;
|
2022-04-08 01:18:00 +02:00
|
|
|
float capacitance;
|
|
|
|
|
float slack;
|
|
|
|
|
float limit;
|
|
|
|
|
sta->maxCapacitanceCheck(pin, capacitance, slack, limit);
|
|
|
|
|
return sta->units()->capacitanceUnit()->staToUser(limit);
|
2022-04-03 22:31:07 +02:00
|
|
|
}
|
|
|
|
|
|
2020-06-02 20:08:48 +02:00
|
|
|
void
|
|
|
|
|
report_capacitance_limit_short_header()
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->reportCapacitanceLimitShortHeader();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
report_capacitance_limit_short(Pin *pin,
|
|
|
|
|
const Corner *corner,
|
|
|
|
|
const MinMax *min_max)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->reportCapacitanceLimitShort(pin, corner, min_max);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
report_capacitance_limit_verbose(Pin *pin,
|
|
|
|
|
const Corner *corner,
|
|
|
|
|
const MinMax *min_max)
|
|
|
|
|
{
|
|
|
|
|
Sta::sta()->reportCapacitanceLimitVerbose(pin, corner, min_max);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2022-06-08 17:29:53 +02:00
|
|
|
void
|
2022-08-22 19:55:11 +02:00
|
|
|
write_timing_model_cmd(const char *lib_name,
|
|
|
|
|
const char *cell_name,
|
2022-06-08 17:29:53 +02:00
|
|
|
const char *filename,
|
|
|
|
|
const Corner *corner)
|
|
|
|
|
{
|
2022-08-22 19:55:11 +02:00
|
|
|
Sta::sta()->writeTimingModel(lib_name, cell_name, filename, corner);
|
2022-06-08 17:29:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2019-04-19 03:01:10 +02:00
|
|
|
bool
|
|
|
|
|
fuzzy_equal(float value1,
|
|
|
|
|
float value2)
|
2018-09-28 17:54:21 +02:00
|
|
|
{
|
2019-04-19 03:01:10 +02:00
|
|
|
return fuzzyEqual(value1, value2);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char
|
|
|
|
|
pin_sim_logic_value(const Pin *pin)
|
|
|
|
|
{
|
|
|
|
|
return logicValueString(Sta::sta()->simLogicValue(pin));
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-22 19:17:08 +01:00
|
|
|
InstanceSeq
|
|
|
|
|
slow_drivers(int count)
|
2018-09-28 17:54:21 +02:00
|
|
|
{
|
2024-01-22 19:17:08 +01:00
|
|
|
return Sta::sta()->slowDrivers(count);
|
2018-09-28 17:54:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
timing_role_is_check(TimingRole *role)
|
|
|
|
|
{
|
|
|
|
|
return role->isTimingCheck();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2023-01-19 19:23:45 +01:00
|
|
|
PinSet
|
2018-09-28 17:54:21 +02:00
|
|
|
find_fanin_pins(PinSeq *to,
|
|
|
|
|
bool flat,
|
|
|
|
|
bool startpoints_only,
|
|
|
|
|
int inst_levels,
|
|
|
|
|
int pin_levels,
|
|
|
|
|
bool thru_disabled,
|
|
|
|
|
bool thru_constants)
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
|
|
|
|
Sta *sta = Sta::sta();
|
2023-01-19 19:23:45 +01:00
|
|
|
PinSet fanin = sta->findFaninPins(to, flat, startpoints_only,
|
|
|
|
|
inst_levels, pin_levels,
|
|
|
|
|
thru_disabled, thru_constants);
|
2018-09-28 17:54:21 +02:00
|
|
|
delete to;
|
|
|
|
|
return fanin;
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-19 19:23:45 +01:00
|
|
|
InstanceSet
|
2018-09-28 17:54:21 +02:00
|
|
|
find_fanin_insts(PinSeq *to,
|
|
|
|
|
bool flat,
|
|
|
|
|
bool startpoints_only,
|
|
|
|
|
int inst_levels,
|
|
|
|
|
int pin_levels,
|
|
|
|
|
bool thru_disabled,
|
|
|
|
|
bool thru_constants)
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
|
|
|
|
Sta *sta = Sta::sta();
|
2023-01-19 19:23:45 +01:00
|
|
|
InstanceSet fanin = sta->findFaninInstances(to, flat, startpoints_only,
|
|
|
|
|
inst_levels, pin_levels,
|
|
|
|
|
thru_disabled, thru_constants);
|
2018-09-28 17:54:21 +02:00
|
|
|
delete to;
|
|
|
|
|
return fanin;
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-19 19:23:45 +01:00
|
|
|
PinSet
|
2018-09-28 17:54:21 +02:00
|
|
|
find_fanout_pins(PinSeq *from,
|
|
|
|
|
bool flat,
|
|
|
|
|
bool endpoints_only,
|
|
|
|
|
int inst_levels,
|
|
|
|
|
int pin_levels,
|
|
|
|
|
bool thru_disabled,
|
|
|
|
|
bool thru_constants)
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
|
|
|
|
Sta *sta = Sta::sta();
|
2023-01-19 19:23:45 +01:00
|
|
|
PinSet fanout = sta->findFanoutPins(from, flat, endpoints_only,
|
|
|
|
|
inst_levels, pin_levels,
|
|
|
|
|
thru_disabled, thru_constants);
|
2018-09-28 17:54:21 +02:00
|
|
|
delete from;
|
|
|
|
|
return fanout;
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-19 19:23:45 +01:00
|
|
|
InstanceSet
|
2018-09-28 17:54:21 +02:00
|
|
|
find_fanout_insts(PinSeq *from,
|
|
|
|
|
bool flat,
|
|
|
|
|
bool endpoints_only,
|
|
|
|
|
int inst_levels,
|
|
|
|
|
int pin_levels,
|
|
|
|
|
bool thru_disabled,
|
|
|
|
|
bool thru_constants)
|
|
|
|
|
{
|
|
|
|
|
cmdLinkedNetwork();
|
|
|
|
|
Sta *sta = Sta::sta();
|
2023-01-19 19:23:45 +01:00
|
|
|
InstanceSet fanout = sta->findFanoutInstances(from, flat, endpoints_only,
|
|
|
|
|
inst_levels, pin_levels,
|
|
|
|
|
thru_disabled, thru_constants);
|
2018-09-28 17:54:21 +02:00
|
|
|
delete from;
|
|
|
|
|
return fanout;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
%} // inline
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// Object Methods
|
|
|
|
|
//
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
// Local Variables:
|
|
|
|
|
// mode:c++
|
|
|
|
|
// End:
|