This commit is contained in:
James Cherry 2019-01-05 16:09:27 -08:00
parent de5c3a6400
commit 3d8d088b89
25 changed files with 232 additions and 192 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required (VERSION 3.9)
project(STA VERSION 2.0.3)
project(STA VERSION 2.0.4)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_CXX_STANDARD 11)
@ -422,40 +422,62 @@ set(STA_SWIG_FILES
)
################################################################
#
# Library dependencies
#
################################################################
# Pthreads
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads)
set(HAVE_PTHREADS ${CMAKE_USE_PTHREADS_INIT})
message(STATUS "Found pthreads: ${HAVE_PTHREADS}")
if (HAVE_PTHREADS)
message(STATUS "Found pthreads")
endif()
# Zlib
include(FindZLIB)
if(NOT "$ENV{CUDD}" STREQUAL "")
set(CUDD_INCLUDE $ENV{CUDD}/include)
find_library(CUDD_LIB NAMES cudd PATHS $ENV{CUDD}/lib)
if (CUDD_LIB)
set(CUDD_FOUND TRUE)
message(STATUS "CUDD library: ${CUDD_LIB}")
endif()
else()
################################################################
#
# Locate CUDD bdd packagte
# CUDD variable has precidence over environment variable.
if("${CUDD}" STREQUAL "")
set(CUDD $ENV{CUDD})
endif()
if("${CUDD}" STREQUAL "")
set(CUDD_INCLUDE "")
set(CUDD_LIB "")
set(CUDD_FOUND FALSE)
else()
set(CUDD_INCLUDE ${CUDD}/include)
find_library(CUDD_LIB NAMES cudd PATHS ${CUDD}/lib)
if (CUDD_LIB)
# CUDD_FOUND referenced by config.h.cmake
set(CUDD_FOUND TRUE)
message(STATUS "CUDD library: ${CUDD_LIB}")
endif()
endif()
if("${SSTA}" STREQUAL "")
set(SSTA 0)
endif()
message(STATUS "Enable SSTA: ${SSTA}")
# configure a header file to pass some of the CMake settins
configure_file(
"${STA_HOME}/config.h.cmake"
"${STA_HOME}/config.h"
)
configure_file(${STA_HOME}/config.h.cmake
${STA_HOME}/config.h
)
################################################################
#
# Locate TCL library.
#
# Note that the cmakd findTcl module is hopeless for OSX
# Note that the cmake findTcl module is hopeless for OSX
# because there doesn't appear to be a way to override
# searching OSX system directories before unix directories.
@ -494,7 +516,7 @@ if (NOT TCL_LIB)
PATHS ${TCL_LIB_PATHS}
)
endif()
endif (NOT TCL_LIB)
endif()
message(STATUS "TCL lib: ${TCL_LIB}")
get_filename_component(TCL_LIB_DIR "${TCL_LIB}" PATH)
@ -508,10 +530,14 @@ if (NOT TCL_HEADER)
PATH_SUFFIXES include include/tcl
NO_DEFAULT_PATH
)
endif (NOT TCL_HEADER)
endif()
message(STATUS "TCL header: ${TCL_HEADER}")
get_filename_component(TCL_HEADER_DIR "${TCL_HEADER}" PATH)
################################################################
#
# Flex/bison scanner/parsers
#
################################################################
find_package(FLEX)
@ -672,7 +698,7 @@ target_link_libraries(sta
)
if (ZLIB_FOUND)
target_link_libraries(sta ${ZLIB_LIBRARIES})
endif(ZLIB_FOUND)
endif()
message(STATUS "STA executable: ${STA_HOME}/app/sta")

139
INSTALL
View File

