...
 
Commits (28)
.gitignore
Dockerfile
README
INSTALL
*.o
*.a
*.lo
*.la
*.gcov
*.gcda
*.gcno
*.rej
*.orig
TAGS
*~
\#*#
.~lock.*#
.DS_Store
Makefile
/build
/debug
/rel
# /util/
/util/StaConfig.hh
# /app/
/app/StaApp_wrap.cc
/app/TclInitVar.cc
/app/sta
/app/sta.exe
/app/sta.dSYM
# /doc/
/doc/._Sta.docx
/doc/.~lock.Sta.doc#
/doc/.~lock.Sta.odt#
# /liberty/
/liberty/LibertyExprLex.cc
/liberty/LibertyExprLex.hh
/liberty/LibertyExprParse.cc
/liberty/LibertyExprParse.h
/liberty/LibertyLex.cc
/liberty/LibertyLex.hh
/liberty/LibertyParse.cc
/liberty/LibertyParse.h
/liberty/LibertyExprParse.hh
/liberty/LibertyParse.hh
# /parasitics/
/parasitics/SpefLex.cc
/parasitics/SpefLex.hh
/parasitics/SpefParse.cc
/parasitics/SpefParse.hh
/parasitics/SpfLex.cc
/parasitics/SpfLex.hh
/parasitics/SpfParse.cc
/parasitics/SpfParse.hh
# /sdf/
/sdf/SdfLex.cc
/sdf/SdfLex.hh
/sdf/SdfParse.cc
/sdf/SdfParse.hh
# /tcl/
/tcl/history.tcl
/tcl/init.tcl
# /test/
/test/gmon.out
/test/results
# ngspice turd
/test/b3v3_1check.log
/test_native
# /verilog/
/verilog/VerilogLex.hh
/verilog/VerilogLex.cc
/verilog/VerilogParse.cc
/verilog/VerilogParse.h
/verilog/VerilogParse.output
/verilog/VerilogParse.hh
This diff is collapsed.
FROM ubuntu:18.04
LABEL author="James Cherry"
LABEL maintainer="Abdelrahman Hosny <abdelrahman@brown.edu>"
# install basics
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
apt-get install -y wget apt-utils git cmake gcc tcl-dev swig bison flex
# download CUDD
RUN wget https://www.davidkebo.com/source/cudd_versions/cudd-3.0.0.tar.gz && \
tar -xvf cudd-3.0.0.tar.gz && \
rm cudd-3.0.0.tar.gz
# install CUDD
RUN cd cudd-3.0.0 && \
mkdir ../cudd && \
./configure --prefix=$HOME/cudd && \
make && \
make install
# copy files and install OpenSTA
RUN mkdir OpenSTA
COPY . OpenSTA
RUN cd OpenSTA && \
mkdir build && \
cd build && \
cmake .. -DCUDD=$HOME/cudd && \
make
# Run sta on entry
ENTRYPOINT ["OpenSTA/app/sta"]
This diff is collapsed.
# Parallax Static Timing Analyzer
OpenSTA is a gate level static timing verifier. As a stand-alone
executable it can be used to verify the timing of a design using
standard file formats.
* Verilog netlist
* Liberty library
* SDC timing constraints
* SDF delay annotation
* SPEF parasitics
OpenSTA uses a TCL command interpreter to read the design, specify
timing constraints and print timing reports.
##### Clocks
* Generated
* Latency
* Source latency (insertion delay)
* Uncertainty
* Propagated/Ideal
* Gated clock checks
* Multiple frequency clocks
##### Exception paths
* False path
* Multicycle path
* Min/Max path delay
* Exception points
* -from clock/pin/instance -through pin/net -to clock/pin/instance
* Edge specific exception points
* -rise_from/-fall_from, -rise_through/-fall_through, -rise_to/-fall_to
##### Delay calculation
* Integrated Dartu/Menezes/Pileggi RC effective capacitance algorithm
* External delay calculator API
##### Analysis
* Report timing checks -from, -through, -to, multiple paths to endpoint
* Report delay calculation
* Check timing setup
##### Timing Engine
OpenSTA is architected to be easily bolted on to other tools as a
timing engine. By using a network adapter, OpenSTA can access the host
netlist data structures without duplicating them.
* Query based incremental update of delays, arrival and required times
* Simulator to propagate constants from constraints and netlist tie high/low
See doc/OpenSTA.pdf for complete documentiaton.
## Getting Started
OpenSTA can be run as a [Docker](https://www.docker.com/) container
or built as local executable with CMake.
### Run using Docker
* Install Docker on [Windows](https://docs.docker.com/docker-for-windows/), [Mac](https://docs.docker.com/docker-for-mac/) or [Linux](https://docs.docker.com/install/).
* Navigate to the directory where you have the input files.
* Run OpenSTA as a binary using
````
docker run -it -v $(pwd):/data openroad/opensta
````
4. From the interactive terminal, use OpenSTA commands. You can read input files from `/data` directory inside the docker container (e.g. `read_liberty /data/liberty.lib`). You can use OpenSTA in non-interactive mode by passing a command file using the `-f` flag as follows.
```
docker run -it -v $(pwd):/data openroad/opensta -f /data/cmd_file
```
Note that the path after `-f` is the path inside container, not on the guest machine.
### Prerequisites
The build dependency versions are show below. Other versions may
work, but these are the versions used for development.
```
from Ubuntu Xcode
18.04.1 10.1
cmake 3.9
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
```
These packages are **optional**:
```
libz 1.1.4 1.2.5 1.2.8
cudd 2.4.1 3.0.0
```
CUDD is a binary decision diageram (BDD) package that is used to improve conditional timing arc handling. OpenSTA does not require it to be installed. It is available [here](https://www.davidkebo.com/source/cudd_versions/cudd-3.0.0.tar.gz) or [here](https://sourceforge.net/projects/cudd-mirror/).
Note that the file hierarchy of the CUDD installation changed with version 3.0.
Some changes to CMakeLists.txt are required to support older versions.
When building CUDD you may use the `--prefix ` option to `configure` to
install in a location other than the default (`/usr/local/lib`).
```
cd $HOME/cudd-3.0.0
mkdir $HOME/cudd
./configure --prefix $HOME/cudd
make
make install
```
To not use CUDD specify `CUDD=0`.
Cmake looks for the CUDD library in `CUDD/lib, CUDD/cudd/lib`
and for the header in `CUDD/include, CUDD/cudd/include`.
```
# equivalent to -DCUDD=0
cmake ..
or
cmake .. -DCUDD=0
or
# look in ~/cudd/lib, ~/cudd/include
cmake .. -DCUDD=$HOME/cudd
or
# look in /usr/local/lib/cudd, /usr/local/include/cudd
cmake .. -DCUDD=/usr/local
```
The Zlib library is an optional. If CMake finds libz, OpenSTA can
read Verilog, SDF, SPF, and SPEF files compressed with gzip.
### Installing with CMake
Use the following commands to checkout the git repository and build the
OpenSTA library and excutable.
```
git clone https://github.com/The-OpenROAD-Project/OpenSTA.git
cd OpenSTA
mkdir build
cd build
cmake ..
make
```
The default build type is release to compile optimized code.
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
CMAKE_CXX_FLAGS - additional compiler flags
TCL_LIB - path to tcl library
TCL_HEADER - path to tcl.h
CUDD - path to cudd installation
ZLIB_ROOT - path to zlib
CMAKE_INSTALL_PREFIX
```
If `TCL_LIB` is specified the CMake script will attempt to locate the
header from the library path.
The default install directory is `/usr/local`.
To install in a different directory with CMake use:
```
cmake .. -DCMAKE_INSTALL_PREFIX=<prefix_path>
```
Alternatively, you can use the `DESTDIR` variable with make.
```
make DESTDIR=<prefix_path> install
```
If you make changes to `CMakeLists.txt` you may need to clean out
existing CMake cached variable values by deleting all of the
files in the build directory.
## Authors
* James Cherry
* William Scott authored the arnoldi delay calculator at Blaze, Inc which was subsequently licensed to Nefelus, Inc that has graciously contributed it to OpenSTA.
## Bug Reports
Use the Issues tab on the github repository to report bugs.
Each issue/bug should be a separate issue. The subject of the issue
should be a short description of the problem. Attach a test case to
reproduce the issue as described below. Issues without test cases are
unlikely to get a response.
The files in the test case should be collected into a directory named
YYYYMMDD where YYYY is the year, MM is the month, and DD is the
day (this format allows "ls" to report them in chronological order).
The contents of the directory should be collected into a compressed
tarfile named YYYYMMDD.tgz.
The test case should have a tcl command file recreates the issue named
run.tcl. If there are more than one command file using the same data
files, there should be separate command files, run1.tcl, run2.tcl
etc. The bug report can refer to these command files by name.
Command files should not have absolute filenames like
"/home/cho/OpenSTA_Request/write_path_spice/dump_spice" in them.
These obviously are not portable. Use filenames relative to the test
case directory.
## License
OpenSTA is dual licensed. It is released under GPL v3 as OpenSTA and
is also licensed for commerical applications by Parallax Software without
the GPL's requirements.
OpenSTA, Static Timing Analyzer
Copyright (c) 2019, Parallax Software, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2019, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <stdio.h>
#include "Machine.hh"
#include "StaConfig.hh" // STA_VERSION
#include "StringUtil.hh"
#include "Sta.hh"
#include "StaMain.hh"
using sta::stringEq;
using sta::Sta;
using sta::staMain;
using sta::showUsage;
// Swig uses C linkage for init functions.
extern "C" {
extern int Sta_Init(Tcl_Interp *interp);
}
namespace sta {
extern const char *tcl_inits[];
}
int
main(int argc,
char *argv[])
{
if (argc == 2 && stringEq(argv[1], "-help")) {
showUsage(argv[0]);
return 0;
}
else if (argc == 2 && stringEq(argv[1], "-version")) {
printf("%s\n", STA_VERSION);
return 0;
}
else {
Sta *sta = new Sta;
staMain(sta, argc, argv, Sta_Init, sta::tcl_inits);
return 0;
}
}
# OpenSTA, Static Timing Analyzer
# Copyright (c) 2019, Parallax Software, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
bin_PROGRAMS = sta
include_HEADERS = \
StaMain.hh
sta_SOURCES = \
Main.cc \
StaMain.cc \
StaApp_wrap.cc \
TclInitVar.cc
NETWORK_LIBS = \
../verilog/libverilog.la
sta_DEPENDENCIES = $(NETWORK_LIBS) $(STA_LIBS) $(CUDD_LIBS)
sta_LDADD = $(NETWORK_LIBS) $(STA_LIBS) $(CUDD_LIBS)
StaApp_wrap.cc: $(SWIG_DEPEND) StaApp.i ../verilog/Verilog.i
$(SWIG) $(SWIG_FLAGS) -namespace -prefix sta \
-o StaApp_wrap.cc StaApp.i
../etc/SwigCleanup.tcl StaApp_wrap.cc
# TCL files included as part of the executable.
# These files are encoded and shipped as part of the executable
# so that they do not have to be installed on the client host.
TclInitVar.cc: ../etc/TclEncode.tcl $(TCL_INIT_FILES)
../etc/TclEncode.tcl TclInitVar.cc "tcl_inits" \
$(TCL_INIT_FILES) ../verilog/Verilog.tcl
EXTRA_DIST = \
StaApp.i
# TclInitVar.cc is derived and TCL version specific, so don't dist it.
dist-hook:
rm -rf $(distdir)/TclInitVar.cc
MAINTAINERCLEANFILES = \
StaApp_wrap.cc \
TclInitVar.cc
libs: $(sta_OBJECTS)
xtags: $(SOURCES) $(HEADERS)
etags -a -o ../TAGS $(SOURCES) $(HEADERS)
%module sta
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2019, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
%include "StaException.i"
%include "StaTcl.i"
%include "Verilog.i"
%include "NetworkEdit.i"
%include "Sdf.i"
%include "DelayCalc.i"
%include "Parasitics.i"
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2019, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <tcl.h>
#include <stdlib.h>
#include "Machine.hh"
#include "StringUtil.hh"
#include "Vector.hh"
#include "Sta.hh"
#include "StaMain.hh"
namespace sta {
typedef sta::Vector<SwigInitFunc> SwigInitFuncSeq;
// "Arguments" passed to staTclAppInit.
static int sta_argc;
static char **sta_argv;
static const char **sta_tcl_inits;
static SwigInitFunc sta_swig_init;
static const char *init_filename = "[file join $env(HOME) .sta]";
void
staMain(Sta *sta,
int argc,
char *argv[],
SwigInitFunc swig_init,
const char *tcl_inits[])
{
initSta();
Sta::setSta(sta);
sta->makeComponents();
int thread_count = parseThreadsArg(argc, argv);
sta->setThreadCount(thread_count);
staSetupAppInit(argc, argv, swig_init, tcl_inits);
// Set argc to 1 so Tcl_Main doesn't source any files.
// Tcl_Main never returns.
Tcl_Main(1, argv, staTclAppInit);
}
int
parseThreadsArg(int &argc,
char *argv[])
{
char *thread_arg = findCmdLineKey(argc, argv, "-threads");
if (thread_arg) {
if (stringEqual(thread_arg, "max"))
return processorCount();
else if (isDigits(thread_arg))
return atoi(thread_arg);
else
fprintf(stderr,"Warning: -threads must be max or a positive integer.\n");
}
return 1;
}
// Set globals to pass to staTclAppInit.
void
staSetupAppInit(int argc,
char *argv[],
SwigInitFunc swig_init,
const char *tcl_inits[])
{
sta_argc = argc;
sta_argv = argv;
sta_tcl_inits = tcl_inits;
sta_swig_init = swig_init;
}
// Tcl init executed inside Tcl_Main.
int
staTclAppInit(Tcl_Interp *interp)
{
int argc = sta_argc;
char **argv = sta_argv;
// source init.tcl
Tcl_Init(interp);
// Define swig commands.
sta_swig_init(interp);
Sta *sta = Sta::sta();
sta->setTclInterp(interp);
// Eval encoded sta TCL sources.
evalTclInit(interp, sta_tcl_inits);
if (!findCmdLineFlag(argc, argv, "-no_splash"))
Tcl_Eval(interp, "sta::show_splash");
// Import exported commands from sta namespace to global namespace.
Tcl_Eval(interp, "sta::define_sta_cmds");
Tcl_Eval(interp, "namespace import sta::*");
if (!findCmdLineFlag(argc, argv, "-no_init"))
sourceTclFile(init_filename, true, true, interp);
bool exit_after_cmd_file = findCmdLineFlag(argc, argv, "-exit");
if (argc > 2 ||
(argc > 1 && argv[1][0] == '-'))
showUsage(argv[0]);
else {
if (argc == 2) {
char *cmd_file = argv[1];
if (cmd_file) {
sourceTclFile(cmd_file, false, false, interp);
if (exit_after_cmd_file)
exit(EXIT_SUCCESS);
}
}
}
return TCL_OK;
}
bool
findCmdLineFlag(int &argc,
char *argv[],
const char *flag)
{
for (int i = 1; i < argc; i++) {
char *arg = argv[i];
if (stringEq(arg, flag)) {
// remove flag from argv.
for (int j = i + 1; j < argc; j++, i++)
argv[i] = argv[j];
argc--;
return true;
}
}
return false;
}
char *
findCmdLineKey(int &argc,
char *argv[],
const char *key)
{
for (int i = 1; i < argc; i++) {
char *arg = argv[i];
if (stringEq(arg, key) && i + 1 < argc) {
char *value = argv[i + 1];
// remove key and value from argv.
for (int j = i + 2; j < argc; j++, i++)
argv[i] = argv[j];
argc -= 2;
return value;
}
}
return nullptr;
}
// Use overridden version of source to echo cmds and results.
void
sourceTclFile(const char *filename,
bool echo,
bool verbose,
Tcl_Interp *interp)
{
string cmd;
stringPrint(cmd, "source %s%s%s",
echo ? "-echo " : "",
verbose ? "-verbose " : "",
filename);
Tcl_Eval(interp, cmd.c_str());
}
void
evalTclInit(Tcl_Interp *interp,
const char *inits[])
{
size_t length = 0;
for (const char **e = inits; *e; e++) {
const char *init = *e;
length += strlen(init);
}
char *unencoded = new char[length / 3 + 1];
char *u = unencoded;
for (const char **e = inits; *e; e++) {
const char *init = *e;
size_t init_length = strlen(init);
for (const char *s = init; s < &init[init_length]; s += 3) {
char code[4] = {s[0], s[1], s[2], '\0'};
char ch = atoi(code);
*u++ = ch;
}
}
*u = '\0';
if (Tcl_Eval(interp, unencoded) != TCL_OK) {
// Get a backtrace for the error.
Tcl_Eval(interp, "$errorInfo");
const char *tcl_err = Tcl_GetStringResult(interp);
fprintf(stderr, "Error: TCL init script: %s.\n", tcl_err);
fprintf(stderr, " Try deleting app/TclInitVar.cc and rebuilding.\n");
exit(0);
}
delete [] unencoded;
}
void
showUsage(const char * prog)
{
printf("Usage: %s [-help] [-version] [-no_init] [-exit] cmd_file\n", prog);
printf(" -help show help and exit\n");
printf(" -version show version and exit\n");
printf(" -no_init do not read .sta init file\n");
printf(" -threads count|max use count threads\n");
printf(" -no_splash do not show the license splash at startup\n");
printf(" -exit exit after reading cmd_file\n");
printf(" cmd_file source cmd_file\n");
}
} // namespace
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2019, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#ifndef STA_APP_H
#define STA_APP_H
struct Tcl_Interp;
namespace sta {
class Sta;
typedef int (*SwigInitFunc)(Tcl_Interp *);
// The swig_init function is called to define the swig interface
// functions to the tcl interpreter.
void
staMain(Sta *sta,
int argc,
char *argv[],
SwigInitFunc swig_init,
const char *tcl_inits[]);
// Set arguments passed to staTclAppInit inside the tcl interpreter.
void
staSetupAppInit(int argc,
char *argv[],
SwigInitFunc swig_init,
const char *tcl_inits[]);
int
staTclAppInit(Tcl_Interp *interp);
// TCL init files are encoded into the string init using the three
// digit decimal equivalent for each ascii character. This function
// unencodes the string and evals it. This packages the TCL init
// files as part of the executable so they don't have to be shipped as
// separate files that have to be located and loaded at run time.
void
evalTclInit(Tcl_Interp *interp,
const char *inits[]);
bool
findCmdLineFlag(int &argc,
char *argv[],
const char *flag);
char *
findCmdLineKey(int &argc,
char *argv[],
const char *key);
void
showUsage(const char *prog);
int
parseThreadsArg(int &argc,
char *argv[]);
void
sourceTclFile(const char *filename,
bool echo,
bool verbose,
Tcl_Interp *interp);
} // namespace
#endif
# - Returns a version string from Git
#
# These functions force a re-configure on each git commit so that you can
# trust the values of the variables in your build system.
#
# get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])
#
# Returns the refspec and sha hash of the current head revision
#
# git_describe(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe on the source tree, and adjusting
# the output so that it tests false if an error occurs.
#
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe --exact-match on the source tree,
# and adjusting the output so that it tests false if there was no exact
# matching tag.
#
# git_local_changes(<var>)
#
# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes.
# Uses the return code of "git diff-index --quiet HEAD --".
# Does not regard untracked files.
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if(__get_git_revision_description)
return()
endif()
set(__get_git_revision_description YES)
# We must run the following at "include" time, not at function call time,
# to find the path to this module rather than the path to a calling list file
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
function(get_git_head_revision _refspecvar _hashvar)
set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories
set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}")
get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)
if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)
# We have reached the root directory, we are not in git
set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
return()
endif()
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
endwhile()
# check if this is a submodule
if(NOT IS_DIRECTORY ${GIT_DIR})
file(READ ${GIT_DIR} submodule)
string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule})
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE)
endif()
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
if(NOT EXISTS "${GIT_DATA}")
file(MAKE_DIRECTORY "${GIT_DATA}")
endif()
if(NOT EXISTS "${GIT_DIR}/HEAD")
return()
endif()
set(HEAD_FILE "${GIT_DATA}/HEAD")
configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY)
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
"${GIT_DATA}/grabRef.cmake"
@ONLY)
include("${GIT_DATA}/grabRef.cmake")
set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE)
set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE)
endfunction()
function(git_describe _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
return()
endif()
# TODO sanitize
#if((${ARGN}" MATCHES "&&") OR
# (ARGN MATCHES "||") OR
# (ARGN MATCHES "\\;"))
# message("Please report the following error to the project!")
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
#endif()
#message(STATUS "Arguments to execute_process: ${ARGN}")
execute_process(COMMAND
"${GIT_EXECUTABLE}"
describe
${hash}
${ARGN}
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE
res
OUTPUT_VARIABLE
out
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
set(${_var} "${out}" PARENT_SCOPE)
endfunction()
function(git_get_exact_tag _var)
git_describe(out --exact-match ${ARGN})
set(${_var} "${out}" PARENT_SCOPE)
endfunction()
function(git_local_changes _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
return()
endif()
execute_process(COMMAND
"${GIT_EXECUTABLE}"
diff-index --quiet HEAD --
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE
res
OUTPUT_VARIABLE
out
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(res EQUAL 0)
set(${_var} "CLEAN" PARENT_SCOPE)
else()
set(${_var} "DIRTY" PARENT_SCOPE)
endif()
endfunction()
#
# Internal file for GetGitRevisionDescription.cmake
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
set(HEAD_HASH)
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
if(HEAD_CONTENTS MATCHES "ref")
# named branch
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
else()
configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY)
file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
set(HEAD_HASH "${CMAKE_MATCH_1}")
endif()
endif()
else()
# detached HEAD
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
endif()
if(NOT HEAD_HASH)
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
string(STRIP "${HEAD_HASH}" HEAD_HASH)
endif()
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2019, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "Machine.hh"
#include "TimingModel.hh"
#include "TimingArc.hh"
#include "GraphDelayCalc.hh"
#include "ArcDelayCalc.hh"
namespace sta {
ArcDelayCalc::ArcDelayCalc(StaState *sta):
StaState(sta)
{
}
TimingModel *
ArcDelayCalc::model(TimingArc *arc,
const DcalcAnalysisPt *dcalc_ap) const
{
const OperatingConditions *op_cond = dcalc_ap->operatingConditions();
TimingArc *corner_arc = arc->cornerArc(dcalc_ap->libertyIndex());
return corner_arc->model(op_cond);
}
GateTimingModel *
ArcDelayCalc::gateModel(TimingArc *arc,
const DcalcAnalysisPt *dcalc_ap) const
{
return dynamic_cast<GateTimingModel*>(model(arc, dcalc_ap));
}
CheckTimingModel *
ArcDelayCalc::checkModel(TimingArc *arc,
const DcalcAnalysisPt *dcalc_ap) const
{
return dynamic_cast<CheckTimingModel*>(model(arc, dcalc_ap));
}
} // namespace
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2019, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#ifndef STA_ARC_DELAY_CALC_H
#define STA_ARC_DELAY_CALC_H
#include <string>
#include "DisallowCopyAssign.hh"
#include "MinMax.hh"
#include "Delay.hh"
#include "StaState.hh"
#include "LibertyClass.hh"
#include "NetworkClass.hh"
namespace sta {
using std::string;
class Parasitic;
class DcalcAnalysisPt;
// Delay calculator class hierarchy.
// ArcDelayCalc
// UnitDelayCalc
// LumpedCapDelayCalc
// RCDelayCalc
// SimpleRCDelayCalc
// DmpCeffDelayCalc
// DmpCeffElmoreDelayCalc
// DmpCeffTwoPoleDelayCalc
// Abstract class to interface to a delay calculator primitive.
class ArcDelayCalc : public StaState
{
public:
explicit ArcDelayCalc(StaState *sta);
virtual ~ArcDelayCalc() {}
virtual ArcDelayCalc *copy() = 0;
// Find the parasitic for drvr_pin that is acceptable to the delay
// calculator by probing parasitics_.
virtual Parasitic *findParasitic(const Pin *drvr_pin,
const TransRiseFall *tr,
const DcalcAnalysisPt *dcalc_ap) = 0;
// Find the wire delays and slews for an input port without a driving cell.
// This call primarily initializes the load delay/slew iterator.
virtual void inputPortDelay(const Pin *port_pin,
float in_slew,
const TransRiseFall *tr,
Parasitic *parasitic,
const DcalcAnalysisPt *dcalc_ap) = 0;
// Find the delay and slew for arc driving drvr_pin.
virtual void gateDelay(const LibertyCell *drvr_cell,
TimingArc *arc,
const Slew &in_slew,
// Pass in load_cap or drvr_parasitic.
float load_cap,
Parasitic *drvr_parasitic,
float related_out_cap,
const Pvt *pvt,
const DcalcAnalysisPt *dcalc_ap,
// Return values.
ArcDelay &gate_delay,
Slew &drvr_slew) = 0;
// Find the wire delay and load slew of a load pin.
// Called after inputPortDelay or gateDelay.
virtual void loadDelay(const Pin *load_pin,
// Return values.
ArcDelay &wire_delay,
Slew &load_slew) = 0;
virtual void setMultiDrvrSlewFactor(float factor) = 0;
// Ceff for parasitics with pi models.
virtual float ceff(const LibertyCell *drvr_cell,
TimingArc *arc,
const Slew &in_slew,
float load_cap,
Parasitic *drvr_parasitic,
float related_out_cap,
const Pvt *pvt,
const DcalcAnalysisPt *dcalc_ap) = 0;
// Find the delay for a timing check arc given the arc's
// from/clock, to/data slews and related output pin parasitic.
virtual void checkDelay(const LibertyCell *drvr_cell,
TimingArc *arc,
const Slew &from_slew,
const Slew &to_slew,
float related_out_cap,
const Pvt *pvt,
const DcalcAnalysisPt *dcalc_ap,
// Return values.
ArcDelay &margin) = 0;
// Report delay and slew calculation.
virtual void reportGateDelay(const LibertyCell *drvr_cell,
TimingArc *arc,
const Slew &in_slew,
// Pass in load_cap or drvr_parasitic.
float load_cap,
Parasitic *drvr_parasitic,
float related_out_cap,
const Pvt *pvt,
const DcalcAnalysisPt *dcalc_ap,
int digits,
string *result) = 0;
// Report timing check delay calculation.
virtual void reportCheckDelay(const LibertyCell *cell,
TimingArc *arc,