diff --git a/CMakeLists.txt b/CMakeLists.txt
index 598aa9c9..b47a1bbc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -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")
diff --git a/INSTALL b/INSTALL
index e072e1db..24ee7769 100644
--- a/INSTALL
+++ b/INSTALL
@@ -14,32 +14,81 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-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= 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=
+
+or use the DESTDIR variable with make.
+
+ make DESTDIR= install
+
+Building from a tarfile
+-----------------------
+
Use the following commands to unpack the dist file and compile it.
tar zvfz opensta-.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= 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=
-
-or use the DESTDIR variable with make.
-
- make DESTDIR= 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.
diff --git a/config.h.cmake b/config.h.cmake
index a5768558..082defe3 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -11,3 +11,5 @@
#if ${CUDD_FOUND}==TRUE
#define CUDD
#endif
+
+#define SSTA ${SSTA}
diff --git a/configure.ac b/configure.ac
index a9adc7f6..f11b57c3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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)
diff --git a/doc/OpenSTA.odt b/doc/OpenSTA.odt
index 337075e0..3ab8edb4 100644
Binary files a/doc/OpenSTA.odt and b/doc/OpenSTA.odt differ
diff --git a/doc/OpenSTA.pdf b/doc/OpenSTA.pdf
index 9d33f260..d80c07d5 100644
Binary files a/doc/OpenSTA.pdf and b/doc/OpenSTA.pdf differ
diff --git a/parasitics/ConcreteParasitics.cc b/parasitics/ConcreteParasitics.cc
index c8453dc8..6db058ba 100644
--- a/parasitics/ConcreteParasitics.cc
+++ b/parasitics/ConcreteParasitics.cc
@@ -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(device);
- node1 = cdevice->node1();
- node2 = cdevice->node2();
+ const ConcreteParasiticDevice *cdevice =
+ static_cast(device);
+ return cdevice->node1();
+}
+
+ParasiticNode *
+ConcreteParasitics::node2(const ParasiticDevice *device) const
+{
+ const ConcreteParasiticDevice *cdevice =
+ static_cast(device);
+ return cdevice->node2();
}
ParasiticNode *
diff --git a/parasitics/ConcreteParasitics.hh b/parasitics/ConcreteParasitics.hh
index fc2eb94d..1171d00a 100644
--- a/parasitics/ConcreteParasitics.hh
+++ b/parasitics/ConcreteParasitics.hh
@@ -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;
diff --git a/parasitics/ConcreteParasiticsPvt.hh b/parasitics/ConcreteParasiticsPvt.hh
index 769ff128..7bc2fca7 100644
--- a/parasitics/ConcreteParasiticsPvt.hh
+++ b/parasitics/ConcreteParasiticsPvt.hh
@@ -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);
diff --git a/parasitics/NullParasitics.cc b/parasitics/NullParasitics.cc
index f3c77061..f2151b6d 100644
--- a/parasitics/NullParasitics.cc
+++ b/parasitics/NullParasitics.cc
@@ -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 *
diff --git a/parasitics/NullParasitics.hh b/parasitics/NullParasitics.hh
index b1767f61..3c4b14ed 100644
--- a/parasitics/NullParasitics.hh
+++ b/parasitics/NullParasitics.hh
@@ -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.
diff --git a/parasitics/Parasitics.hh b/parasitics/Parasitics.hh
index eba324e4..c9592487 100644
--- a/parasitics/Parasitics.hh
+++ b/parasitics/Parasitics.hh
@@ -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;
diff --git a/search/PathGroup.cc b/search/PathGroup.cc
index ee0ffd9a..f8761384 100644
--- a/search/PathGroup.cc
+++ b/search/PathGroup.cc
@@ -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);
diff --git a/search/PathGroup.hh b/search/PathGroup.hh
index 50b46551..d9f6c1af 100644
--- a/search/PathGroup.hh
+++ b/search/PathGroup.hh
@@ -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);
diff --git a/search/Search.cc b/search/Search.cc
index f277139d..837e3744 100644
--- a/search/Search.cc
+++ b/search/Search.cc
@@ -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);
}
diff --git a/search/Search.hh b/search/Search.hh
index ee0de690..9fd7a114 100644
--- a/search/Search.hh
+++ b/search/Search.hh
@@ -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_;
diff --git a/search/Sta.cc b/search/Sta.cc
index 6e00bff9..a02a6aa0 100644
--- a/search/Sta.cc
+++ b/search/Sta.cc
@@ -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
diff --git a/search/Sta.hh b/search/Sta.hh
index 7e8a136e..8d6e8f18 100644
--- a/search/Sta.hh
+++ b/search/Sta.hh
@@ -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,
diff --git a/search/VisitPathEnds.cc b/search/VisitPathEnds.cc
index b574b1d1..a1603006 100644
--- a/search/VisitPathEnds.cc
+++ b/search/VisitPathEnds.cc
@@ -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,
diff --git a/search/WritePathSpice.cc b/search/WritePathSpice.cc
index f046a659..561e0265 100644
--- a/search/WritePathSpice.cc
+++ b/search/WritePathSpice.cc
@@ -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);
diff --git a/tcl/Cmds.tcl b/tcl/Cmds.tcl
index f89727c5..5c412bc7 100644
--- a/tcl/Cmds.tcl
+++ b/tcl/Cmds.tcl
@@ -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 {
diff --git a/tcl/Sta.tcl b/tcl/Sta.tcl
index 9ef71520..1909f781 100644
--- a/tcl/Sta.tcl
+++ b/tcl/Sta.tcl
@@ -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
}
diff --git a/tcl/StaTcl.i b/tcl/StaTcl.i
index f9a9b43f..945064ea 100644
--- a/tcl/StaTcl.i
+++ b/tcl/StaTcl.i
@@ -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 {
diff --git a/tcl/Variables.tcl b/tcl/Variables.tcl
index da0331bf..ea07f296 100644
--- a/tcl/Variables.tcl
+++ b/tcl/Variables.tcl
@@ -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 } {
diff --git a/verilog/VerilogParse.yy b/verilog/VerilogParse.yy
index d0c5e8ee..4c9afc50 100644
--- a/verilog/VerilogParse.yy
+++ b/verilog/VerilogParse.yy
@@ -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(); }
;