@ -14,32 +14,81 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
Builds are supported by dist tarfiles or from the git repository.
Building from a dist tarfile does not require the GNU Autotools, Bison
or Flex to be installed and is the recommended method unless you are a
developer.
Builds are supported with cmake. Builds with Autotools are supported
for compatibility but are deprecated.
Builds are also supported with cmake described later in this file.
Autotools based builds are currently supported for compatibility but
are deprecated.
Building from a tarfile
-----------------------
Building with Cmake
-------------------
The build dependency versions are show below. Other versions may
work, but these are the versions used for development.
from Ubuntu Xcode
from Ubuntu Xcode
18.04.1 10.1
clang 9.1.0 10.0.0
gcc 3.3.2 7.3.0
tcl 8.2 8.6 8.6.6
swig 1.3.28 3.0.12 3.0.12
bison 1.35 3.0.4 2.3
flex 2.5.4 2.6.4 2.5.35
Building with cmake requires bison, flex and swig.
These packages are optional:
libz 1.1.4 1.2.5 1.2.8
cudd 2.4.1 3.0.0
CUDD is a BDD package that is used to improve conditional timing arc
handling. It is available here:
https://www.davidkebo.com/source/cudd_versions/cudd-3.0.0.tar.gz
https://sourceforge.net/projects/cudd-mirror/
Note that the file hierarchy of the CUDD installation changed with
version 3.0. This build only supports the 3.0 layout but only small
changes to configure.ac are required to support older versions.
The Zlib library is an optional. If the configure script finds libz,
OpenSTA can read Verilog, SDF, SPF, and SPEF files compressed with
gzip.
Use the following commands to checkout the git repository build the
OpenSTA library and excutable.
git clone https://xp-dev.com/git/opensta
cd opensta
mkdir build
cd build
cmake ..
make
The resulting executable is in app/sta.
The library without a main() procedure is app/libSTA.a.
Optional cmake variables passed as -D<var>=<value> arguments to cmake
are show below.
CMAKE_BUILD_TYPE DEBUG|RELEASE
TCL_LIB - path to tcl library
TCL_HEADER - path to tcl.h
CMAKE_INSTALL_PREFIX
If TCL_LIB is specified the cmake script will attempt to locate the
header from its path.
The default install directory is /usr/local.
To install in a different directory with cmake use:
cmake .. -DCMAKE_INSTALL_PREFIX=<prefix_path>
or use the DESTDIR variable with make.
make DESTDIR=<prefix_path> install
Building from a tarfile
-----------------------
Use the following commands to unpack the dist file and compile it.
tar zvfz opensta-<version>.tgz
@ -63,20 +112,6 @@ configure options:
--with-cudd=path use Cudd BDD package, defaults to $CUDD
--with-visualstudio use Microcruft Visual Studio C++ compiler
CUDD is a BDD package that is used to improve conditional timing arc
handling. It is available here:
https://www.davidkebo.com/source/cudd_versions/cudd-3.0.0.tar.gz
https://sourceforge.net/projects/cudd-mirror/
Note that the file hierarchy of the CUDD installation changed with
version 3.0. This build only supports the 3.0 layout but only small
changes to configure.ac are required to support older versions.
The Zlib library is an optional. If the configure script finds libz,
OpenSTA can read Verilog, SDF, SPF, and SPEF files compressed with
gzip.
If the configure script fails to find any of the TCL, Zlib or CUDD
files, use the --with-include, --with-lib, --with-tcl, --with-cudd
options to add directories to search for the files.
@ -86,10 +121,10 @@ are not described above. The default arguments to configure disable
shared libraries. To build with shared libraries use the
--enable-shared option.
Building from the git repository
--------------------------------
Building with GNU Autotools
---------------------------
Building from the git repository has the additional build dependencies
Building with GNU Autotools the additional build dependencies
shown below.
from Ubuntu Xcode
@ -97,15 +132,6 @@ shown below.
autoconf 2.53 2.69 2.69
automake 1.6.3 1.15.1 1.16.1
libtool 1.4.2 2.4.6 2.4.6
swig 1.3.28 3.0.12 3.0.12
bison 1.35 3.0.4 2.3
flex 2.5.4 2.6.4 2.5.35
These packages are optional:
gdb 5.3 8.1
lldb 902.0.79.7 1000.11.38.2
valgrind 1.9.6 3.13.0 N/A
Use the following commands to checkout the git repository and compile
it.
@ -116,43 +142,9 @@ it.
./configure [options...]
make
Building with Cmake
-------------------
Building with cmake requires bison and flex.
git clone https://xp-dev.com/git/opensta
cd opensta
mkdir build
cd build
cmake ../
make
The resulting executable is app/sta for compatibility with configure.
The library without main is app/libSTA.a.
Optional cmake variables passed as -D<var>=<value> arguments to cmake.
CMAKE_BUILD_TYPE DEBUG|RELEASE
TCL_LIB - path to tcl library
TCL_HEADER - path to tcl.h
TCL_INIT - path to init.tcl
CMAKE_INSTALL_PREFIX
If TCL_LIB is specified the cmake script will attempt to locate
the header and init files from its path.
Default install directory is /usr/local.
To install in a different directory with cmake use:
cmake .. -DCMAKE_INSTALL_PREFIX=<prefix_path>
or use the DESTDIR variable with make.
make DESTDIR=<prefix_path> install
Building on Windoz
------------------
The Win32 API does not natively support the pthreads API. The
pthreads-win32 package is one way to get support for pthreads for 32
bit builds. It is available from www.sourceware.org/pthreads-win32.
@ -169,6 +161,9 @@ tcsh-startup.bat
set path=c:\cygwin\bin;%PATH%
c:\cygwin\bin\tcsh
cmake is supposedly more compatible with the windoz environment
so you may have better luck wih it.
Configure and build from the shell. Note that tcl and zlib must be
built with the Visual C++ compiler to link to the sta libraries.

