Merge remote-tracking branch 'parallax/master'
Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
This commit is contained in:
commit
b8b590e90c
|
|
@ -15,11 +15,6 @@ cmake-build-debug
|
|||
build
|
||||
pvt
|
||||
|
||||
app/sta
|
||||
app/libOpenSTA.*
|
||||
app/sta.exe
|
||||
app/sta.dSYM
|
||||
|
||||
# iverilog turd
|
||||
examples/gcd_tb
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.14)
|
|||
cmake_policy(SET CMP0086 NEW)
|
||||
endif()
|
||||
|
||||
project(STA VERSION 2.6.2
|
||||
project(STA VERSION 2.7.0
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
|
|
@ -471,9 +471,6 @@ target_include_directories(sta_swig
|
|||
# Library
|
||||
###########################################################
|
||||
|
||||
# compatibility with configure
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${STA_HOME}/app)
|
||||
|
||||
add_library(OpenSTA)
|
||||
|
||||
target_sources(OpenSTA
|
||||
|
|
@ -553,13 +550,12 @@ target_compile_options(OpenSTA
|
|||
set_target_properties(OpenSTA PROPERTIES CXX_EXTENSIONS OFF)
|
||||
target_compile_features(OpenSTA PUBLIC cxx_std_17)
|
||||
|
||||
message(STATUS "STA library: ${CMAKE_BINARY_DIR}/libOpenSTA.a")
|
||||
|
||||
###########################################################
|
||||
# Executable
|
||||
###########################################################
|
||||
|
||||
# compatibility with configure
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${STA_HOME}/app)
|
||||
|
||||
# Note executable and lib name cannot be the same because
|
||||
# on osx something is case insensitive. Using STA for the
|
||||
# lib name results in "No rule to make target ../depend.
|
||||
|
|
@ -570,7 +566,7 @@ target_link_libraries(sta
|
|||
OpenSTA
|
||||
)
|
||||
|
||||
message(STATUS "STA executable: ${STA_HOME}/app/sta")
|
||||
message(STATUS "STA executable: ${CMAKE_BINARY_DIR}/sta")
|
||||
|
||||
################################################################
|
||||
# Install
|
||||
|
|
|
|||
|
|
@ -64,4 +64,4 @@ RUN source /opt/rh/devtoolset-11/enable && \
|
|||
make -j`nproc`
|
||||
|
||||
# Run sta on entry
|
||||
ENTRYPOINT ["/OpenSTA/app/sta"]
|
||||
ENTRYPOINT ["/OpenSTA/build/sta"]
|
||||
|
|
|
|||
|
|
@ -40,4 +40,4 @@ RUN cd OpenSTA && \
|
|||
make -j`nproc`
|
||||
|
||||
# Run sta on entry
|
||||
ENTRYPOINT ["OpenSTA/app/sta"]
|
||||
ENTRYPOINT ["OpenSTA/build/sta"]
|
||||
|
|
|
|||
|
|
@ -161,8 +161,8 @@ cmake -DCUDD_DIR=<CUDD_INSTALL_DIR> ,.
|
|||
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`.
|
||||
The resulting executable is in `build/sta`.
|
||||
The library without a `main()` procedure is `build/libOpenSTA.a`.
|
||||
|
||||
Optional CMake variables passed as -D<var>=<value> arguments to CMake are show below.
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
%include "sdc/Sdc.i"
|
||||
%include "sdf/Sdf.i"
|
||||
%include "search/Search.i"
|
||||
%include "search/Property.i"
|
||||
%include "util/Util.i"
|
||||
%include "spice/WriteSpice.i"
|
||||
%include "verilog/Verilog.i"
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ sourceTclFile(const char *filename,
|
|||
bool verbose,
|
||||
Tcl_Interp *interp)
|
||||
{
|
||||
string cmd;
|
||||
std::string cmd;
|
||||
stringPrint(cmd, "sta::include_file %s %s %s",
|
||||
filename,
|
||||
echo ? "1" : "0",
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ namespace sta {
|
|||
// ra_get_r
|
||||
// ra_get_s
|
||||
|
||||
using std::string;
|
||||
using std::abs;
|
||||
using std::vector;
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
|
||||
// Implementaion based on:
|
||||
// "Gate Delay Estimation with Library Compatible Current Source Models
|
||||
// and Effective Capacitance", D. Garyfallou et al,
|
||||
|
|
|
|||
|
|
@ -50,14 +50,14 @@ public:
|
|||
const Parasitic *parasitic,
|
||||
const LoadPinIndexMap &load_pin_index_map,
|
||||
const DcalcAnalysisPt *dcalc_ap) override;
|
||||
string reportGateDelay(const Pin *drvr_pin,
|
||||
const TimingArc *arc,
|
||||
const Slew &in_slew,
|
||||
float load_cap,
|
||||
const Parasitic *parasitic,
|
||||
const LoadPinIndexMap &load_pin_index_map,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
int digits) override;
|
||||
std::string reportGateDelay(const Pin *drvr_pin,
|
||||
const TimingArc *arc,
|
||||
const Slew &in_slew,
|
||||
float load_cap,
|
||||
const Parasitic *parasitic,
|
||||
const LoadPinIndexMap &load_pin_index_map,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
int digits) override;
|
||||
|
||||
// Record waveform for drvr/load pin.
|
||||
void watchPin(const Pin *pin) override;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@
|
|||
#include "dcalc/PrimaDelayCalc.hh"
|
||||
#include "Sta.hh"
|
||||
|
||||
using std::string;
|
||||
|
||||
%}
|
||||
|
||||
%inline %{
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
using std::log;
|
||||
|
||||
DelayCalcBase::DelayCalcBase(StaState *sta) :
|
||||
|
|
|
|||
|
|
@ -52,14 +52,14 @@ public:
|
|||
float related_out_cap,
|
||||
const DcalcAnalysisPt *dcalc_ap) override;
|
||||
|
||||
string reportCheckDelay(const Pin *check_pin,
|
||||
const TimingArc *arc,
|
||||
const Slew &from_slew,
|
||||
const char *from_slew_annotation,
|
||||
const Slew &to_slew,
|
||||
float related_out_cap,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
int digits) override;
|
||||
std::string reportCheckDelay(const Pin *check_pin,
|
||||
const TimingArc *arc,
|
||||
const Slew &from_slew,
|
||||
const char *from_slew_annotation,
|
||||
const Slew &to_slew,
|
||||
float related_out_cap,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
int digits) override;
|
||||
|
||||
protected:
|
||||
// Find the liberty library to use for logic/slew thresholds.
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
using std::abs;
|
||||
using std::min;
|
||||
using std::max;
|
||||
|
|
|
|||
|
|
@ -50,14 +50,14 @@ public:
|
|||
const Parasitic *parasitic,
|
||||
const LoadPinIndexMap &load_pin_index_map,
|
||||
const DcalcAnalysisPt *dcalc_ap) override;
|
||||
string reportGateDelay(const Pin *drvr_pin,
|
||||
const TimingArc *arc,
|
||||
const Slew &in_slew,
|
||||
float load_cap,
|
||||
const Parasitic *parasitic,
|
||||
const LoadPinIndexMap &load_pin_index_map,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
int digits) override;
|
||||
std::string reportGateDelay(const Pin *drvr_pin,
|
||||
const TimingArc *arc,
|
||||
const Slew &in_slew,
|
||||
float load_cap,
|
||||
const Parasitic *parasitic,
|
||||
const LoadPinIndexMap &load_pin_index_map,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
int digits) override;
|
||||
void copyState(const StaState *sta) override;
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
using std::abs;
|
||||
using std::array;
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
using std::isnan;
|
||||
|
||||
ArcDelayCalc *
|
||||
|
|
|
|||
|
|
@ -57,14 +57,14 @@ public:
|
|||
const Parasitic *parasitic,
|
||||
const LoadPinIndexMap &load_pin_index_map,
|
||||
const DcalcAnalysisPt *dcalc_ap) override;
|
||||
string reportGateDelay(const Pin *drvr_pin,
|
||||
const TimingArc *arc,
|
||||
const Slew &in_slew,
|
||||
float load_cap,
|
||||
const Parasitic *parasitic,
|
||||
const LoadPinIndexMap &load_pin_index_map,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
int digits) override;
|
||||
std::string reportGateDelay(const Pin *drvr_pin,
|
||||
const TimingArc *arc,
|
||||
const Slew &in_slew,
|
||||
float load_cap,
|
||||
const Parasitic *parasitic,
|
||||
const LoadPinIndexMap &load_pin_index_map,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
int digits) override;
|
||||
|
||||
protected:
|
||||
ArcDcalcResult makeResult(const LibertyLibrary *drvr_library,
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
using std::abs;
|
||||
using std::make_shared;
|
||||
using Eigen::SparseLU;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
|
||||
ArcDelayCalc *
|
||||
makeUnitDelayCalc(StaState *sta)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -74,22 +74,22 @@ public:
|
|||
const Slew &to_slew,
|
||||
float related_out_cap,
|
||||
const DcalcAnalysisPt *dcalc_ap) override;
|
||||
string reportGateDelay(const Pin *drvr_pin,
|
||||
const TimingArc *arc,
|
||||
const Slew &in_slew,
|
||||
float load_cap,
|
||||
const Parasitic *parasitic,
|
||||
const LoadPinIndexMap &load_pin_index_map,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
int digits) override;
|
||||
string reportCheckDelay(const Pin *check_pin,
|
||||
const TimingArc *arc,
|
||||
const Slew &from_slew,
|
||||
const char *from_slew_annotation,
|
||||
const Slew &to_slew,
|
||||
float related_out_cap,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
int digits) override;
|
||||
std::string reportGateDelay(const Pin *drvr_pin,
|
||||
const TimingArc *arc,
|
||||
const Slew &in_slew,
|
||||
float load_cap,
|
||||
const Parasitic *parasitic,
|
||||
const LoadPinIndexMap &load_pin_index_map,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
int digits) override;
|
||||
std::string reportCheckDelay(const Pin *check_pin,
|
||||
const TimingArc *arc,
|
||||
const Slew &from_slew,
|
||||
const char *from_slew_annotation,
|
||||
const Slew &to_slew,
|
||||
float related_out_cap,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
int digits) override;
|
||||
void finishDrvrPin() override;
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
This file summarizes STA API changes for each release.
|
||||
|
||||
Release 2.6.2 2024/03/30
|
||||
Release 2.6.2 2025/03/30
|
||||
------------------------
|
||||
|
||||
The following functions have been renamed to to_string and return std::string
|
||||
|
|
|
|||
|
|
@ -3,7 +3,22 @@ OpenSTA Timing Analyzer Release Notes
|
|||
|
||||
This file summarizes user visible changes for each release.
|
||||
|
||||
Realase 2.6.1 2025/03/30
|
||||
Release 2.7.0 2025/05/19
|
||||
-------------------------
|
||||
|
||||
The OpenSTA library `libOpenSTA` and `sta` executable are now built in the
|
||||
build directory instead of `app/`.
|
||||
|
||||
The set_max_delay and set_min_delay commands now support the -probe option.
|
||||
With -probe these commands do not break paths at internal (non-startpoint) pins.
|
||||
|
||||
The set_property command is used to annotate a user defined property
|
||||
on an object. It does not change the value of built in properties. If
|
||||
property names a built-in property it has no effect.
|
||||
|
||||
set_property [-object_type type] object property value
|
||||
|
||||
Release 2.6.1 2025/03/30
|
||||
-------------------------
|
||||
|
||||
The -list_annotated and -list_not_annotated arguments to the
|
||||
|
|
|
|||
BIN
doc/OpenSTA.odt
BIN
doc/OpenSTA.odt
Binary file not shown.
BIN
doc/OpenSTA.pdf
BIN
doc/OpenSTA.pdf
Binary file not shown.
|
|
@ -232,23 +232,23 @@ public:
|
|||
float related_out_cap,
|
||||
const DcalcAnalysisPt *dcalc_ap) = 0;
|
||||
// Report delay and slew calculation.
|
||||
virtual string reportGateDelay(const Pin *drvr_pin,
|
||||
const TimingArc *arc,
|
||||
const Slew &in_slew,
|
||||
float load_cap,
|
||||
const Parasitic *parasitic,
|
||||
const LoadPinIndexMap &load_pin_index_map,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
int digits) = 0;
|
||||
virtual std::string reportGateDelay(const Pin *drvr_pin,
|
||||
const TimingArc *arc,
|
||||
const Slew &in_slew,
|
||||
float load_cap,
|
||||
const Parasitic *parasitic,
|
||||
const LoadPinIndexMap &load_pin_index_map,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
int digits) = 0;
|
||||
// Report timing check delay calculation.
|
||||
virtual string reportCheckDelay(const Pin *check_pin,
|
||||
const TimingArc *arc,
|
||||
const Slew &from_slew,
|
||||
const char *from_slew_annotation,
|
||||
const Slew &to_slew,
|
||||
float related_out_cap,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
int digits) = 0;
|
||||
virtual std::string reportCheckDelay(const Pin *check_pin,
|
||||
const TimingArc *arc,
|
||||
const Slew &from_slew,
|
||||
const char *from_slew_annotation,
|
||||
const Slew &to_slew,
|
||||
float related_out_cap,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
int digits) = 0;
|
||||
virtual void finishDrvrPin() = 0;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ class LibertyCell;
|
|||
class LibertyPort;
|
||||
|
||||
typedef Map<std::string, ConcreteCell*> ConcreteCellMap;
|
||||
typedef std::map<std::string, std::string> AttributeMap;
|
||||
typedef Vector<ConcretePort*> ConcretePortSeq;
|
||||
typedef Map<std::string, ConcretePort*> ConcretePortMap;
|
||||
typedef ConcreteCellMap::ConstIterator ConcreteLibraryCellIterator;
|
||||
|
|
@ -117,6 +116,7 @@ public:
|
|||
void setAttribute(const std::string &key,
|
||||
const std::string &value);
|
||||
std::string getAttribute(const std::string &key) const;
|
||||
const AttributeMap &attributeMap() const { return attribute_map_; }
|
||||
|
||||
// Cell acts as port factory.
|
||||
ConcretePort *makePort(const char *name);
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ class ConcreteBindingTbl;
|
|||
class ConcreteLibertyLibraryIterator;
|
||||
|
||||
typedef Vector<ConcreteLibrary*> ConcreteLibrarySeq;
|
||||
typedef std::map<std::string, std::string> AttributeMap;
|
||||
typedef Map<const char*, ConcreteLibrary*, CharPtrLess> ConcreteLibraryMap;
|
||||
typedef ConcreteLibrarySeq::ConstIterator ConcreteLibraryIterator;
|
||||
typedef Map<const char *, ConcreteInstance*,
|
||||
|
|
@ -85,6 +84,7 @@ public:
|
|||
const char *name(const Cell *cell) const override;
|
||||
std::string getAttribute(const Cell *cell,
|
||||
const std::string &key) const override;
|
||||
const AttributeMap &attributeMap(const Cell *cell) const override;
|
||||
ObjectId id(const Cell *cell) const override;
|
||||
Library *library(const Cell *cell) const override;
|
||||
LibertyCell *libertyCell(Cell *cell) const override;
|
||||
|
|
@ -121,6 +121,7 @@ public:
|
|||
const char *name(const Instance *instance) const override;
|
||||
std::string getAttribute(const Instance *inst,
|
||||
const std::string &key) const override;
|
||||
const AttributeMap &attributeMap(const Instance *inst) const override;
|
||||
ObjectId id(const Instance *instance) const override;
|
||||
Cell *cell(const Instance *instance) const override;
|
||||
Instance *parent(const Instance *instance) const override;
|
||||
|
|
@ -307,6 +308,7 @@ public:
|
|||
void setAttribute(const std::string &key,
|
||||
const std::string &value);
|
||||
std::string getAttribute(const std::string &key) const;
|
||||
const AttributeMap &attributeMap() const { return attribute_map_; }
|
||||
void addChild(ConcreteInstance *child);
|
||||
void deleteChild(ConcreteInstance *child);
|
||||
void addPin(ConcretePin *pin);
|
||||
|
|
|
|||
|
|
@ -119,6 +119,9 @@ public:
|
|||
ExceptionThruSeq *thrus,
|
||||
ExceptionTo *to,
|
||||
bool own_pts) = 0;
|
||||
void deleteInstance(const Instance *inst,
|
||||
const Network *network);
|
||||
|
||||
// Default handlers.
|
||||
virtual bool useEndClk() const { return false; }
|
||||
virtual int pathMultiplier() const { return 0; }
|
||||
|
|
@ -126,6 +129,7 @@ public:
|
|||
virtual const char *name() const { return nullptr; }
|
||||
virtual bool isDefault() const { return false; }
|
||||
virtual bool ignoreClkLatency() const { return false; }
|
||||
virtual bool breakPath() const { return false; }
|
||||
|
||||
protected:
|
||||
virtual const char *typeString() const = 0;
|
||||
|
|
@ -194,6 +198,7 @@ public:
|
|||
ExceptionTo *to,
|
||||
const MinMax *min_max,
|
||||
bool ignore_clk_latency,
|
||||
bool break_path,
|
||||
float delay,
|
||||
bool own_pts,
|
||||
const char *comment);
|
||||
|
|
@ -211,9 +216,11 @@ public:
|
|||
virtual int typePriority() const;
|
||||
virtual bool tighterThan(ExceptionPath *exception) const;
|
||||
virtual bool ignoreClkLatency() const { return ignore_clk_latency_; }
|
||||
virtual bool breakPath() const { return break_path_; }
|
||||
|
||||
protected:
|
||||
bool ignore_clk_latency_;
|
||||
bool break_path_;
|
||||
float delay_;
|
||||
};
|
||||
|
||||
|
|
@ -410,14 +417,14 @@ public:
|
|||
Network *) {}
|
||||
virtual void disconnectPinBefore(const Pin *,
|
||||
Network *) {}
|
||||
void deleteInstance(const Instance *inst,
|
||||
const Network *network);
|
||||
|
||||
protected:
|
||||
virtual void findHash(const Network *network);
|
||||
|
||||
void deletePin(const Pin *pin,
|
||||
const Network *network);
|
||||
void deleteInstance(const Instance *inst,
|
||||
const Network *network);
|
||||
virtual const char *cmdKeyword() const = 0;
|
||||
|
||||
PinSet *pins_;
|
||||
|
|
@ -532,6 +539,8 @@ public:
|
|||
Network *network);
|
||||
virtual void disconnectPinBefore(const Pin *pin,
|
||||
Network *network);
|
||||
void deleteInstance(const Instance *inst,
|
||||
const Network *network);
|
||||
|
||||
protected:
|
||||
void findHash(const Network *network);
|
||||
|
|
@ -549,8 +558,6 @@ protected:
|
|||
void deleteEdge(const EdgePins &edge);
|
||||
void deleteNet(const Net *net,
|
||||
const Network *network);
|
||||
void deleteInstance(const Instance *inst,
|
||||
const Network *network);
|
||||
void makeAllEdges(const Network *network);
|
||||
void makePinEdges(const Network *network);
|
||||
void makeNetEdges(const Network *network);
|
||||
|
|
|
|||
|
|
@ -69,11 +69,11 @@ public:
|
|||
// Find and annotate drvr_vertex gate and load delays/slews.
|
||||
virtual void findDelays(Vertex *drvr_vertex);
|
||||
// Returned string is owned by the caller.
|
||||
virtual string reportDelayCalc(const Edge *edge,
|
||||
const TimingArc *arc,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
int digits);
|
||||
virtual std::string reportDelayCalc(const Edge *edge,
|
||||
const TimingArc *arc,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
int digits);
|
||||
// Percentage (0.0:1.0) change in delay that causes downstream
|
||||
// delays to be recomputed during incremental delay calculation.
|
||||
virtual float incrementalDelayTolerance();
|
||||
|
|
|
|||
|
|
@ -41,11 +41,11 @@ public:
|
|||
// Return values.
|
||||
ArcDelay &gate_delay,
|
||||
Slew &drvr_slew) const override;
|
||||
string reportGateDelay(const Pvt *pvt,
|
||||
float in_slew,
|
||||
float load_cap,
|
||||
bool pocv_enabled,
|
||||
int digits) const override;
|
||||
std::string reportGateDelay(const Pvt *pvt,
|
||||
float in_slew,
|
||||
float load_cap,
|
||||
bool pocv_enabled,
|
||||
int digits) const override;
|
||||
float driveResistance(const Pvt *pvt) const override;
|
||||
|
||||
protected:
|
||||
|
|
@ -65,13 +65,13 @@ public:
|
|||
float to_slew,
|
||||
float related_out_cap,
|
||||
bool pocv_enabled) const override;
|
||||
string reportCheckDelay(const Pvt *pvt,
|
||||
float from_slew,
|
||||
const char *from_slew_annotation,
|
||||
float to_slew,
|
||||
float related_out_cap,
|
||||
bool pocv_enabled,
|
||||
int digits) const override;
|
||||
std::string reportCheckDelay(const Pvt *pvt,
|
||||
float from_slew,
|
||||
const char *from_slew_annotation,
|
||||
float to_slew,
|
||||
float related_out_cap,
|
||||
bool pocv_enabled,
|
||||
int digits) const override;
|
||||
|
||||
protected:
|
||||
void setIsScaled(bool is_scaled) override;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
namespace sta {
|
||||
|
||||
// Add convenience functions around STL container.
|
||||
template <class KEY, class VALUE, class CMP = std::less<KEY> >
|
||||
template <class KEY, class VALUE, class CMP = std::less<KEY>>
|
||||
class Map : public std::map<KEY, VALUE, CMP>
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -153,6 +153,7 @@ public:
|
|||
// Attributes can be null
|
||||
virtual std::string getAttribute(const Cell *cell,
|
||||
const std::string &key) const = 0;
|
||||
virtual const AttributeMap &attributeMap(const Cell *cell) const = 0;
|
||||
// Name can be a simple, bundle, bus, or bus bit name.
|
||||
virtual Port *findPort(const Cell *cell,
|
||||
const char *name) const = 0;
|
||||
|
|
@ -217,6 +218,7 @@ public:
|
|||
const PatternMatch *pattern) const;
|
||||
virtual std::string getAttribute(const Instance *inst,
|
||||
const std::string &key) const = 0;
|
||||
virtual const AttributeMap &attributeMap(const Instance *inst) const = 0;
|
||||
// Hierarchical path name.
|
||||
virtual const char *pathName(const Instance *instance) const;
|
||||
bool pathNameLess(const Instance *inst1,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "Set.hh"
|
||||
#include "Vector.hh"
|
||||
|
|
@ -70,6 +72,7 @@ typedef Iterator<const Pin*> ConnectedPinIterator;
|
|||
typedef ConnectedPinIterator NetConnectedPinIterator;
|
||||
typedef ConnectedPinIterator PinConnectedPinIterator;
|
||||
typedef uint32_t ObjectId;
|
||||
typedef std::map<std::string, std::string> AttributeMap;
|
||||
|
||||
enum class LogicValue : unsigned { zero, one, unknown, rise, fall };
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "LibertyClass.hh"
|
||||
|
|
@ -35,6 +36,136 @@
|
|||
namespace sta {
|
||||
|
||||
class Sta;
|
||||
class PropertyValue;
|
||||
|
||||
template<class TYPE>
|
||||
class PropertyRegistry
|
||||
{
|
||||
public:
|
||||
PropertyValue getProperty(TYPE inst,
|
||||
const std::string property);
|
||||
void setProperty(TYPE inst,
|
||||
const std::string property,
|
||||
PropertyValue value);
|
||||
|
||||
private:
|
||||
std::map<std::pair<TYPE, const std::string>, PropertyValue> registry_;
|
||||
};
|
||||
|
||||
class Properties
|
||||
{
|
||||
public:
|
||||
Properties(Sta *sta);
|
||||
|
||||
PropertyValue getProperty(const Library *lib,
|
||||
const std::string property);
|
||||
void setProperty(const Library *lib,
|
||||
const std::string property,
|
||||
PropertyValue value);
|
||||
PropertyValue getProperty(const LibertyLibrary *lib,
|
||||
const std::string property);
|
||||
void setProperty(const LibertyLibrary *lib,
|
||||
const std::string property,
|
||||
PropertyValue value);
|
||||
PropertyValue getProperty(const Cell *cell,
|
||||
const std::string property);
|
||||
void setProperty(const Cell *cell,
|
||||
const std::string property,
|
||||
PropertyValue value);
|
||||
PropertyValue getProperty(const LibertyCell *cell,
|
||||
const std::string property);
|
||||
void setProperty(const LibertyCell *cell,
|
||||
const std::string property,
|
||||
PropertyValue value);
|
||||
PropertyValue getProperty(const Port *port,
|
||||
const std::string property);
|
||||
void setProperty(const Port *port,
|
||||
const std::string property,
|
||||
PropertyValue value);
|
||||
PropertyValue getProperty(const LibertyPort *port,
|
||||
const std::string property);
|
||||
void setProperty(const LibertyPort *port,
|
||||
const std::string property,
|
||||
PropertyValue value);
|
||||
PropertyValue getProperty(const Instance *inst,
|
||||
const std::string property);
|
||||
void setProperty(const Instance *inst,
|
||||
const std::string property,
|
||||
PropertyValue value);
|
||||
PropertyValue getProperty(const Pin *pin,
|
||||
const std::string property);
|
||||
void setProperty(const Pin *pin,
|
||||
const std::string property,
|
||||
PropertyValue value);
|
||||
PropertyValue getProperty(const Net *net,
|
||||
const std::string property);
|
||||
void setProperty(const Net *net,
|
||||
const std::string property,
|
||||
PropertyValue value);
|
||||
PropertyValue getProperty(Edge *edge,
|
||||
const std::string property);
|
||||
void setProperty(Edge *edge,
|
||||
const std::string property,
|
||||
PropertyValue value);
|
||||
PropertyValue getProperty(const Clock *clk,
|
||||
const std::string property);
|
||||
void setProperty(const Clock *clk,
|
||||
const std::string property,
|
||||
PropertyValue value);
|
||||
PropertyValue getProperty(PathEnd *end,
|
||||
const std::string property);
|
||||
PropertyValue getProperty(Path *path,
|
||||
const std::string property);
|
||||
PropertyValue getProperty(TimingArcSet *arc_set,
|
||||
const std::string property);
|
||||
|
||||
private:
|
||||
PropertyValue portSlew(const Port *port,
|
||||
const MinMax *min_max);
|
||||
PropertyValue portSlew(const Port *port,
|
||||
const RiseFall *rf,
|
||||
const MinMax *min_max);
|
||||
PropertyValue portSlack(const Port *port,
|
||||
const MinMax *min_max);
|
||||
PropertyValue portSlack(const Port *port,
|
||||
const RiseFall *rf,
|
||||
const MinMax *min_max);
|
||||
PropertyValue pinArrival(const Pin *pin,
|
||||
const RiseFall *rf,
|
||||
const MinMax *min_max);
|
||||
|
||||
PropertyValue pinSlack(const Pin *pin,
|
||||
const MinMax *min_max);
|
||||
PropertyValue pinSlack(const Pin *pin,
|
||||
const RiseFall *rf,
|
||||
const MinMax *min_max);
|
||||
PropertyValue pinSlew(const Pin *pin,
|
||||
const MinMax *min_max);
|
||||
PropertyValue pinSlew(const Pin *pin,
|
||||
const RiseFall *rf,
|
||||
const MinMax *min_max);
|
||||
|
||||
PropertyValue delayPropertyValue(Delay delay);
|
||||
PropertyValue resistancePropertyValue(float res);
|
||||
PropertyValue capacitancePropertyValue(float cap);
|
||||
PropertyValue edgeDelay(Edge *edge,
|
||||
const RiseFall *rf,
|
||||
const MinMax *min_max);
|
||||
|
||||
// set_property user definied properties.
|
||||
PropertyRegistry<const Library*> registry_lib_;
|
||||
PropertyRegistry<const LibertyLibrary*> registry_liberty_lib_;
|
||||
PropertyRegistry<const Cell*> registry_cell_;
|
||||
PropertyRegistry<const LibertyCell*> registry_liberty_cell_;
|
||||
PropertyRegistry<const Port*> registry_port_;
|
||||
PropertyRegistry<const LibertyPort*> registry_liberty_port_;
|
||||
PropertyRegistry<const Instance*> registry_inst_;
|
||||
PropertyRegistry<const Pin*> registry_pin_;
|
||||
PropertyRegistry<const Net*> registry_net_;
|
||||
PropertyRegistry<const Edge*> registry_edge_;
|
||||
PropertyRegistry<const Clock*> registry_clk_;
|
||||
Sta *sta_;
|
||||
};
|
||||
|
||||
// Adding a new property type
|
||||
// value union
|
||||
|
|
@ -133,74 +264,4 @@ private:
|
|||
const Unit *unit_;
|
||||
};
|
||||
|
||||
PropertyValue
|
||||
getProperty(const Instance *inst,
|
||||
const char *property,
|
||||
Sta *sta);
|
||||
|
||||
PropertyValue
|
||||
getProperty(const Pin *pin,
|
||||
const char *property,
|
||||
Sta *sta);
|
||||
|
||||
PropertyValue
|
||||
getProperty(const Net *net,
|
||||
const char *property,
|
||||
Sta *sta);
|
||||
|
||||
PropertyValue
|
||||
getProperty(const Port *port,
|
||||
const char *property,
|
||||
Sta *sta);
|
||||
|
||||
PropertyValue
|
||||
getProperty(const Cell *cell,
|
||||
const char *property,
|
||||
Sta *sta);
|
||||
|
||||
PropertyValue
|
||||
getProperty(const LibertyCell *cell,
|
||||
const char *property,
|
||||
Sta *sta);
|
||||
|
||||
PropertyValue
|
||||
getProperty(const LibertyPort *port,
|
||||
const char *property,
|
||||
Sta *);
|
||||
|
||||
PropertyValue
|
||||
getProperty(const LibertyLibrary *lib,
|
||||
const char *property,
|
||||
Sta *sta);
|
||||
|
||||
PropertyValue
|
||||
getProperty(const Library *lib,
|
||||
const char *property,
|
||||
Sta *sta);
|
||||
|
||||
PropertyValue
|
||||
getProperty(Edge *edge,
|
||||
const char *property,
|
||||
Sta *sta);
|
||||
|
||||
PropertyValue
|
||||
getProperty(Clock *clk,
|
||||
const char *property,
|
||||
Sta *sta);
|
||||
|
||||
PropertyValue
|
||||
getProperty(PathEnd *end,
|
||||
const char *property,
|
||||
Sta *sta);
|
||||
|
||||
PropertyValue
|
||||
getProperty(Path *end,
|
||||
const char *property,
|
||||
Sta *sta);
|
||||
|
||||
PropertyValue
|
||||
getProperty(TimingArcSet *arc_set,
|
||||
const char *property,
|
||||
Sta *sta);
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -216,6 +216,7 @@ public:
|
|||
// Build data structures for search.
|
||||
void searchPreamble();
|
||||
void deleteNetBefore(const Net *net);
|
||||
void deleteInstanceBefore(const Instance *inst);
|
||||
|
||||
// SWIG sdc interface.
|
||||
PortSeq allInputs(bool no_clks);
|
||||
|
|
@ -744,6 +745,7 @@ public:
|
|||
ExceptionTo *to,
|
||||
const MinMax *min_max,
|
||||
bool ignore_clk_latency,
|
||||
bool break_path,
|
||||
float delay,
|
||||
const char *comment);
|
||||
bool pathDelaysWithoutTo() const { return path_delays_without_to_; }
|
||||
|
|
@ -1003,9 +1005,11 @@ public:
|
|||
const Pin *pin,
|
||||
const RiseFall *rf,
|
||||
const MinMax *min_max) const;
|
||||
bool isPathDelayInternalStartpoint(const Pin *pin) const;
|
||||
const PinSet &pathDelayInternalStartpoints() const;
|
||||
bool isPathDelayInternalEndpoint(const Pin *pin) const;
|
||||
bool isPathDelayInternalFrom(const Pin *pin) const;
|
||||
bool isPathDelayInternalFromBreak(const Pin *pin) const;
|
||||
const PinSet &pathDelayInternalFrom() const;
|
||||
bool isPathDelayInternalTo(const Pin *pin) const;
|
||||
bool isPathDelayInternalToBreak(const Pin *pin) const;
|
||||
ExceptionPathSet *exceptions() { return &exceptions_; }
|
||||
void deleteExceptions();
|
||||
void deleteException(ExceptionPath *exception);
|
||||
|
|
@ -1042,11 +1046,11 @@ protected:
|
|||
ExceptionPath *findMergeMatch(ExceptionPath *exception);
|
||||
void addException1(ExceptionPath *exception);
|
||||
void addException2(ExceptionPath *exception);
|
||||
void recordPathDelayInternalStartpoints(ExceptionPath *exception);
|
||||
void unrecordPathDelayInternalStartpoints(ExceptionFrom *from);
|
||||
void recordPathDelayInternalFrom(ExceptionPath *exception);
|
||||
void unrecordPathDelayInternalFrom(ExceptionPath *exception);
|
||||
bool pathDelayFrom(const Pin *pin);
|
||||
void recordPathDelayInternalEndpoints(ExceptionPath *exception);
|
||||
void unrecordPathDelayInternalEndpoints(ExceptionPath *exception);
|
||||
void recordPathDelayInternalTo(ExceptionPath *exception);
|
||||
void unrecordPathDelayInternalTo(ExceptionPath *exception);
|
||||
bool pathDelayTo(const Pin *pin);
|
||||
bool hasLibertyCheckTo(const Pin *pin);
|
||||
void deleteMatchingExceptions(ExceptionPath *exception);
|
||||
|
|
@ -1355,9 +1359,13 @@ protected:
|
|||
// Exception hash with one missing from/thru/to point, used for merging.
|
||||
ExceptionPathPtHash exception_merge_hash_;
|
||||
// Path delay -from pin internal startpoints.
|
||||
PinSet path_delay_internal_startpoints_;
|
||||
// Path delay -to pin internal endpoints.
|
||||
PinSet path_delay_internal_endpoints_;
|
||||
PinSet path_delay_internal_from_;
|
||||
// Path delay -from pin internal -from w/o -probe.
|
||||
PinSet path_delay_internal_from_break_;
|
||||
// Path delay -to pin internal -to.
|
||||
PinSet path_delay_internal_to_;
|
||||
// Path delay -to pin internal -to w/o -probe.
|
||||
PinSet path_delay_internal_to_break_;
|
||||
// There is a path delay exception without a -to.
|
||||
bool path_delays_without_to_;
|
||||
// Group path exception names.
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ public:
|
|||
const char *name(const Cell *cell) const override;
|
||||
std::string getAttribute(const Cell *cell,
|
||||
const std::string &key) const override;
|
||||
const AttributeMap &attributeMap(const Cell *cell) const override;
|
||||
ObjectId id(const Cell *cell) const override;
|
||||
Library *library(const Cell *cell) const override;
|
||||
LibertyCell *libertyCell(Cell *cell) const override;
|
||||
|
|
@ -93,6 +94,7 @@ public:
|
|||
ObjectId id(const Instance *instance) const override;
|
||||
std::string getAttribute(const Instance *inst,
|
||||
const std::string &key) const override;
|
||||
const AttributeMap &attributeMap(const Instance *inst) const override;
|
||||
Instance *topInstance() const override;
|
||||
Cell *cell(const Instance *instance) const override;
|
||||
Instance *parent(const Instance *instance) const override;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include "ArcDelayCalc.hh"
|
||||
#include "CircuitSim.hh"
|
||||
#include "Variables.hh"
|
||||
#include "Property.hh"
|
||||
|
||||
struct Tcl_Interp;
|
||||
|
||||
|
|
@ -508,6 +509,7 @@ public:
|
|||
ExceptionTo *to,
|
||||
const MinMax *min_max,
|
||||
bool ignore_clk_latency,
|
||||
bool break_path,
|
||||
float delay,
|
||||
const char *comment);
|
||||
void makeGroupPath(const char *name,
|
||||
|
|
@ -906,11 +908,11 @@ public:
|
|||
PinSet findGroupPathPins(const char *group_path_name);
|
||||
// Find all required times after updateTiming().
|
||||
void findRequireds();
|
||||
string reportDelayCalc(Edge *edge,
|
||||
TimingArc *arc,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
int digits);
|
||||
std::string reportDelayCalc(Edge *edge,
|
||||
TimingArc *arc,
|
||||
const Corner *corner,
|
||||
const MinMax *min_max,
|
||||
int digits);
|
||||
void writeSdc(const char *filename,
|
||||
// Map hierarchical pins and instances to leaf pins and instances.
|
||||
bool leaf,
|
||||
|
|
@ -1326,6 +1328,8 @@ public:
|
|||
void setUseDefaultArrivalClock(bool enable);
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
Properties &properties() { return properties_; }
|
||||
|
||||
protected:
|
||||
// Default constructors that are called by makeComponents in the Sta
|
||||
// constructor. These can be redefined by a derived class to
|
||||
|
|
@ -1469,6 +1473,7 @@ protected:
|
|||
bool graph_sdc_annotated_;
|
||||
bool parasitics_per_corner_;
|
||||
bool parasitics_per_min_max_;
|
||||
Properties properties_;
|
||||
|
||||
// Singleton sta used by tcl command interpreter.
|
||||
static Sta *sta_;
|
||||
|
|
|
|||
|
|
@ -82,11 +82,11 @@ public:
|
|||
bool pocv_enabled,
|
||||
ArcDelay &gate_delay,
|
||||
Slew &drvr_slew) const __attribute__ ((deprecated));
|
||||
string reportGateDelay(const Pvt *pvt,
|
||||
float in_slew,
|
||||
float load_cap,
|
||||
bool pocv_enabled,
|
||||
int digits) const override;
|
||||
std::string reportGateDelay(const Pvt *pvt,
|
||||
float in_slew,
|
||||
float load_cap,
|
||||
bool pocv_enabled,
|
||||
int digits) const override;
|
||||
float driveResistance(const Pvt *pvt) const override;
|
||||
|
||||
const TableModel *delayModel() const { return delay_model_; }
|
||||
|
|
@ -112,13 +112,13 @@ protected:
|
|||
float in_slew,
|
||||
float load_cap,
|
||||
float related_out_cap) const;
|
||||
string reportTableLookup(const char *result_name,
|
||||
const Pvt *pvt,
|
||||
const TableModel *model,
|
||||
float in_slew,
|
||||
float load_cap,
|
||||
float related_out_cap,
|
||||
int digits) const;
|
||||
std::string reportTableLookup(const char *result_name,
|
||||
const Pvt *pvt,
|
||||
const TableModel *model,
|
||||
float in_slew,
|
||||
float load_cap,
|
||||
float related_out_cap,
|
||||
int digits) const;
|
||||
void findAxisValues(const TableModel *model,
|
||||
float in_slew,
|
||||
float load_cap,
|
||||
|
|
@ -149,13 +149,13 @@ public:
|
|||
float to_slew,
|
||||
float related_out_cap,
|
||||
bool pocv_enabled) const override;
|
||||
string reportCheckDelay(const Pvt *pvt,
|
||||
float from_slew,
|
||||
const char *from_slew_annotation,
|
||||
float to_slew,
|
||||
float related_out_cap,
|
||||
bool pocv_enabled,
|
||||
int digits) const override;
|
||||
std::string reportCheckDelay(const Pvt *pvt,
|
||||
float from_slew,
|
||||
const char *from_slew_annotation,
|
||||
float to_slew,
|
||||
float related_out_cap,
|
||||
bool pocv_enabled,
|
||||
int digits) const override;
|
||||
const TableModel *model() const { return model_; }
|
||||
|
||||
// Check the axes before making the model.
|
||||
|
|
@ -180,14 +180,14 @@ protected:
|
|||
float load_cap,
|
||||
float in_slew,
|
||||
float related_out_cap) const;
|
||||
string reportTableDelay(const char *result_name,
|
||||
const Pvt *pvt,
|
||||
const TableModel *model,
|
||||
float from_slew,
|
||||
const char *from_slew_annotation,
|
||||
float to_slew,
|
||||
float related_out_cap,
|
||||
int digits) const;
|
||||
std::string reportTableDelay(const char *result_name,
|
||||
const Pvt *pvt,
|
||||
const TableModel *model,
|
||||
float from_slew,
|
||||
const char *from_slew_annotation,
|
||||
float to_slew,
|
||||
float related_out_cap,
|
||||
int digits) const;
|
||||
static bool checkAxis(const TableAxis *axis);
|
||||
|
||||
TableModel *model_;
|
||||
|
|
@ -222,24 +222,24 @@ public:
|
|||
float value1,
|
||||
float value2,
|
||||
float value3) const;
|
||||
string reportValue(const char *result_name,
|
||||
const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
float value1,
|
||||
const char *comment1,
|
||||
float value2,
|
||||
float value3,
|
||||
const Unit *table_unit,
|
||||
int digits) const;
|
||||
string report(const Units *units,
|
||||
Report *report) const;
|
||||
std::string reportValue(const char *result_name,
|
||||
const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
float value1,
|
||||
const char *comment1,
|
||||
float value2,
|
||||
float value3,
|
||||
const Unit *table_unit,
|
||||
int digits) const;
|
||||
std::string report(const Units *units,
|
||||
Report *report) const;
|
||||
|
||||
protected:
|
||||
float scaleFactor(const LibertyCell *cell,
|
||||
const Pvt *pvt) const;
|
||||
string reportPvtScaleFactor(const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
int digits) const;
|
||||
std::string reportPvtScaleFactor(const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
int digits) const;
|
||||
|
||||
TablePtr table_;
|
||||
TableTemplate *tbl_template_;
|
||||
|
|
@ -275,15 +275,15 @@ public:
|
|||
float axis_value1,
|
||||
float axis_value2,
|
||||
float axis_value3) const;
|
||||
virtual string reportValue(const char *result_name,
|
||||
const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
float value1,
|
||||
const char *comment1,
|
||||
float value2,
|
||||
float value3,
|
||||
const Unit *table_unit,
|
||||
int digits) const = 0;
|
||||
virtual std::string reportValue(const char *result_name,
|
||||
const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
float value1,
|
||||
const char *comment1,
|
||||
float value2,
|
||||
float value3,
|
||||
const Unit *table_unit,
|
||||
int digits) const = 0;
|
||||
virtual void report(const Units *units,
|
||||
Report *report) const = 0;
|
||||
};
|
||||
|
|
@ -300,15 +300,15 @@ public:
|
|||
float findValue(float axis_value1,
|
||||
float axis_value2,
|
||||
float axis_value3) const override;
|
||||
string reportValue(const char *result_name,
|
||||
const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
float value1,
|
||||
const char *comment1,
|
||||
float value2,
|
||||
float value3,
|
||||
const Unit *table_unit,
|
||||
int digits) const override;
|
||||
std::string reportValue(const char *result_name,
|
||||
const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
float value1,
|
||||
const char *comment1,
|
||||
float value2,
|
||||
float value3,
|
||||
const Unit *table_unit,
|
||||
int digits) const override;
|
||||
void report(const Units *units,
|
||||
Report *report) const override;
|
||||
using Table::findValue;
|
||||
|
|
@ -337,15 +337,15 @@ public:
|
|||
float findValue(float value1,
|
||||
float value2,
|
||||
float value3) const override;
|
||||
string reportValue(const char *result_name,
|
||||
const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
float value1,
|
||||
const char *comment1,
|
||||
float value2,
|
||||
float value3,
|
||||
const Unit *table_unit,
|
||||
int digits) const override;
|
||||
std::string reportValue(const char *result_name,
|
||||
const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
float value1,
|
||||
const char *comment1,
|
||||
float value2,
|
||||
float value3,
|
||||
const Unit *table_unit,
|
||||
int digits) const override;
|
||||
void report(const Units *units,
|
||||
Report *report) const override;
|
||||
|
||||
|
|
@ -382,15 +382,15 @@ public:
|
|||
float findValue(float value1,
|
||||
float value2,
|
||||
float value3) const override;
|
||||
string reportValue(const char *result_name,
|
||||
const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
float value1,
|
||||
const char *comment1,
|
||||
float value2,
|
||||
float value3,
|
||||
const Unit *table_unit,
|
||||
int digits) const override;
|
||||
std::string reportValue(const char *result_name,
|
||||
const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
float value1,
|
||||
const char *comment1,
|
||||
float value2,
|
||||
float value3,
|
||||
const Unit *table_unit,
|
||||
int digits) const override;
|
||||
void report(const Units *units,
|
||||
Report *report) const override;
|
||||
|
||||
|
|
@ -428,15 +428,15 @@ public:
|
|||
float findValue(float value1,
|
||||
float value2,
|
||||
float value3) const override;
|
||||
string reportValue(const char *result_name,
|
||||
const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
float value1,
|
||||
const char *comment1,
|
||||
float value2,
|
||||
float value3,
|
||||
const Unit *table_unit,
|
||||
int digits) const override;
|
||||
std::string reportValue(const char *result_name,
|
||||
const LibertyCell *cell,
|
||||
const Pvt *pvt,
|
||||
float value1,
|
||||
const char *comment1,
|
||||
float value2,
|
||||
float value3,
|
||||
const Unit *table_unit,
|
||||
int digits) const override;
|
||||
void report(const Units *units,
|
||||
Report *report) const override;
|
||||
using Table::findValue;
|
||||
|
|
@ -574,13 +574,13 @@ private:
|
|||
class DriverWaveform
|
||||
{
|
||||
public:
|
||||
DriverWaveform(const string &name,
|
||||
DriverWaveform(const std::string &name,
|
||||
TablePtr waveforms);
|
||||
const char *name() const { return name_.c_str(); }
|
||||
Table1 waveform(float slew);
|
||||
|
||||
private:
|
||||
string name_;
|
||||
std::string name_;
|
||||
TablePtr waveforms_;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -31,8 +31,6 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
|
||||
// Abstract base class for GateTimingModel and CheckTimingModel.
|
||||
class TimingModel
|
||||
{
|
||||
|
|
@ -58,11 +56,11 @@ public:
|
|||
// Return values.
|
||||
ArcDelay &gate_delay,
|
||||
Slew &drvr_slew) const = 0;
|
||||
virtual string reportGateDelay(const Pvt *pvt,
|
||||
float in_slew,
|
||||
float load_cap,
|
||||
bool pocv_enabled,
|
||||
int digits) const = 0;
|
||||
virtual std::string reportGateDelay(const Pvt *pvt,
|
||||
float in_slew,
|
||||
float load_cap,
|
||||
bool pocv_enabled,
|
||||
int digits) const = 0;
|
||||
virtual float driveResistance(const Pvt *pvt) const = 0;
|
||||
};
|
||||
|
||||
|
|
@ -77,13 +75,13 @@ public:
|
|||
float to_slew,
|
||||
float related_out_cap,
|
||||
bool pocv_enabled) const = 0;
|
||||
virtual string reportCheckDelay(const Pvt *pvt,
|
||||
float from_slew,
|
||||
const char *from_slew_annotation,
|
||||
float to_slew,
|
||||
float related_out_cap,
|
||||
bool pocv_enabled,
|
||||
int digits) const = 0;
|
||||
virtual std::string reportCheckDelay(const Pvt *pvt,
|
||||
float from_slew,
|
||||
const char *from_slew_annotation,
|
||||
float to_slew,
|
||||
float related_out_cap,
|
||||
bool pocv_enabled,
|
||||
int digits) const = 0;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
namespace sta {
|
||||
|
||||
// Add convenience functions around STL container.
|
||||
template <class KEY, class VALUE, class HASH = std::hash<KEY>, class EQUAL = std::equal_to<KEY> >
|
||||
template <class KEY, class VALUE, class HASH = std::hash<KEY>, class EQUAL = std::equal_to<KEY>>
|
||||
class UnorderedMap : public std::unordered_map<KEY, VALUE, HASH, EQUAL>
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
|
||||
InternalPowerAttrs::InternalPowerAttrs() :
|
||||
when_(nullptr),
|
||||
models_{nullptr, nullptr},
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
|
||||
typedef Set<LatchEnable*> LatchEnableSet;
|
||||
|
||||
void
|
||||
|
|
@ -134,6 +136,9 @@ LibertyLibrary::~LibertyLibrary()
|
|||
delete inverters_;
|
||||
driver_waveform_map_.deleteContents();
|
||||
delete driver_waveform_default_;
|
||||
|
||||
delete default_ocv_derate_;
|
||||
default_ocv_derate_ = nullptr;
|
||||
}
|
||||
|
||||
LibertyCell *
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
|
||||
void
|
||||
LibertyBuilder::init(Debug *debug,
|
||||
Report *report)
|
||||
|
|
|
|||
|
|
@ -62,8 +62,8 @@ class OutputWaveform;
|
|||
|
||||
typedef void (LibertyReader::*LibraryAttrVisitor)(LibertyAttr *attr);
|
||||
typedef void (LibertyReader::*LibraryGroupVisitor)(LibertyGroup *group);
|
||||
typedef Map<string, LibraryAttrVisitor> LibraryAttrMap;
|
||||
typedef Map<string ,LibraryGroupVisitor> LibraryGroupMap;
|
||||
typedef Map<std::string, LibraryAttrVisitor> LibraryAttrMap;
|
||||
typedef Map<std::string ,LibraryGroupVisitor> LibraryGroupMap;
|
||||
typedef Vector<PortGroup*> PortGroupSeq;
|
||||
typedef Vector<SequentialGroup*> SequentialGroupSeq;
|
||||
typedef Vector<LibertyFunc*> LibertyFuncSeq;
|
||||
|
|
@ -674,7 +674,7 @@ protected:
|
|||
OutputWaveforms *output_waveforms_;
|
||||
float reference_time_;
|
||||
bool reference_time_exists_;
|
||||
string driver_waveform_name_;
|
||||
std::string driver_waveform_name_;
|
||||
|
||||
TestCell *test_cell_;
|
||||
// Saved state while parsing test_cell.
|
||||
|
|
@ -934,7 +934,7 @@ protected:
|
|||
LibertyPort *port_;
|
||||
LibertyPortMemberIterator *bit_iterator_;
|
||||
LibertyPort *range_bus_port_;
|
||||
string range_bus_name_;
|
||||
std::string range_bus_name_;
|
||||
LibertyPort *range_name_next_;
|
||||
int range_from_;
|
||||
int range_to_;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
|
||||
GateLinearModel::GateLinearModel(LibertyCell *cell,
|
||||
float intrinsic,
|
||||
float resistance) :
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
using std::make_shared;
|
||||
|
||||
static bool
|
||||
|
|
|
|||
|
|
@ -624,6 +624,13 @@ ConcreteNetwork::getAttribute(const Cell *cell,
|
|||
return ccell->getAttribute(key);
|
||||
}
|
||||
|
||||
const AttributeMap &
|
||||
ConcreteNetwork::attributeMap(const Cell *cell) const
|
||||
{
|
||||
const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
|
||||
return ccell->attributeMap();
|
||||
}
|
||||
|
||||
Port *
|
||||
ConcreteNetwork::findPort(const Cell *cell,
|
||||
const char *name) const
|
||||
|
|
@ -956,6 +963,13 @@ ConcreteNetwork::getAttribute(const Instance *inst,
|
|||
return cinst->getAttribute(key);
|
||||
}
|
||||
|
||||
const AttributeMap &
|
||||
ConcreteNetwork::attributeMap(const Instance *inst) const
|
||||
{
|
||||
const ConcreteInstance *cinst = reinterpret_cast<const ConcreteInstance*>(inst);
|
||||
return cinst->attributeMap();
|
||||
}
|
||||
|
||||
Cell *
|
||||
ConcreteNetwork::cell(const Instance *instance) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -144,6 +144,12 @@ NetworkNameAdapter::getAttribute(const Cell *cell,
|
|||
return network_->getAttribute(cell, key);
|
||||
}
|
||||
|
||||
const AttributeMap &
|
||||
NetworkNameAdapter::attributeMap(const Cell *cell) const
|
||||
{
|
||||
return network_->attributeMap(cell);
|
||||
}
|
||||
|
||||
Library *
|
||||
NetworkNameAdapter::library(const Cell *cell) const
|
||||
{
|
||||
|
|
@ -356,6 +362,12 @@ NetworkNameAdapter::getAttribute(const Instance *inst,
|
|||
return network_->getAttribute(inst, key);
|
||||
}
|
||||
|
||||
const AttributeMap &
|
||||
NetworkNameAdapter::attributeMap(const Instance *inst) const
|
||||
{
|
||||
return network_->attributeMap(inst);
|
||||
}
|
||||
|
||||
Instance *
|
||||
NetworkNameAdapter::parent(const Instance *instance) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
|
||||
bool
|
||||
readSpefFile(const char *filename,
|
||||
Instance *instance,
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
using std::min;
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
using std::abs;
|
||||
using std::min;
|
||||
using std::to_string;
|
||||
|
|
|
|||
|
|
@ -458,6 +458,20 @@ thrusIntersectPts(ExceptionThruSeq *thrus1,
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ExceptionPath::deleteInstance(const Instance *inst,
|
||||
const Network *network)
|
||||
{
|
||||
if (from_)
|
||||
from_->deleteInstance(inst, network);
|
||||
if (thrus_) {
|
||||
for (ExceptionThru *thru : *thrus_)
|
||||
thru->deleteInstance(inst, network);
|
||||
}
|
||||
if (to_)
|
||||
to_->deleteInstance(inst, network);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
PathDelay::PathDelay(ExceptionFrom *from,
|
||||
|
|
@ -465,6 +479,7 @@ PathDelay::PathDelay(ExceptionFrom *from,
|
|||
ExceptionTo *to,
|
||||
const MinMax *min_max,
|
||||
bool ignore_clk_latency,
|
||||
bool break_path,
|
||||
float delay,
|
||||
bool own_pts,
|
||||
const char *comment) :
|
||||
|
|
@ -472,6 +487,7 @@ PathDelay::PathDelay(ExceptionFrom *from,
|
|||
pathDelayPriority() + fromThruToPriority(from, thrus, to),
|
||||
comment),
|
||||
ignore_clk_latency_(ignore_clk_latency),
|
||||
break_path_(break_path),
|
||||
delay_(delay)
|
||||
{
|
||||
}
|
||||
|
|
@ -483,8 +499,8 @@ PathDelay::clone(ExceptionFrom *from,
|
|||
bool own_pts)
|
||||
{
|
||||
return new PathDelay(from, thrus, to, min_max_->asMinMax(),
|
||||
ignore_clk_latency_, delay_, own_pts,
|
||||
comment_);
|
||||
ignore_clk_latency_, break_path_, delay_,
|
||||
own_pts, comment_);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
|||
103
sdc/Sdc.cc
103
sdc/Sdc.cc
|
|
@ -122,8 +122,10 @@ Sdc::Sdc(StaState *sta) :
|
|||
exception_id_(0),
|
||||
have_thru_hpin_exceptions_(false),
|
||||
first_thru_edge_exceptions_(0, PinPairHash(network_), PinPairEqual()),
|
||||
path_delay_internal_startpoints_(network_),
|
||||
path_delay_internal_endpoints_(network_)
|
||||
path_delay_internal_from_(network_),
|
||||
path_delay_internal_from_break_(network_),
|
||||
path_delay_internal_to_(network_),
|
||||
path_delay_internal_to_break_(network_)
|
||||
{
|
||||
sdc_ = this;
|
||||
initVariables();
|
||||
|
|
@ -361,6 +363,25 @@ Sdc::deleteNetBefore(const Net *net)
|
|||
}
|
||||
}
|
||||
|
||||
// see Sdc::isConstrained
|
||||
void
|
||||
Sdc::deleteInstanceBefore(const Instance *inst)
|
||||
{
|
||||
instance_pvt_maps_[MinMax::minIndex()].erase(inst);
|
||||
instance_pvt_maps_[MinMax::maxIndex()].erase(inst);
|
||||
inst_derating_factors_.erase(inst);
|
||||
inst_clk_gating_check_map_.erase(inst);
|
||||
disabled_inst_ports_.erase(inst);
|
||||
inst_latch_borrow_limit_map_.erase(inst);
|
||||
inst_min_pulse_width_map_.erase(inst);
|
||||
|
||||
for (ExceptionPath *exception : exceptions_)
|
||||
exception->deleteInstance(inst, network_);
|
||||
first_from_inst_exceptions_.erase(inst);
|
||||
first_thru_inst_exceptions_.erase(inst);
|
||||
first_to_inst_exceptions_.erase(inst);
|
||||
}
|
||||
|
||||
void
|
||||
Sdc::makeCornersBefore()
|
||||
{
|
||||
|
|
@ -3875,18 +3896,19 @@ Sdc::makePathDelay(ExceptionFrom *from,
|
|||
ExceptionTo *to,
|
||||
const MinMax *min_max,
|
||||
bool ignore_clk_latency,
|
||||
bool break_path,
|
||||
float delay,
|
||||
const char *comment)
|
||||
{
|
||||
checkFromThrusTo(from, thrus, to);
|
||||
PathDelay *exception = new PathDelay(from, thrus, to, min_max,
|
||||
ignore_clk_latency, delay, true,
|
||||
comment);
|
||||
ignore_clk_latency, break_path,
|
||||
delay, true, comment);
|
||||
addException(exception);
|
||||
}
|
||||
|
||||
void
|
||||
Sdc::recordPathDelayInternalStartpoints(ExceptionPath *exception)
|
||||
Sdc::recordPathDelayInternalFrom(ExceptionPath *exception)
|
||||
{
|
||||
ExceptionFrom *from = exception->from();
|
||||
if (from
|
||||
|
|
@ -3894,23 +3916,29 @@ Sdc::recordPathDelayInternalStartpoints(ExceptionPath *exception)
|
|||
for (const Pin *pin : *from->pins()) {
|
||||
if (!(network_->isRegClkPin(pin)
|
||||
|| network_->isTopLevelPort(pin))) {
|
||||
path_delay_internal_startpoints_.insert(pin);
|
||||
path_delay_internal_from_.insert(pin);
|
||||
if (exception->breakPath())
|
||||
path_delay_internal_from_break_.insert(pin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Sdc::unrecordPathDelayInternalStartpoints(ExceptionFrom *from)
|
||||
Sdc::unrecordPathDelayInternalFrom(ExceptionPath *exception)
|
||||
{
|
||||
ExceptionFrom *from = exception->from();
|
||||
if (from
|
||||
&& from->hasPins()
|
||||
&& !path_delay_internal_startpoints_.empty()) {
|
||||
&& !path_delay_internal_from_.empty()) {
|
||||
for (const Pin *pin : *from->pins()) {
|
||||
if (!(network_->isRegClkPin(pin)
|
||||
|| network_->isTopLevelPort(pin))
|
||||
&& !pathDelayFrom(pin))
|
||||
path_delay_internal_startpoints_.erase(pin);
|
||||
&& !pathDelayFrom(pin)) {
|
||||
path_delay_internal_from_.erase(pin);
|
||||
if (exception->breakPath())
|
||||
path_delay_internal_from_break_.erase(pin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3927,19 +3955,25 @@ Sdc::pathDelayFrom(const Pin *pin)
|
|||
}
|
||||
|
||||
bool
|
||||
Sdc::isPathDelayInternalStartpoint(const Pin *pin) const
|
||||
Sdc::isPathDelayInternalFrom(const Pin *pin) const
|
||||
{
|
||||
return path_delay_internal_startpoints_.hasKey(pin);
|
||||
return path_delay_internal_from_.hasKey(pin);
|
||||
}
|
||||
|
||||
bool
|
||||
Sdc::isPathDelayInternalFromBreak(const Pin *pin) const
|
||||
{
|
||||
return path_delay_internal_from_break_.hasKey(pin);
|
||||
}
|
||||
|
||||
const PinSet &
|
||||
Sdc::pathDelayInternalStartpoints() const
|
||||
Sdc::pathDelayInternalFrom() const
|
||||
{
|
||||
return path_delay_internal_startpoints_;
|
||||
return path_delay_internal_from_;
|
||||
}
|
||||
|
||||
void
|
||||
Sdc::recordPathDelayInternalEndpoints(ExceptionPath *exception)
|
||||
Sdc::recordPathDelayInternalTo(ExceptionPath *exception)
|
||||
{
|
||||
ExceptionTo *to = exception->to();
|
||||
if (to
|
||||
|
|
@ -3947,24 +3981,29 @@ Sdc::recordPathDelayInternalEndpoints(ExceptionPath *exception)
|
|||
for (const Pin *pin : *to->pins()) {
|
||||
if (!(hasLibertyCheckTo(pin)
|
||||
|| network_->isTopLevelPort(pin))) {
|
||||
path_delay_internal_endpoints_.insert(pin);
|
||||
path_delay_internal_to_.insert(pin);
|
||||
if (exception->breakPath())
|
||||
path_delay_internal_to_break_.insert(pin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Sdc::unrecordPathDelayInternalEndpoints(ExceptionPath *exception)
|
||||
Sdc::unrecordPathDelayInternalTo(ExceptionPath *exception)
|
||||
{
|
||||
ExceptionTo *to = exception->to();
|
||||
if (to
|
||||
&& to->hasPins()
|
||||
&& !path_delay_internal_endpoints_.empty()) {
|
||||
&& !path_delay_internal_to_.empty()) {
|
||||
for (const Pin *pin : *to->pins()) {
|
||||
if (!(hasLibertyCheckTo(pin)
|
||||
|| network_->isTopLevelPort(pin))
|
||||
&& !pathDelayTo(pin))
|
||||
path_delay_internal_endpoints_.erase(pin);
|
||||
&& !pathDelayTo(pin)) {
|
||||
path_delay_internal_to_.erase(pin);
|
||||
if (exception->breakPath())
|
||||
path_delay_internal_to_break_.erase(pin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3998,9 +4037,15 @@ Sdc::pathDelayTo(const Pin *pin)
|
|||
}
|
||||
|
||||
bool
|
||||
Sdc::isPathDelayInternalEndpoint(const Pin *pin) const
|
||||
Sdc::isPathDelayInternalTo(const Pin *pin) const
|
||||
{
|
||||
return path_delay_internal_endpoints_.hasKey(pin);
|
||||
return path_delay_internal_to_.hasKey(pin);
|
||||
}
|
||||
|
||||
bool
|
||||
Sdc::isPathDelayInternalToBreak(const Pin *pin) const
|
||||
{
|
||||
return path_delay_internal_to_break_.hasKey(pin);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
@ -4168,8 +4213,8 @@ Sdc::addException(ExceptionPath *exception)
|
|||
exception->asString(network_));
|
||||
|
||||
if (exception->isPathDelay()) {
|
||||
recordPathDelayInternalStartpoints(exception);
|
||||
recordPathDelayInternalEndpoints(exception);
|
||||
recordPathDelayInternalFrom(exception);
|
||||
recordPathDelayInternalTo(exception);
|
||||
if (exception->to() == nullptr)
|
||||
path_delays_without_to_ = true;
|
||||
}
|
||||
|
|
@ -4814,8 +4859,10 @@ Sdc::deleteExceptions()
|
|||
first_thru_net_exceptions_.deleteContentsClear();
|
||||
first_thru_edge_exceptions_.deleteContentsClear();
|
||||
first_thru_edge_exceptions_.clear();
|
||||
path_delay_internal_startpoints_.clear();
|
||||
path_delay_internal_endpoints_.clear();
|
||||
path_delay_internal_from_.clear();
|
||||
path_delay_internal_from_break_.clear();
|
||||
path_delay_internal_to_.clear();
|
||||
path_delay_internal_to_break_.clear();
|
||||
|
||||
deleteExceptionPtHashMapSets(exception_merge_hash_);
|
||||
exception_merge_hash_.clear();
|
||||
|
|
@ -5097,8 +5144,8 @@ Sdc::resetPath(ExceptionFrom *from,
|
|||
while (expand_iter.hasNext()) {
|
||||
ExceptionPath *expand = expand_iter.next();
|
||||
if (expand->resetMatch(from, thrus, to, min_max, network_)) {
|
||||
unrecordPathDelayInternalStartpoints(expand->from());
|
||||
unrecordPathDelayInternalEndpoints(expand);
|
||||
unrecordPathDelayInternalFrom(expand);
|
||||
unrecordPathDelayInternalTo(expand);
|
||||
delete expand;
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -696,11 +696,13 @@ make_path_delay(ExceptionFrom *from,
|
|||
ExceptionTo *to,
|
||||
const MinMax *min_max,
|
||||
bool ignore_clk_latency,
|
||||
bool break_path,
|
||||
float delay,
|
||||
const char *comment)
|
||||
const char *comment)
|
||||
{
|
||||
Sta::sta()->makePathDelay(from, thrus, to, min_max,
|
||||
ignore_clk_latency, delay, comment);
|
||||
ignore_clk_latency, break_path,
|
||||
delay, comment);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1221,12 +1223,13 @@ filter_objects(const char *property,
|
|||
Vector<T*> filtered_objects;
|
||||
if (objects) {
|
||||
Sta *sta = Sta::sta();
|
||||
Properties &properties = sta->properties();
|
||||
bool exact_match = stringEq(op, "==");
|
||||
bool pattern_match = stringEq(op, "=~");
|
||||
bool not_match = stringEq(op, "!=");
|
||||
bool not_pattern_match = stringEq(op, "!~");
|
||||
for (T *object : *objects) {
|
||||
PropertyValue value(getProperty(object, property, sta));
|
||||
PropertyValue value(properties.getProperty(object, property));
|
||||
string prop_str = value.to_string(sta->network());
|
||||
const char *prop = prop_str.c_str();
|
||||
if (!prop_str.empty()
|
||||
|
|
|
|||
13
sdc/Sdc.tcl
13
sdc/Sdc.tcl
|
|
@ -2335,7 +2335,8 @@ proc unset_input_delay { args } {
|
|||
################################################################
|
||||
|
||||
define_cmd_args "set_max_delay" \
|
||||
{[-rise] [-fall] [-ignore_clock_latency] [-reset_path] [-comment comment]\
|
||||
{[-rise] [-fall] [-ignore_clock_latency] [-reset_path]\
|
||||
[-probe] [-comment comment]\
|
||||
[-from from_list] [-rise_from from_list] [-fall_from from_list]\
|
||||
[-through through_list] [-rise_through through_list]\
|
||||
[-fall_through through_list]\
|
||||
|
|
@ -2348,7 +2349,7 @@ proc set_max_delay { args } {
|
|||
proc set_path_delay { cmd args min_max } {
|
||||
parse_key_args $cmd args \
|
||||
keys {-from -rise_from -fall_from -to -rise_to -fall_to -comment} \
|
||||
flags {-rise -fall -ignore_clock_latency -reset_path} 0
|
||||
flags {-rise -fall -ignore_clock_latency -reset_path -probe} 0
|
||||
|
||||
set arg_error 0
|
||||
set from [parse_from_arg keys arg_error]
|
||||
|
|
@ -2370,6 +2371,7 @@ proc set_path_delay { cmd args min_max } {
|
|||
}
|
||||
|
||||
set ignore_clk_latency [info exists flags(-ignore_clock_latency)]
|
||||
set break_path [expr {![info exists flags(-probe)]}]
|
||||
|
||||
if [info exists flags(-reset_path)] {
|
||||
reset_path_cmd $from $thrus $to "all"
|
||||
|
|
@ -2377,8 +2379,8 @@ proc set_path_delay { cmd args min_max } {
|
|||
|
||||
set comment [parse_comment_key keys]
|
||||
|
||||
make_path_delay $from $thrus $to $min_max $ignore_clk_latency \
|
||||
$delay $comment
|
||||
make_path_delay $from $thrus $to $min_max \
|
||||
$ignore_clk_latency $break_path $delay $comment
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2404,7 +2406,8 @@ proc set_max_time_borrow { limit objects } {
|
|||
################################################################
|
||||
|
||||
define_cmd_args "set_min_delay" \
|
||||
{[-rise] [-fall] [-ignore_clock_latency] [-reset_path] [-comment comment]\
|
||||
{[-rise] [-fall] [-ignore_clock_latency] [-reset_path]\
|
||||
[-probe] [-comment comment]\
|
||||
[-from from_list] [-rise_from from_list] [-fall_from from_list]\
|
||||
[-through through_list] [-rise_through through_list]\
|
||||
[-fall_through through_list]\
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
|
||||
class SdfWriter : public StaState
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
using std::min;
|
||||
using std::max;
|
||||
using std::make_shared;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,249 @@
|
|||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2025, 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/>.
|
||||
//
|
||||
// The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software.
|
||||
//
|
||||
// Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
//
|
||||
// This notice may not be removed or altered from any source distribution.
|
||||
|
||||
%module properties
|
||||
|
||||
%{
|
||||
|
||||
#include "Property.hh"
|
||||
#include "Sta.hh"
|
||||
|
||||
using namespace sta;
|
||||
|
||||
%}
|
||||
|
||||
%inline %{
|
||||
|
||||
PropertyValue
|
||||
library_property(const Library *lib,
|
||||
const char *property)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
return properties.getProperty(lib, property);
|
||||
}
|
||||
|
||||
void
|
||||
set_library_property(const Library *lib,
|
||||
const char *property,
|
||||
PropertyValue value)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
properties.setProperty(lib, property, value);
|
||||
}
|
||||
|
||||
PropertyValue
|
||||
liberty_library_property(const LibertyLibrary *lib,
|
||||
const char *property)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
return properties.getProperty(lib, property);
|
||||
}
|
||||
|
||||
void
|
||||
set_liberty_library_property(const LibertyLibrary *lib,
|
||||
const char *property,
|
||||
PropertyValue value)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
properties.setProperty(lib, property, value);
|
||||
}
|
||||
|
||||
PropertyValue
|
||||
cell_property(const Cell *cell,
|
||||
const char *property)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
return properties.getProperty(cell, property);
|
||||
}
|
||||
|
||||
void
|
||||
set_cell_property(const Cell *cell,
|
||||
const char *property,
|
||||
PropertyValue value)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
properties.setProperty(cell, property, value);
|
||||
}
|
||||
|
||||
PropertyValue
|
||||
liberty_cell_property(const LibertyCell *cell,
|
||||
const char *property)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
return properties.getProperty(cell, property);
|
||||
}
|
||||
|
||||
void
|
||||
set_liberty_cell_property(const LibertyCell *cell,
|
||||
const char *property,
|
||||
PropertyValue value)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
properties.setProperty(cell, property, value);
|
||||
}
|
||||
|
||||
PropertyValue
|
||||
port_property(const Port *port,
|
||||
const char *property)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
return properties.getProperty(port, property);
|
||||
}
|
||||
|
||||
void
|
||||
set_port_property(const Port *port,
|
||||
const char *property,
|
||||
PropertyValue value)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
properties.setProperty(port, property, value);
|
||||
}
|
||||
|
||||
PropertyValue
|
||||
liberty_port_property(const LibertyPort *port,
|
||||
const char *property)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
return properties.getProperty(port, property);
|
||||
}
|
||||
|
||||
void
|
||||
set_liberty_port_property(const LibertyPort *port,
|
||||
const char *property,
|
||||
PropertyValue value)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
properties.setProperty(port, property, value);
|
||||
}
|
||||
|
||||
PropertyValue
|
||||
instance_property(const Instance *inst,
|
||||
const char *property)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
return properties.getProperty(inst, property);
|
||||
}
|
||||
|
||||
void
|
||||
set_instance_property(const Instance *inst,
|
||||
const char *property,
|
||||
PropertyValue value)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
properties.setProperty(inst, property, value);
|
||||
}
|
||||
|
||||
PropertyValue
|
||||
pin_property(const Pin *pin,
|
||||
const char *property)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
return properties.getProperty(pin, property);
|
||||
}
|
||||
|
||||
void
|
||||
set_pin_property(const Pin *pin,
|
||||
const char *property,
|
||||
PropertyValue value)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
properties.setProperty(pin, property, value);
|
||||
}
|
||||
|
||||
PropertyValue
|
||||
net_property(const Net *net,
|
||||
const char *property)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
return properties.getProperty(net, property);
|
||||
}
|
||||
|
||||
void
|
||||
set_net_property(const Net *net,
|
||||
const char *property,
|
||||
PropertyValue value)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
properties.setProperty(net, property, value);
|
||||
}
|
||||
|
||||
PropertyValue
|
||||
edge_property(Edge *edge,
|
||||
const char *property)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
return properties.getProperty(edge, property);
|
||||
}
|
||||
|
||||
void
|
||||
set_edge_property(Edge *edge,
|
||||
const char *property,
|
||||
PropertyValue value)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
properties.setProperty(edge, property, value);
|
||||
}
|
||||
|
||||
PropertyValue
|
||||
clock_property(Clock *clk,
|
||||
const char *property)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
return properties.getProperty(clk, property);
|
||||
}
|
||||
|
||||
void
|
||||
set_clock_property(const Clock *clk,
|
||||
const char *property,
|
||||
PropertyValue value)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
properties.setProperty(clk, property, value);
|
||||
}
|
||||
|
||||
PropertyValue
|
||||
path_end_property(PathEnd *end,
|
||||
const char *property)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
return properties.getProperty(end, property);
|
||||
}
|
||||
|
||||
PropertyValue
|
||||
path_property(Path *path,
|
||||
const char *property)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
return properties.getProperty(path, property);
|
||||
}
|
||||
|
||||
PropertyValue
|
||||
timing_arc_set_property(TimingArcSet *arc_set,
|
||||
const char *property)
|
||||
{
|
||||
Properties &properties = Sta::sta()->properties();
|
||||
return properties.getProperty(arc_set, property);
|
||||
}
|
||||
|
||||
%} // inline
|
||||
|
|
@ -63,6 +63,8 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
|
||||
static void
|
||||
hierPinsAbove(const Net *net,
|
||||
const Network *network,
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ EvalPred::searchTo(const Vertex *to_vertex)
|
|||
const Pin *pin = to_vertex->pin();
|
||||
return SearchPred0::searchTo(to_vertex)
|
||||
&& !(sdc->isLeafPinClock(pin)
|
||||
&& !sdc->isPathDelayInternalEndpoint(pin));
|
||||
&& !sdc->isPathDelayInternalTo(pin));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
@ -979,7 +979,7 @@ Search::visitStartpoints(VertexVisitor *visitor)
|
|||
for (Vertex *vertex : *graph_->regClkVertices())
|
||||
visitor->visit(vertex);
|
||||
|
||||
const PinSet &startpoints = sdc_->pathDelayInternalStartpoints();
|
||||
const PinSet &startpoints = sdc_->pathDelayInternalFrom();
|
||||
if (!startpoints.empty()) {
|
||||
for (const Pin *pin : startpoints) {
|
||||
Vertex *vertex = graph_->pinDrvrVertex(pin);
|
||||
|
|
@ -995,7 +995,7 @@ Search::visitEndpoints(VertexVisitor *visitor)
|
|||
Pin *pin = end->pin();
|
||||
// Filter register clock pins (fails on set_max_delay -from clk_src).
|
||||
if (!network_->isRegClkPin(pin)
|
||||
|| sdc_->isPathDelayInternalEndpoint(pin))
|
||||
|| sdc_->isPathDelayInternalTo(pin))
|
||||
visitor->visit(end);
|
||||
}
|
||||
}
|
||||
|
|
@ -1163,21 +1163,24 @@ ArrivalVisitor::visit(Vertex *vertex)
|
|||
&& !has_fanin_one_)
|
||||
tag_bldr_no_crpr_->init(vertex);
|
||||
|
||||
visitFaninPaths(vertex);
|
||||
if (crpr_active_
|
||||
&& search_->crprPathPruningEnabled()
|
||||
&& !vertex->crprPathPruningDisabled()
|
||||
// No crpr for ideal clocks.
|
||||
&& tag_bldr_->hasPropagatedClk()
|
||||
&& !has_fanin_one_)
|
||||
pruneCrprArrivals();
|
||||
// Fanin paths are broken by path delays internal pin startpoints.
|
||||
if (!sdc_->isPathDelayInternalFromBreak(pin)) {
|
||||
visitFaninPaths(vertex);
|
||||
if (crpr_active_
|
||||
&& search_->crprPathPruningEnabled()
|
||||
&& !vertex->crprPathPruningDisabled()
|
||||
// No crpr for ideal clocks.
|
||||
&& tag_bldr_->hasPropagatedClk()
|
||||
&& !has_fanin_one_)
|
||||
pruneCrprArrivals();
|
||||
}
|
||||
|
||||
// Insert paths that originate here.
|
||||
if (!network_->isTopLevelPort(pin)
|
||||
&& sdc_->hasInputDelay(pin))
|
||||
// set_input_delay on internal pin.
|
||||
search_->seedInputSegmentArrival(pin, vertex, tag_bldr_);
|
||||
if (sdc_->isPathDelayInternalStartpoint(pin))
|
||||
if (sdc_->isPathDelayInternalFrom(pin))
|
||||
// set_min/max_delay -from internal pin.
|
||||
search_->makeUnclkedPaths(vertex, false, true, tag_bldr_);
|
||||
if (sdc_->isLeafPinClock(pin))
|
||||
|
|
@ -2263,10 +2266,13 @@ PathVisitor::visitFromPath(const Pin *from_pin,
|
|||
}
|
||||
}
|
||||
else {
|
||||
arc_delay = search_->deratedDelay(from_vertex, arc, edge, false, path_ap);
|
||||
if (!delayInf(arc_delay)) {
|
||||
to_arrival = from_arrival + arc_delay;
|
||||
to_tag = search_->thruTag(from_tag, edge, to_rf, min_max, path_ap);
|
||||
if (!(sdc_->isPathDelayInternalFromBreak(to_pin)
|
||||
|| sdc_->isPathDelayInternalToBreak(from_pin))) {
|
||||
arc_delay = search_->deratedDelay(from_vertex, arc, edge, false, path_ap);
|
||||
if (!delayInf(arc_delay)) {
|
||||
to_arrival = from_arrival + arc_delay;
|
||||
to_tag = search_->thruTag(from_tag, edge, to_rf, min_max, path_ap);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (to_tag)
|
||||
|
|
@ -2607,7 +2613,7 @@ Search::mutateTag(Tag *from_tag,
|
|||
if (from_states) {
|
||||
// Check for state changes in from_tag (but postpone copying state set).
|
||||
bool state_change = false;
|
||||
for (auto state : *from_states) {
|
||||
for (ExceptionState *state : *from_states) {
|
||||
ExceptionPath *exception = state->exception();
|
||||
// One edge may traverse multiple hierarchical thru pins.
|
||||
while (state->matchesNextThru(from_pin,to_pin,to_rf,min_max,network_)) {
|
||||
|
|
@ -3294,7 +3300,7 @@ Search::isEndpoint(Vertex *vertex,
|
|||
|| (variables_->gatedClkChecksEnabled()
|
||||
&& gated_clk_->isGatedClkEnable(vertex))
|
||||
|| vertex->isConstrained()
|
||||
|| sdc_->isPathDelayInternalEndpoint(pin)
|
||||
|| sdc_->isPathDelayInternalTo(pin)
|
||||
|| !hasFanout(vertex, pred, graph_)
|
||||
// Unconstrained paths at register clk pins.
|
||||
|| (unconstrained_paths_
|
||||
|
|
|
|||
105
search/Search.i
105
search/Search.i
|
|
@ -1128,111 +1128,6 @@ set_use_default_arrival_clock(bool enable)
|
|||
Sta::sta()->setUseDefaultArrivalClock(enable);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Properties
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
PropertyValue
|
||||
pin_property(const Pin *pin,
|
||||
const char *property)
|
||||
{
|
||||
return getProperty(pin, property, Sta::sta());
|
||||
}
|
||||
|
||||
PropertyValue
|
||||
instance_property(const Instance *inst,
|
||||
const char *property)
|
||||
{
|
||||
return getProperty(inst, property, Sta::sta());
|
||||
}
|
||||
|
||||
PropertyValue
|
||||
net_property(const Net *net,
|
||||
const char *property)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return getProperty(edge, property, Sta::sta());
|
||||
}
|
||||
|
||||
PropertyValue
|
||||
clock_property(Clock *clk,
|
||||
const char *property)
|
||||
{
|
||||
return getProperty(clk, property, Sta::sta());
|
||||
}
|
||||
|
||||
PropertyValue
|
||||
path_end_property(PathEnd *end,
|
||||
const char *property)
|
||||
{
|
||||
return getProperty(end, property, Sta::sta());
|
||||
}
|
||||
|
||||
PropertyValue
|
||||
path_ref_property(Path *path,
|
||||
const char *property)
|
||||
{
|
||||
return getProperty(path, property, Sta::sta());
|
||||
}
|
||||
|
||||
PropertyValue
|
||||
timing_arc_set_property(TimingArcSet *arc_set,
|
||||
const char *property)
|
||||
{
|
||||
return getProperty(arc_set, property, Sta::sta());
|
||||
}
|
||||
|
||||
%} // inline
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
using std::min;
|
||||
using std::max;
|
||||
|
||||
|
|
@ -284,7 +285,8 @@ Sta::Sta() :
|
|||
equiv_cells_(nullptr),
|
||||
graph_sdc_annotated_(false),
|
||||
// Default to same parasitics for all corners.
|
||||
parasitics_per_corner_(false)
|
||||
parasitics_per_corner_(false),
|
||||
properties_(this)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -1965,12 +1967,13 @@ Sta::makePathDelay(ExceptionFrom *from,
|
|||
ExceptionTo *to,
|
||||
const MinMax *min_max,
|
||||
bool ignore_clk_latency,
|
||||
bool break_path,
|
||||
float delay,
|
||||
const char *comment)
|
||||
{
|
||||
sdc_->makePathDelay(from, thrus, to, min_max,
|
||||
ignore_clk_latency, delay,
|
||||
comment);
|
||||
ignore_clk_latency, break_path,
|
||||
delay, comment);
|
||||
search_->endpointsInvalid();
|
||||
search_->arrivalsInvalid();
|
||||
}
|
||||
|
|
@ -4576,6 +4579,7 @@ void
|
|||
Sta::deleteLeafInstanceBefore(const Instance *inst)
|
||||
{
|
||||
sim_->deleteInstanceBefore(inst);
|
||||
sdc_->deleteInstanceBefore(inst);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
using std::ofstream;
|
||||
using std::ifstream;
|
||||
using std::max;
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
using std::ifstream;
|
||||
using std::ofstream;
|
||||
using std::swap;
|
||||
|
|
|
|||
|
|
@ -25,28 +25,24 @@
|
|||
namespace eval sta {
|
||||
|
||||
define_cmd_args "get_property" \
|
||||
{[-object_type cell|pin|net|port|clock|timing_arc] object property}
|
||||
{[-object_type library|liberty_library|cell|liberty_cell|instance|pin|net|port|clock|timing_arc] object property}
|
||||
|
||||
proc get_property { args } {
|
||||
return [get_property_cmd "get_property" "-object_type" $args]
|
||||
}
|
||||
|
||||
proc get_property_cmd { cmd type_key cmd_args } {
|
||||
parse_key_args $cmd cmd_args keys $type_key flags {-quiet}
|
||||
parse_key_args "get_property" args keys {-object_type} flags {-quiet}
|
||||
check_argc_eq2 "get_property" $args
|
||||
set quiet [info exists flags(-quiet)]
|
||||
check_argc_eq2 $cmd $cmd_args
|
||||
set object [lindex $cmd_args 0]
|
||||
set object [lindex $args 0]
|
||||
if { $object == "" } {
|
||||
sta_error 320 "$cmd object is null."
|
||||
sta_error 2200 "get_property object is null."
|
||||
} elseif { ![is_object $object] } {
|
||||
if [info exists keys($type_key)] {
|
||||
set object_type $keys($type_key)
|
||||
if [info exists keys(-object_type)] {
|
||||
set object_type $keys(-object_type)
|
||||
} else {
|
||||
sta_error 321 "$cmd $type_key must be specified with object name argument."
|
||||
sta_error 2201 "get_property -object_type must be specified with object name argument."
|
||||
}
|
||||
set object [get_property_object_type $object_type $object $quiet]
|
||||
}
|
||||
set prop [lindex $cmd_args 1]
|
||||
set prop [lindex $args 1]
|
||||
return [get_object_property $object $prop]
|
||||
}
|
||||
|
||||
|
|
@ -78,14 +74,14 @@ proc get_object_property { object prop } {
|
|||
} elseif { $object_type == "PathEnd" } {
|
||||
return [path_end_property $object $prop]
|
||||
} elseif { $object_type == "Path" } {
|
||||
return [path_ref_property $object $prop]
|
||||
return [path_property $object $prop]
|
||||
} elseif { $object_type == "TimingArcSet" } {
|
||||
return [timing_arc_set_property $object $prop]
|
||||
} else {
|
||||
sta_error 322 "get_property unsupported object type $object_type."
|
||||
sta_error 2203 "get_property unsupported object type $object_type."
|
||||
}
|
||||
} else {
|
||||
sta_error 323 "get_property $object is not an object."
|
||||
sta_error 2204 "get_property $object is not an object."
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -112,13 +108,73 @@ proc get_property_object_type { object_type object_name quiet } {
|
|||
|| $object_type == "lib"} {
|
||||
set object [get_libs -quiet $object_name]
|
||||
} else {
|
||||
sta_error 324 "$object_type not supported."
|
||||
sta_error 2205 "$object_type not supported."
|
||||
}
|
||||
if { $object == "NULL" && !$quiet } {
|
||||
sta_error 325 "$object_type '$object_name' not found."
|
||||
sta_error 2206 "$object_type '$object_name' not found."
|
||||
}
|
||||
return [lindex $object 0]
|
||||
}
|
||||
|
||||
define_cmd_args "set_property" \
|
||||
{[-object_type library|liberty_library|cell|liberty_cell|instance|pin|net|port|clock|timing_arc] object property value}
|
||||
|
||||
proc set_property { args } {
|
||||
return [get_property_cmd "set_property" "-object_type" $args]
|
||||
}
|
||||
|
||||
proc set_property { args } {
|
||||
parse_key_args "set_property" args keys {-object_type} flags {-quiet}
|
||||
check_argc_eq3 "set_property" $args
|
||||
set quiet [info exists flags(-quiet)]
|
||||
set object [lindex $args 0]
|
||||
if { $object == "" } {
|
||||
sta_error 2207 "set_property object is null."
|
||||
} elseif { ![is_object $object] } {
|
||||
if [info exists keys(-object_type)] {
|
||||
set object_type $keys(-object_type)
|
||||
} else {
|
||||
sta_error 2208 "set_property -object_type must be specified with object name argument."
|
||||
}
|
||||
set object [get_property_object_type $object_type $object $quiet]
|
||||
}
|
||||
set prop [lindex $args 1]
|
||||
set value [lindex $args 2]
|
||||
set_object_property $object $prop $value
|
||||
}
|
||||
|
||||
proc set_object_property { object prop value } {
|
||||
if { [is_object $object] } {
|
||||
set object_type [object_type $object]
|
||||
if { $object_type == "Instance" } {
|
||||
set_instance_property $object $prop $value
|
||||
} elseif { $object_type == "Pin" } {
|
||||
set_pin_property $object $prop $value
|
||||
} elseif { $object_type == "Net" } {
|
||||
set_net_property $object $prop $value
|
||||
} elseif { $object_type == "Clock" } {
|
||||
set_clock_property $object $prop $value
|
||||
} elseif { $object_type == "Port" } {
|
||||
set_port_property $object $prop $value
|
||||
} elseif { $object_type == "LibertyPort" } {
|
||||
set_liberty_port_property $object $prop $value
|
||||
} elseif { $object_type == "LibertyCell" } {
|
||||
set_liberty_cell_property $object $prop $value
|
||||
} elseif { $object_type == "Cell" } {
|
||||
set_cell_property $object $prop $value
|
||||
} elseif { $object_type == "Library" } {
|
||||
set_library_property $object $prop $value
|
||||
} elseif { $object_type == "LibertyLibrary" } {
|
||||
set_liberty_library_property $object $prop $value
|
||||
} elseif { $object_type == "Edge" } {
|
||||
set_edge_property $object $prop $value
|
||||
} else {
|
||||
sta_error 2209 "get_property unsupported object type $object_type."
|
||||
}
|
||||
} else {
|
||||
sta_error 2210 "get_property $object is not an object."
|
||||
}
|
||||
}
|
||||
|
||||
# sta namespace end.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1260,6 +1260,12 @@ using namespace sta;
|
|||
Tcl_SetObjResult(interp, list);
|
||||
}
|
||||
|
||||
%typemap(in) PropertyValue {
|
||||
int length;
|
||||
const char *arg = Tcl_GetStringFromObj($input, &length);
|
||||
$1 = PropertyValue(arg);
|
||||
}
|
||||
|
||||
%typemap(out) PropertyValue {
|
||||
PropertyValue value = $1;
|
||||
switch (value.type()) {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
# Application program to run tests on.
|
||||
set app "sta"
|
||||
set sta_dir [file dirname $test_dir]
|
||||
set app_path [file join $sta_dir "app" $app]
|
||||
set app_path [file join $sta_dir "build" $app]
|
||||
# Application options.
|
||||
set app_options "-no_init -no_splash -exit"
|
||||
# Log files for each test are placed in result_dir.
|
||||
|
|
|
|||
Loading…
Reference in New Issue