View File

@ -11,3 +11,5 @@
#if ${CUDD_FOUND}==TRUE
#define CUDD
#endif
#define SSTA ${SSTA}

View File

@ -16,7 +16,7 @@
# Process this file with autoconf to produce a configure script.
AC_INIT(sta, 2.0.3)
AC_INIT(sta, 2.0.4)
AM_INIT_AUTOMAKE
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS(config.h)

Binary file not shown.

Binary file not shown.

View File

@ -1885,16 +1885,20 @@ ConcreteParasitics::value(const ParasiticDevice *device,
return cdevice->value();
}
void
ConcreteParasitics::resistorNodes(const ParasiticDevice *device,
// Return values.
ParasiticNode *&node1,
ParasiticNode *&node2) const
ParasiticNode *
ConcreteParasitics::node1(const ParasiticDevice *device) const
{
const ConcreteParasiticResistor *cdevice =
static_cast<const ConcreteParasiticResistor*>(device);
node1 = cdevice->node1();
node2 = cdevice->node2();
const ConcreteParasiticDevice *cdevice =
static_cast<const ConcreteParasiticDevice*>(device);
return cdevice->node1();
}
ParasiticNode *
ConcreteParasitics::node2(const ParasiticDevice *device) const
{
const ConcreteParasiticDevice *cdevice =
static_cast<const ConcreteParasiticDevice*>(device);
return cdevice->node2();
}
ParasiticNode *

View File

@ -175,10 +175,8 @@ public:
virtual const char *name(const ParasiticDevice *device) const;
virtual float value(const ParasiticDevice *device,
const ParasiticAnalysisPt *ap) const;
virtual void resistorNodes(const ParasiticDevice *device,
// Return values.
ParasiticNode *&node1,
ParasiticNode *&node2) const;
virtual ParasiticNode *node1(const ParasiticDevice *device) const;
virtual ParasiticNode *node2(const ParasiticDevice *device) const;
virtual ParasiticNode *otherNode(const ParasiticDevice *device,
ParasiticNode *node) const;

View File

@ -299,6 +299,8 @@ public:
virtual bool isCouplingCap() const { return false; }
const char *name() const { return name_; }
float value() const { return value_; }
ConcreteParasiticNode *node1() const { return node_; }
virtual ConcreteParasiticNode *node2() const = 0;
virtual ParasiticNode *otherNode(ParasiticNode *node) const = 0;
virtual void replaceNode(ConcreteParasiticNode *from_node,
ConcreteParasiticNode *to_node) = 0;
@ -319,11 +321,10 @@ public:
ConcreteParasiticNode *other_node,
float res);
virtual bool isResistor() const { return true; }
virtual ConcreteParasiticNode *node2() const { return other_node_; }
virtual ParasiticNode *otherNode(ParasiticNode *node) const;
virtual void replaceNode(ConcreteParasiticNode *from_node,
ConcreteParasiticNode *to_node);
ConcreteParasiticNode *node1() const { return node_; }
ConcreteParasiticNode *node2() const { return other_node_; }
private:
ConcreteParasiticNode *other_node_;
@ -337,6 +338,7 @@ public:
ConcreteParasiticNode *node,
float cap);
virtual bool isCouplingCap() const { return true; }
virtual ConcreteParasiticNode *node2() const { return NULL; }
virtual void replaceNode(ConcreteParasiticNode *from_node,
ConcreteParasiticNode *to_node);
};
@ -349,6 +351,7 @@ public:
ConcreteParasiticNode *other_node,
float cap);
virtual bool isCouplingCap() const { return true; }
virtual ConcreteParasiticNode *node2() const { return other_node_; }
virtual ParasiticNode *otherNode(ParasiticNode *node) const;
virtual void replaceNode(ConcreteParasiticNode *from_node,
ConcreteParasiticNode *to_node);

View File

@ -424,12 +424,16 @@ NullParasitics::value(const ParasiticDevice *,
return 0.0;
}
void
NullParasitics::resistorNodes(const ParasiticDevice *,
// Return values.
ParasiticNode *&,
ParasiticNode *&) const
ParasiticNode *
NullParasitics::node1(const ParasiticDevice *) const
{
return NULL;
}
ParasiticNode *
NullParasitics::node2(const ParasiticDevice *) const
{
return NULL;
}
ParasiticNode *

View File

@ -164,10 +164,8 @@ public:
virtual const char *name(const ParasiticDevice *device) const;
virtual float value(const ParasiticDevice *device,
const ParasiticAnalysisPt *ap) const;
virtual void resistorNodes(const ParasiticDevice *device,
// Return values.
ParasiticNode *&node1,
ParasiticNode *&node2) const;
virtual ParasiticNode *node1(const ParasiticDevice *device) const;
virtual ParasiticNode *node2(const ParasiticDevice *device) const;
virtual ParasiticNode *otherNode(const ParasiticDevice *device,
ParasiticNode *node) const;
// Reduce parasitic network to reduce_to model.

View File

@ -248,10 +248,8 @@ public:
// Device "value" (resistance, capacitance).
virtual float value(const ParasiticDevice *device,
const ParasiticAnalysisPt *ap) const = 0;
virtual void resistorNodes(const ParasiticDevice *device,
// Return values.
ParasiticNode *&node1,
ParasiticNode *&node2) const = 0;
virtual ParasiticNode *node1(const ParasiticDevice *device) const = 0;
virtual ParasiticNode *node2(const ParasiticDevice *device) const = 0;
virtual ParasiticNode *otherNode(const ParasiticDevice *device,
ParasiticNode *node) const = 0;

View File

@ -498,12 +498,14 @@ exceptionToEmpty(ExceptionTo *to);
PathEndSeq *
PathGroups::makePathEnds(ExceptionTo *to,
bool unconstrained_paths,
const Corner *corner,
const MinMaxAll *min_max,
bool sort_by_slack)
{
Stats stats(this->debug());
makeGroupPathEnds(to, group_count_, endpoint_count_, unique_pins_, corner, min_max);
makeGroupPathEnds(to, group_count_, endpoint_count_, unique_pins_,
corner, min_max);
PathEndSeq *path_ends = new PathEndSeq;
pushGroupPathEnds(path_ends);
@ -513,7 +515,7 @@ PathGroups::makePathEnds(ExceptionTo *to,
path_ends->resize(group_count_);
}
if (search_->reportUnconstrainedPaths()
if (unconstrained_paths
&& path_ends->empty())
// No constrained paths, so report unconstrained paths.
pushUnconstrainedPathEnds(path_ends, min_max);

View File

@ -119,6 +119,7 @@ public:
// Returned PathEndSeq is owned by the caller.
// The PathEnds in the vector are owned by the PathGroups.
PathEndSeq *makePathEnds(ExceptionTo *to,
bool unconstrained_paths,
const Corner *corner,
const MinMaxAll *min_max,
bool sort_by_slack);

View File

@ -228,7 +228,7 @@ void
Search::init(StaState *sta)
{
crpr_path_pruning_enabled_ = true;
report_unconstrained_paths_ = false;
unconstrained_paths_ = false;
search_adj_ = new SearchThru(NULL, sta);
eval_pred_ = new EvalPred(sta);
check_crpr_ = new CheckCrpr(sta);
@ -329,14 +329,6 @@ Search::setCrprpathPruningEnabled(bool enabled)
crpr_path_pruning_enabled_ = enabled;
}
void
Search::setReportUnconstrainedPaths(bool report)
{
if (report_unconstrained_paths_ != report)
arrivalsInvalid();
report_unconstrained_paths_ = report;
}
void
Search::deleteTags()
{
@ -430,6 +422,7 @@ PathEndSeq *
Search::findPathEnds(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
bool unconstrained,
const Corner *corner,
const MinMaxAll *min_max,
int group_count,
@ -446,6 +439,7 @@ Search::findPathEnds(ExceptionFrom *from,
bool clk_gating_setup,
bool clk_gating_hold)
{
unconstrained_paths_ = unconstrained;
// Delete results from last findPathEnds.
// Filtered arrivals are deleted by Sta::searchPreamble.
deletePathGroups();
@ -474,7 +468,8 @@ Search::findPathEnds(ExceptionFrom *from,
recovery, removal,
clk_gating_setup, clk_gating_hold);
ensureDownstreamClkPins();
PathEndSeq *path_ends = path_groups_->makePathEnds(to, corner, min_max,
PathEndSeq *path_ends = path_groups_->makePathEnds(to, unconstrained_paths_,
corner, min_max,
sort_by_slack);
sdc_->reportClkToClkMaxCycleWarnings();
return path_ends;
@ -1462,7 +1457,7 @@ Search::seedArrival(Vertex *vertex)
bool is_reg_clk = vertex->isRegClk();
if (is_reg_clk
// Internal roots isolated by disabled pins are seeded with no clock.
|| (report_unconstrained_paths_
|| (unconstrained_paths_
&& !network_->isTopLevelPort(pin))) {
debugPrint1(debug_, "search", 2, "arrival seed unclked root %s\n",
network_->pathName(pin));
@ -3236,7 +3231,7 @@ Search::isEndpoint(Vertex *vertex,
|| sdc_->isPathDelayInternalEndpoint(pin)
|| !hasFanout(vertex, pred, graph_)
// Unconstrained paths at register clk pins.
|| (report_unconstrained_paths_
|| (unconstrained_paths_
&& vertex->isRegClk()));
}
@ -4026,7 +4021,7 @@ Search::makePathGroups(int group_count,
setup, hold,
recovery, removal,
clk_gating_setup, clk_gating_hold,
report_unconstrained_paths_,
unconstrained_paths_,
this);
}

View File

@ -75,9 +75,7 @@ public:
// non-critical paths on intermediate pins may be incorrect.
bool crprPathPruningEnabled() const;
void setCrprpathPruningEnabled(bool enabled);
// Report unconstrained paths.
bool reportUnconstrainedPaths() const { return report_unconstrained_paths_; }
void setReportUnconstrainedPaths(bool report);
bool unconstrainedPaths() const { return unconstrained_paths_; }
// from/thrus/to are owned and deleted by Search.
// Use corner NULL to report timing for all corners.
// Returned sequence is owned by the caller.
@ -85,6 +83,7 @@ public:
PathEndSeq *findPathEnds(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
bool unconstrained,
const Corner *corner,
const MinMaxAll *min_max,
int group_count,
@ -524,7 +523,8 @@ protected:
////////////////////////////////////////////////////////////////
bool report_unconstrained_paths_;
// findPathEnds arg.
bool unconstrained_paths_;
bool have_paths_;
// Search predicates.
SearchPred *search_adj_;

View File

@ -2281,18 +2281,6 @@ Sta::setUseDefaultArrivalClock(bool enable)
}
}
bool
Sta::reportUnconstrainedPaths() const
{
return search_->reportUnconstrainedPaths();
}
void
Sta::setReportUnconstrainedPaths(bool report)
{
search_->setReportUnconstrainedPaths(report);
}
bool
Sta::propagateAllClocks() const
{
@ -2374,6 +2362,7 @@ PathEndSeq *
Sta::findPathEnds(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
bool unconstrained,
const Corner *corner,
const MinMaxAll *min_max,
int group_count,
@ -2391,7 +2380,7 @@ Sta::findPathEnds(ExceptionFrom *from,
bool clk_gating_hold)
{
searchPreamble();
return search_->findPathEnds(from, thrus, to,
return search_->findPathEnds(from, thrus, to, unconstrained,
corner, min_max, group_count, endpoint_count,
unique_pins, slack_min, slack_max,
sort_by_slack, group_names,
@ -2552,8 +2541,8 @@ PinSet *
Sta::findGroupPathPins(const char *group_path_name)
{
if (!search_->havePathGroups()) {
PathEndSeq *path_ends = findPathEnds(// from, thrus, to
NULL, NULL, NULL,
PathEndSeq *path_ends = findPathEnds(// from, thrus, to, unconstrained
NULL, NULL, NULL, false,
// corner, min_max,
NULL, MinMaxAll::max(),
// group_count, endpoint_count, unique_pins

View File

@ -721,9 +721,6 @@ public:
bool no_version);
// Remove all delay and slew annotations.
void removeDelaySlewAnnotations();
// TCL variable sta_report_unconstrained_paths.
bool reportUnconstrainedPaths() const;
void setReportUnconstrainedPaths(bool report);
// TCL variable sta_crpr_enabled.
// Common Reconvergent Clock Removal (CRPR).
// Timing check source/target common clock path overlap for search
@ -787,6 +784,7 @@ public:
virtual PathEndSeq *findPathEnds(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
bool unconstrained,
// Use corner NULL to report timing
// for all corners.
const Corner *corner,

View File

@ -62,7 +62,7 @@ VisitPathEnds::visitPathEnds(Vertex *vertex,
bool is_constrained = false;
visitClkedPathEnds(pin, vertex, corner, min_max, filtered, visitor,
is_constrained);
if (search_->reportUnconstrainedPaths()
if (search_->unconstrainedPaths()
&& !is_constrained
&& !vertex->isDisabledConstraint())
visitUnconstrainedPathEnds(pin, vertex, corner, min_max, filtered,

View File

@ -279,7 +279,9 @@ WritePathSpice::maxTime()
Path *input_path = stageDrvrPath(input_stage);
auto input_slew = input_path->slew(this);
auto end_slew = path_->slew(this);
auto max_time = (input_slew + path_->arrival(this) + end_slew * 2) * 1.5;
auto max_time = delayAsFloat(input_slew
+ path_->arrival(this)
+ end_slew * 2) * 1.5;
return max_time;
}
@ -348,7 +350,7 @@ WritePathSpice::writeInputSource()
volt1 = gnd_voltage_;
}
Path *input_path = stageDrvrPath(input_stage);
auto input_slew = input_path->slew(this);
auto input_slew = delayAsFloat(input_path->slew(this));
if (input_slew == 0.0)
input_slew = maxTime() / 1e+3;
// Arbitrary offset.
@ -732,8 +734,8 @@ WritePathSpice::writeStageParasitics(Stage stage)
auto device = device_iter.next();
auto resistance = parasitics_->value(device, parasitic_ap);
if (parasitics_->isResistor(device)) {
ParasiticNode *node1, *node2;
parasitics_->resistorNodes(device, node1, node2);
ParasiticNode *node1 = parasitics_->node1(device);
ParasiticNode *node2 = parasitics_->node2(device);
streamPrint(spice_stream_, "R%d %s %s %.3e\n",
resistor_index,
nodeName(node1),
@ -742,6 +744,14 @@ WritePathSpice::writeStageParasitics(Stage stage)
resistor_index++;
}
else if (parasitics_->isCouplingCap(device)) {
// Ground coupling caps for now.
ParasiticNode *node1 = parasitics_->node1(device);
auto cap = parasitics_->value(device, parasitic_ap);
streamPrint(spice_stream_, "C%d %s 0 %.3e\n",
cap_index,
nodeName(node1),
cap);
cap_index++;
}
}
ParasiticNodeSet::Iterator node_iter(nodes);

View File

@ -1930,7 +1930,7 @@ proc write_path_spice { args } {
sta_error "No -path_args specified.\n"
}
set path_args $keys(-path_args)
set path_ends [eval [concat get_timing_paths $path_args]]
set path_ends [eval [concat find_timing_paths $path_args]]
if { $path_ends == {} } {
sta_error "No paths found for -path_args $path_args.\n"
} else {

View File

@ -143,6 +143,7 @@ define_sta_cmd_args "find_timing_paths" \
[-through through_list|-rise_through through_list|-fall_through through_list]\
[-to to_list|-rise_to to_list|-fall_to to_list]\
[-path_delay min|min_rise|min_fall|max|max_rise|max_fall|min_max]\
[-unconstrained]
[-corner corner_name]\
[-group_count path_count] \
[-endpoint_count path_count]\
@ -158,13 +159,14 @@ proc find_timing_paths { args } {
}
proc find_timing_paths_cmd { cmd args_var } {
global sta_report_unconstrained_paths
upvar 1 $args_var args
parse_key_args "find_timing_paths" args \
parse_key_args $cmd args \
keys {-from -rise_from -fall_from -to -rise_to -fall_to \
-path_delay -corner -group_count -endpoint_count \
-slack_max -slack_min -path_group} \
flags {-sort_by_slack -unique_paths_to_endpoint} 0
flags {-unconstrained -sort_by_slack -unique_paths_to_endpoint} 0
set min_max "max"
set end_tr "rise_fall"
@ -185,7 +187,7 @@ proc find_timing_paths_cmd { cmd args_var } {
} elseif { $mm_key == "min" || $mm_key == "max" || $mm_key == "min_max" } {
set min_max $mm_key
} else {
sta_error "report_checks -path_delay must be min, min_rise, min_fall, max, max_rise, max_fall or min_max."
sta_error "$cmd -path_delay must be min, min_rise, min_fall, max, max_rise, max_fall or min_max."
}
}
@ -200,6 +202,14 @@ proc find_timing_paths_cmd { cmd args_var } {
check_for_key_args $cmd args
if { [info exists flags(-unconstrained)] } {
set unconstrained 1
} elseif { [info exists sta_report_unconstrained_paths] } {
set unconstrained $sta_report_unconstrained_paths
} else {
set unconstrained 0
}
set corner [parse_corner_or_all keys]
set endpoint_count 1
@ -251,7 +261,8 @@ proc find_timing_paths_cmd { cmd args_var } {
}
}
set path_ends [find_path_ends $from $thrus $to $corner $min_max \
set path_ends [find_path_ends $from $thrus $to $unconstrained \
$corner $min_max \
$group_count $endpoint_count $unique_pins \
$slack_min $slack_max \
$sort_by_slack $groups \
@ -265,6 +276,7 @@ define_sta_cmd_args "report_checks" \
{[-from from_list|-rise_from from_list|-fall_from from_list]\
[-through through_list|-rise_through through_list|-fall_through through_list]\
[-to to_list|-rise_to to_list|-fall_to to_list]\
[-unconstrained]\
[-path_delay min|min_rise|min_fall|max|max_rise|max_fall|min_max]\
[-corner corner_name]\
[-group_count path_count] \
@ -286,11 +298,7 @@ proc_redirect report_checks {
parse_report_path_options "report_checks" args "full" 0
set path_ends [find_timing_paths_cmd "report_checks" args]
if { $path_ends == {} } {
if { $sta_report_unconstrained_paths } {
puts "No paths."
} else {
puts "No constrained paths."
}
puts "No paths found."
} else {
report_path_ends $path_ends
}

View File

@ -2123,18 +2123,6 @@ net_is_constrained(Net *net)
return Sta::sta()->sdc()->isConstrained(net);
}
bool
report_unconstrained_paths()
{
return Sta::sta()->reportUnconstrainedPaths();
}
void
set_report_unconstrained_paths(bool report)
{
Sta::sta()->setReportUnconstrainedPaths(report);
}
bool
clk_thru_tristate_enabled()
{
@ -4104,6 +4092,7 @@ PathEndSeq *
find_path_ends(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
bool unconstrained,
Corner *corner,
const MinMaxAll *delay_min_max,
int group_count,
@ -4122,7 +4111,7 @@ find_path_ends(ExceptionFrom *from,
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
PathEndSeq *ends = sta->findPathEnds(from, thrus, to,
PathEndSeq *ends = sta->findPathEnds(from, thrus, to, unconstrained,
corner, delay_min_max,
group_count, endpoint_count, unique_pins,
slack_min, slack_max,
@ -4422,6 +4411,17 @@ worst_slack(const MinMax *min_max)
return worst_slack;
}
Vertex *
worst_slack_vertex(const MinMax *min_max)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
Slack worst_slack;
Vertex *worst_vertex;
sta->worstSlack(min_max, worst_slack, worst_vertex);
return worst_vertex;;
}
Slack
worst_slack_corner(const Corner *corner,
const MinMax *min_max)
@ -6051,6 +6051,22 @@ tag()
return self->tag(sta)->asString(sta);
}
// mea_opt3
TmpPinSeq *
pins()
{
Sta *sta = Sta::sta();
PinSeq *pins = new PinSeq;
PathRef path1(self);
while (!path1.isNull()) {
pins->push_back(path1.vertex(sta)->pin());
PathRef prev_path;
path1.prevPath(sta, prev_path);
path1.init(prev_path);
}
return pins;
}
}
%extend VertexPathIterator {

View File

@ -160,14 +160,6 @@ proc trace_propagate_gated_clock_enable { name1 name2 op } {
propagate_gated_clock_enable set_propagate_gated_clock_enable
}
trace variable ::sta_report_unconstrained_paths "rw" \
sta::trace_report_unconstrained_paths
proc trace_report_unconstrained_paths { ignore1 ignore2 op } {
trace_boolean_var $op ::sta_report_unconstrained_paths \
report_unconstrained_paths set_report_unconstrained_paths
}
################################################################
proc trace_boolean_var { op var_name get_proc set_proc } {

View File

@ -171,6 +171,7 @@ port_dcl_type:
| INOUT REG { $$ = sta::PortDirection::bidirect(); }
| INOUT WIRE { $$ = sta::PortDirection::bidirect(); }
| OUTPUT { $$ = sta::PortDirection::output(); }
| OUTPUT WIRE { $$ = sta::PortDirection::output(); }
| OUTPUT REG { $$ = sta::PortDirection::output(); }
;